• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья TOCTOU-атака в Solana: механизм дрейнера и обход Phantom одной транзакцией

BaphometTeam

HDD-drive
Seller
Регистрация
05.01.2026
Сообщения
30
Реакции
65
|ГЛАВА 1: TOCTOU атака, proxy program, смена state, как происходил дрейн.
|ГЛАВА 2: Что такое Lighthouse и пример его использования PHANTOM`ом.
|ГЛАВА 3: Потери и похороны TOCTOU.


JSNJDNFKSJF.png


ПЕРЕД ЧТЕНИЕМ СТАТЬИ ПОЗНАКОМЬТЕСЬ С ТЕРМИНАМИ:smile10::

SetAuthority :zns6:(установка/смена authority)​

Что это: Инструкция, которая меняет или устанавливает владельца/авторитет (authority) для токен-аккаунта (ATA) или минта.
Используемый Тип authority :
AccountOwner — меняет владельца токен-аккаунта (кто может переводить токены).
В атаке: Атакующий заставляет жертву подписать SetAuthority с типом AccountOwner → меняет owner ATA на свой адрес → потом спокойно переводит все токены без подписи жертвы.

Delegate :zns6:- так и переводится (делегат)​

Что это: Владелец токен-аккаунта может дать временное разрешение (approve) другому адресу (delegate) на перевод определённого количества токенов (amount).
Как работает:
Approve(delegate, amount) — даёт делегированному адресу право перевести до amount токенов.
TransferFrom — delegate может перевести токены от имени владельца.
В атаках: Жертва подписывает approve с unlimited amount → атакующий (delegate) потом переводит всё сам.
TOCTOU :zns6:(Time-of-Check to Time-of-Use)
Что это: класс программных ошибок, связанных с состоянием гонки (race condition), когда программа проверяет состояние ресурса (например, файла или прав доступа) в один момент времени (Time-of-Check), а использует результат этой проверки в другой момент, при этом злоумышленник успевает изменить ресурс между проверкой и использованием, что может привести к эксплуатации уязвимостей, например, подмене файла на вредоносный.
ATA:zns6:(Associated Token Account)
Что это: специальный токен-аккаунт в Solana, который привязан к конкретному пользователю (wallet) и конкретному токену (mint).
Каждый пользователь + каждый токен = свой уникальный ATA.
Адрес ATA вычисляется автоматически по формуле: Associated Token Address = findProgramAddress([walletPubkey, TOKEN_PROGRAM_ID, mintPubkey], ASSOCIATED_TOKEN_PROGRAM_ID).
В нём хранится баланс токена, owner (кто владеет аккаунтом), delegate (если есть) и другие данные.
Owner ATA по умолчанию — это публичный ключ кошелька владельца.


:smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50:
ГЛАВА 1: TOCTOU атака, proxy program, смена state, как происходил дрейн.

1768067467992.png
TOCTOU-атака в контексте Solana. Это один из самых опасных типов solana drainer'ов, который бушевал в 2025 году. Атака эксплуатирует разрыв между симуляцией транзакции (когда кошелёк типа Phantom или Solflare показывает юзеру "safe" изменения, вроде +0.01 SOL) и реальным исполнением на сети. Solana — быстрый блокчейн, но это окно в секунды давало атакующим шанс на flip state и полный drain.

Прокси-программа (proxy program) на Solana — это специальная вредоносная программа, которую атакующий разворачивает на блокчейне, чтобы использовать её как посредника в TOCTOU-атаках (или в других схемах дренажа)
  • Это обычная программа на Rust/Anchor, но с хитрой логикой.
  • Внутри есть условная ветвь по состоянию (state):
    • Если состояние "safe" (флаг = 0 в PDA) → делает безвредное действие (+0.01 SOL или ничего).
    • Если состояние "malicious" (флаг = 1) → выполняет полный drain (SetAuthority на адрес атакующего, transfer токенов и т.д.).









Давайте разберёмся с планом TOCTOU-атаки, где акцент на маскировке под harmless SetAuthority. В safe сценарии симуляция показывает не просто +0.00001 SOL, но если юзер нажмёт advanced (подробнее) в Phantom, видно SetAuthority на тот же адрес (кошелёк жертвы). Это даёт "no changes", потому что owner меняется с кошелька жертвы на... кошелёк жертвы (никакого effective flip). А после подписи идёт смена state — и реальное исполнение становится malicious, с дрейном. Атакующие автоматизировали это, чтобы flip state в окне секунд. Классический сценарий с "proxy program" выглядел так:
  • Атакующий разворачивает malicious program (прокси-программу) на Solana. Эта программа имеет встроенную логику TOCTOU: поведение зависит от текущего on-chain state (например, от значения в PDA или другом аккаунте). Программа естественно деплоилась без верифицированного кода, чтобы не спалить сканеры вроде Blowfish или Blockaid. Встроенная маскировка: в safe state SetAuthority устанавливает owner на текущий адрес жертвы, что выглядит harmless.
  • dApp показывает "safe" сценарий:
    • Юзер подключает кошелёк к sol drainer сайту
    • dApp генерирует транзакцию, которая вызывает эту программу.
    • На момент симуляции в кошельке state программы safe (флаг = 0) → программа выполняет безвредное действие (начисляет +0.00001 SOL или просто ничего вредного). В симуляции видно +0.00001 SOL, но если нажать advanced, там SetAuthority на тот же адрес (кошелёк жертвы) — это даёт "no changes", потому что с кошелька жертвы на кошелёк жертвы.
    • Кошелёк симулирует tx, видит баланс safe (+0.00001 SOL, без дрена), показывает зачисление, и юзер подписывает. Здесь ключевой момент: симуляция использует текущий state на момент проверки, без учёта возможных изменений. Advanced view подтверждает "без изменений", так как SetAuthority не меняет owner реально.
    • JSNJDNFKSJF.png
ВИДЕО TOCTOU АТАКИ (CLICK)
  • После подписи — смена state:
    • Атакующий (контролирует dApp и знает signed transaction) быстро шлёт предварительную tx, которая меняет state программы на "malicious" (флаг = 1, или устанавливает delegate authority на свой адрес).
    • Это могло быть SetAuthority (делегирует authority токен-аккаунтов атакующему), approve delegate для unlimited amount (или permanent delegate в Token-2022), или другие изменения, позволяющие drain. Flip state меняет логику: SetAuthority теперь на адрес атакующего.

  • Исполнение signed tx жертвы:
    • Атакующий шлёт уже подписанную tx на сеть.
    • Теперь, при реальном исполнении, программа видит malicious state → вместо safe действия (SetAuthority на тот же адрес) выполняет drain: переносит все токены/SOL на адрес атакующего.
    • Или, если делегировали authority — атакующий потом отдельной tx (своим authority) дрейнит всё максимально (токены, native SOL).

  • Почему PHANTOM не ловил В 2025:
    • Симуляция использует текущий state на момент симуляции (safe).
    • Реальное исполнение — через секунды/блоки, после смены state.
    • Solana быстрая, окно для атаки — несколько секунд. Кошелек не детектил потому что не всегда добавлялся Lighthouse в конец инструкции.

  • Почему PHANTOM ловит В 2026:
    • Вся работа TOCTOU сейчас упирается в Lighthouse: если Phantom видит хотя бы одну inner instruction даже пустую — автоматом при симуляции добавляет Lighthouse, который проверяет owner смену и изменения баланса. Lighthouse добавляется только если есть inner instruction — то есть что-то с CPI. Если допустим transfer SOL в outer — Lighthouse не будет, но жертва увидит списание. а если с CPI то автоматически добавится Lighthouse.

ГЛАВА 2: Что такое Lighthouse и пример его использования PHANTOM`ом
Lighthouse (Lighthouse Protocol) — это on-chain протокол защиты транзакций на Solana, созданный для борьбы с TOCTOU-атаками (Time-of-Check-to-Time-of-Use) и другими манипуляциями состоянием.

Краткое определение:

Lighthouse — это набор специальных инструкций (assertion-инструкций), которые автоматически добавляются в конец транзакции кошельком (в первую очередь Phantom, а также частично Solflare и OKX). Эти инструкции проверяют, что финальное состояние аккаунтов после исполнения транзакции полностью соответствует тому, что показала симуляция перед подписью.
ПРИМЕР :
Возьмем, к примеру, вредоносную транзакцию, в которой симуляция показывает,
что баланс токена на счете остается неизменным, но при обработке транзакция
фактически переводит весь баланс токенов злоумышленнику.
SKDFKFNSDJKNF.png

Поставщик кошелька внедряет в транзакцию инструкцию проверки Lighthouse,
чтобы убедиться, что баланс токена на счете соответствует ожидаемому результату
в симуляции. Если инструкция Lighthouse не срабатывает, транзакция отклоняется.
kkcxxvnkjcxnv.png


К концу 2025 Phantom и другие кошельки начали автоматически добавлять
Lighthouse Guard Instructions в конец каждой транзакции, где есть хотя бы одна
inner instruction (CPI — вызов другой программы).

dfgdfgdfgfd.png


Правила добавления Lighthouse фантомом(на январь 2026)::smile10:

1) Если в транзакции есть хотя бы одна CPI (cross-program invocation, inner instruction) → Lighthouse добавляется почти всегда.
2) Если транзакция состоит только из outer-инструкций (например, простой SystemProgram.transfer SOL без вызова других программ) → Lighthouse обычно не добавляется.
3) Если транзакция большая (1200+ байт) → иногда кошелёк не может добавить guard из-за лимита 1232 байт и блокирует подпись. ТО ЕСТЬ ВЫТЕСНИТЬ LIGHTHOUSE СПАМОМ 4) В ТРАНЗАКЦИИ НЕ ПОЛУЧИТСЯ! phantompidoras -tx фейлится

Почему теперь транзакция фейлится, если пытаться подменить в конце

Lighthouse добавляет специальные assertion-инструкции в самый конец транзакции (после всех основных инструкций). Эти assertions проверяют финальное состояние аккаунтов на момент исполнения:

1) Баланс SOL не уменьшился больше, чем ожидалось.
2) Owner токен-аккаунтов не изменился неожиданно.
3) Delegate authority не появился или не вырос.
4) И тд (в зависимости от того, что кошелёк увидел в симуляции).

Схема исполнения транзакции на Solana:
fdsfjsdfkj.png

[инструкция 1] → [инструкция 2] → ... → [инструкция N] → [Lighthouse assertions]

Если в транзакции есть CPI → Lighthouse в конце.
То есть если Lighthouse заметит то что мы что-то flipнули (изменили owner), он отменит транзакцию

1) Так выглядит прямая замена SetAuthority (AccountOwner) (если бы не исполняли трюк динамически)
2) Замена SetAuthority (AccountOwner) через динамический смарт контракт (прокси-программа anchor)
Снимок экрана 2026-01-08 203925.png
ывалывлатывлаывлат.jpg


При подписи транзакция апгрейдится на вредоносную, меняется SetAuthority (AccountOwner) на адрес атакующего. Токены не списываются сразу — просто owner ATA становится attacker'ом, и он выводит токены автоматически отдельной tx. Подписью жертва передаёт права владения токенами злоумышленнику

ГЛАВА 3: Потери и похороны TOCTOU.
роиорио.jpg

Летом (август): начали открываться solana drainer тимы с TOCTOU BYPASS
Осенью (сентябрь - ноябрь): Prime toctou solana drainerов выносили миллионы долларов
Зимой (середина декабря): Phantom стал принудительно добавлять Lighthouse в транзакции с CPI

:smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50::smile50:

26 ноября 2025 — кейс "Angel Ferno"
Одна из самых мощных single-tx краж 2025 года: через TOCTOU-flip вынесли 9 токенов (SOL + токены) на сумму около $3 млн
Это был классический TOCTOU: симуляция safe, подпись, быстрый flip state, исполнение — полный drain

:smile2:
Снимок экрана 2026-01-10 212412.png


ЦЕНА ЗА TOCTOU BYPASS ДОХОДИЛА ДО 15 ТЫСЯЧ ДОЛЛАРОВ

Ключевые причины падения TOCTOU в конце 2025
  • Lighthouse стал добавляться автоматически при CPI → assertion в конце tx ловит любые изменения owner/balance/delegate.
  • Улучшенные симуляторы (Phantom + Blowfish) начали флагать подозрительные паттерны.
  • Общие потери от phishing/drainer'ов выросли на 78% по сравнению с 2024, но Solana пострадала сильнее других цепей.

ИТОГ :zns6::
В 2025 году TOCTOU-атака стала самым мощным и самым короткоживущим оружием в истории Solana-дрейнеров. Лето — ПУБЛИЧНОЕ рождение и первые миллионы, осень — пик, когда prime-тиммы выносили по несколько миллионов в неделю, зима — внезапная смерть от Phantom & Lighthouse. Один tx — $3 млн у Angel Ferno, десятки тысяч долларов за рабочий bypass, тысячи слитых кошельков. Всё это было возможно ровно до тех пор, пока Phantom и экосистема не включили автоматические assertions в конец каждой транзакции с CPI.
Сейчас, в начале 2026, классический TOCTOU практически мёртв:
  • Lighthouse ловит любые изменения состояния в конце tx.
  • Симуляторы флагают proxy-программы и подозрительные паттерны.
  • Обходы (спам memo, overflow лимита 1232 байт) приводят либо к "simulation failed", либо к тому, что Lighthouse всё равно влезает и фейлит транзакцию.
Но мёртв ли он окончательно? Нет. Теоретически, если кто-то найдёт стабильный способ обойти Lighthouse, например, чисто outer-инструкции без CPI, но с хитрым drain, или новый вектор подмены без inner calls что врядтли но — TOCTOU может воскреснуть. Пока что это дело времени, удачи и очень дорогих разработок.
 

Вложения

  • efsklkdsklds.jpg
    efsklkdsklds.jpg
    31.7 КБ · Просмотры: 16
  • Снимок экрана 2026-01-08 203925.png
    Снимок экрана 2026-01-08 203925.png
    46.4 КБ · Просмотры: 13
  • dvdfvdfvdfv.png
    dvdfvdfvdfv.png
    54.2 КБ · Просмотры: 31
Последнее редактирование модератором:
хорошая статья) еще бы источники про техническую часть и было бы вообще супер)
Rust anchor смарт контракт, я подумал что смысла вставлять код нету ибо уже не воркает
 
Но мёртв ли он окончательно? Нет. Теоретически, если кто-то найдёт стабильный способ обойти Lighthouse, например, чисто outer-инструкции без CPI, но с хитрым drain, или новый вектор подмены без inner calls что врядтли но — TOCTOU может воскреснуть. Пока что это дело времени, удачи и очень дорогих разработок.
пишут что в 2026 уже начали надкусывать новые векторы
  • Versioned Transactions + priority fee abuse с предсказуемыми слотами,
  • Атаки через Flash Loans + JIT-бандлы (когда весь drain происходит в одной транзакции, но состояние меняется в середине через flash loan callback)
  • Использование новых примитивов типа Address Lookup Tables для подмены адресатов
Пока что эти новые методы не дают таких же объёмов, как TOCTOU в свой пик, но отдельные сливы по 500k–1M $ якобы уже были.
 
пишут что в 2026 уже начали надкусывать новые векторы
  • Versioned Transactions + priority fee abuse с предсказуемыми слотами,
  • Атаки через Flash Loans + JIT-бандлы (когда весь drain происходит в одной транзакции, но состояние меняется в середине через flash loan callback)
  • Использование новых примитивов типа Address Lookup Tables для подмены адресатов
Пока что эти новые методы не дают таких же объёмов, как TOCTOU в свой пик, но отдельные сливы по 500k–1M $ якобы уже были.
  • Атаки через Flash Loans + JIT-бандлы (когда весь drain происходит в одной транзакции, но состояние меняется в середине через flash loan callback) Звучит интересно, что то известно ща про 2 метод?
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх