TGViewer
Channel Public Channel
Noobing Security Research

Noobing Security Research

@web3securityresearch

Изучаю и пишу про безопасность смарт контрактов и агентов
Subscribers
278
Photos
32
Videos
0
Links
74

Showing posts older than #41 · Back to latest

Older Posts 19 shown
Post #40 235
подал заявку на участие в Octant DeFi Hackathon 2025

сроки проведения: 31 октября - 11 ноября

в чем суть: создать проект, использующий octant vault'ы, которые являются альтернативой erc-4626

призовой пул 21_500$, делится на разные категории, например самый чистый код (2,500) или лучшее использование aave vaults v3(2500) и так далее

я думаю, что стоит собрать команду из 2-3-4 человек, чтобы вместе поучаствовать ради опыта + проекта в гитхаб

подавайте заявки, пишите в личку, если вашу заявку одобрили
octant.devfolio.co Octant DeFi Hackathon 2025 | Devfolio Hack on Octant's new Yield Donating Vaults and Public Goods
  • ❤ 11
Post #39 272
Уязвимость: Inflation Attack/Donation attack

Этот пост написан на основе треда security researcher Kankodu

Итак, мы знаем, что такое инфляционная атака и как можно защититься и даже применяем это на практике.
Этот отчет о уязвимости мне понравился потому, что демонстрирует важность консистентности работы с выпускаемыми токенами. Всё должно подчиняться единым правилам, иначе - дрейн

Речь пойдет об уязвимости в лендинг протоколе Vesuxyz, которая возникала в момент добавления нового asset’a к пулам коллатералов.
Сама уязвимость уже исправлена и внесенные изменения можно посмотреть здесь

Протокол VESU поддерживает деплой нескольких пулов, каждый из которых является лендинг маркетом с разными парами коллатерал - займ. Для каждой пары свой LTV (Loan-to-Value - сколько можно занять под свой залог). Такая структура позволяет использовать очень разные вариации займов. Существует Genesis pool, который содержит значительный TVL и который по сути является обычным лендинг маркетом с поддержкой регипотеки (rehypothecation - практика, при которой финансовая организация (например, банк или брокер) повторно использует залоговые активы своего клиента (такие как ценные бумаги или криптовалюта) в качестве обеспечения по своим собственным кредитам или сделкам, создавая таким образом многократное использование одного и того же актива для получения дополнительной выгоды )

И этот пул можно было сдрейнить через инфляционную атаку, хотя она скорее комбинированная

Разработчики протокола учли первый шаг, про который я писал ранее, поэтому, если total shares = 0, то при попытке сминтить долю, сначала минтятся 1000 dead shares

Но! Когда вкладчики получали свой процент дохода, протокол забирал часть в качестве комиссии и при этом минтил эквивалентное количество shares, увеличивая общее количество shares без минта 1000 deadshares. Я думаю вы уже начали понимать, в чем загвоздка

Атакующий донатит в резервы небольшое количество токена, на пул которого и готовится атака. Функция доната позволяет закинуть протоколу активов без минта shares, для увеличения стоимости пула, покрытия комиссий, в общем в качестве поддержки. Возможно, что вы о таком не слышали, но такое встречается

Затем атакующий берет эти средства в долг на небольшое время, возвращает долг, протокол минтит немного shares, стоимостью меньше 500 wei

Теперь пул содержит больше 0 shares, а значит начальная проверка на необходимость минта 1000 dead shares обходится

Теперь атакующий может сминтить свою долю, которая тоже меньше 500 Wei, а так же он донатит большую сумму в пул

На данный момент у него есть очень небольшое количество shares, которые сопоставляются большой сумме в пуле. Под эти shares он вполне легально берет долг в других пулах

Осталось понять, как вытащить задоначенные средства и не возвращать долг

У протокола есть механизм, который скидывает остаток shares в 0, если при выводе их остается меньше 1000, это изначально было сделано для того, чтобы не оставалось «пыли». Атакующий с другого адреса вносит и выносит 1 Wei, это приводит к тому, что в пуле лежат средства, но shares равно 0

Затем так же с другого адреса вносится какое-то количество средств, атакующего больше не волнует, что сгенерилось 1000 dead shares, ведь всё равно все средства в пуле соответствуют его вновь сминченной доле. После этого он может выносить все ранее внесенное, а на другом его аккаунте висит займ, который теперь нечем закрыть. Это возможно потому, что протокол не проверяет автоматически все позиции на ликвидацию (это тоже обычная история), а когда вынос случится - ликвидировать первую позицию уже смысла нет - у нее нет обеспечения

https://t.me/web3securityresearch
  • ❤ 7
Post #38 247
Noobing Security Research Второй раз за последние пару месяцев возникает ситуация, где взлом происходит на уровне npm пакетов Вроде как если вы сегодня не обновляли ничего, то должно быть ок, но это не точно
Метамаск выкатил в ранний доступ kipuka, инструмент для защиты от вредоносных npm пакетов. В целом, всем разработчикам давно рекомендовано запускать проекты в контейнерах/VM, но не все это делают и не всегда (надо написать об этом подробный пост). Кипука оборачивает ваши запросы к npm пакетам в контейнеры автоматически, так что если вы забываете или ленитесь поднимать каждый раз безопасное окружение, то эта штука для вас

https://t.me/web3securityresearch
GitHub GitHub - LavaMoat/kipuka: Easy, composable and transparent way to run things in a docker container. Easy, composable and transparent way to run things in a docker container. - LavaMoat/kipuka
  • ❤ 7
Post #37 236
Noobing Security Research 3. Использовать "dead shares"
А что такое deadshares?

Для того, чтобы атакующий не мог размыть долю вкладчика, используются так называемые dead shares, т.е. мертвые доли

Например, при инициализации пула мы можем сминтить 1000 shares и отправить их на нулевой адрес

function initialize() public {
uint256 deadAmount = 1000; // Или 1e6, в зависимости от decimals
_mint(address(0), deadAmount); // Минтим и "сжигаем" на нулевом адресе
}


Размыть 1000 долей намного сложнее, чем манипулировать отправной точкой 0, то есть мы не закрываем уязвимость, но делаем эксплуатацию сильно дороже, потому что в

sharesAmount = totalShares * assetAmount / asset.balanceOf(address(this))

totalShares теперь равен 1000, а не 1, как было показано в примере атаки

UPD. Мне попалась классная атака с обходом deadshares, так что этот пост нужен для контекста разбора

https://t.me/web3securityresearch
  • ❤ 5
Post #36 252
Как заработать сотни тысяч долларов на NFT

Речь пойдет про вчерашнюю ситуацию/инцидент с контрактами группы Strategy

Коротко, для тех кто всё пропустил, в общих чертах. Сейчас в крипте появилась новая «мета» strategy (нарратив, тема, мода, идея - называйте как угодно), суть которой заключается в следующем:

1. У нас есть NFT проекты со своей аудиторией, с богатой историей и достаточно высокой ценой за одну NFT
2. NFT рынок живет волнами активности, у многих коллекций на фоне роста эфира просели цены, потому что люди продают NFT и фиксируют эфир
3. Что если откупать эти NFT на комиссии, которые были собраны с торговли определенным токеном? Будет расти цена коллекции, потому что никто не хочет продавать дешево, когда у тебя есть гарантия выкупа
4. Купленная NFT продается в рынок, вырученные средства идут теперь уже на выкуп токена с последующим сжиганием. Цена токена растет, NFT дорожают и все такое.

Мы не будем останавливаться на том кто же платит за вечеринку, это просто механизм, вот тут про тайминги и имена написано
https://t.me/MMPRTVNFT/3614

Что произошло?
Произошел деплой контракта, который должен этот механизм осуществлять, помимо прочего там есть функция

function buyTargetNFT(uint256 value, bytes calldata data, uint256 expectedId, address target) external nonReentrant {
// Store both balance and nft amount before calling external
uint256 ethBalanceBefore = address(this).balance;
uint256 nftBalanceBefore = collection.balanceOf(address(this));

// Make sure we are not owner of the expected id
if (collection.ownerOf(expectedId) == address(this)) {
revert AlreadyNFTOwner();
}

// Ensure value is not more than currentFees
if (value > currentFees) {
revert NotEnoughEth();
}

// Call external
(bool success, bytes memory reason) = target.call{value: value}(data);
if (!success) {
revert ExternalCallFailed(reason);
}

// Ensure we now have one more NFT
uint256 nftBalanceAfter = collection.balanceOf(address(this));

if (nftBalanceAfter != nftBalanceBefore + 1) {
revert NeedToBuyNFT();
}

// Ensure we are now owner of expectedId
if (collection.ownerOf(expectedId) != address(this)) {
revert NotNFTOwner();
}

// Calculate actual cost of the NFT to base new price on
uint256 cost = ethBalanceBefore - address(this).balance;
currentFees -= cost;

// List NFT for sale at priceMultiplier times the cost
uint256 salePrice = cost * priceMultiplier / 1000;
nftForSale[expectedId] = salePrice;

emit NFTBoughtByProtocol(expectedId, cost, salePrice);
}

Она позволяет указать контракту какую NFT и по какой цене покупать, это ок

Ну и она в общем то не отслеживает то, кто ее вызывает, то есть мог её вызвать кто угодно

Соответственно, нашелся человек, который начал контракту продавать свои NFT по x3 цене, затем откупать, потом снова продавать, до тех пор, пока на контракте не кончились деньги

Эта уязвимость называется Missing Access Control, это одна из первых уязвимостей, которую вам показывают на курсах по безопасности

Неужели разрабы контрактов настолько не шарят?

Есть вариант, что это была не уязвимость, а недоделанная система

Потому что если мы представим, что есть акторы, которые будут триггерить контракт каждый раз, когда его средств достаточно на выкуп, то мы получим просто работающий механизм. Этими акторами конечно должны стать flashbots, про которых я обзорно писал здесь

И есть парень, который вчера, через пару часов после инцидента, написал бота, который теперь следит за количеством средств + за ценами на NFT и инициирует покупку, вот он

Такие дела, на протяжении часов в сети была возможность хорошо заработать и кто-то ее смог прочитать

https://t.me/web3securityresearch
  • ❤ 9
Post #35 234
Атака: Inflation Attack

Инфляционная атака - это распространенная атака, характерная для Vault’ов стандарта ERC-4626

Этот стандарт вам знаком, если вы хоть раз депонировали средства в протоколы-обёртки под процент или поинты

Относится к уязвимостям высокого уровня, поскольку содержит в себе фронтран с кражей средств пользователя

Огромное количество протоколов использует этот стандарт, здесь список

Когда возникает
На ранних стадиях этому подвержен любой пул, который предлагает обмен активов на долю в этом пуле.
То есть, если ваш протокол в том или ином виде предлагает функцию минта долей (mint shares), то вы под ударом

Формула минта обычно выглядит примерно так

sharesAmount = totalShares * assetAmount / asset.balanceOf(address(this))

Атакующий может манипулировать делителем, что может привести к получению очень малой доли токенов пула, вплоть до нулевой

Пример кода, подверженного атаке

abstract contract ERC4626 is ERC20 {
IERC20 asset;

constructor(IERC20 asset_) {
asset = asset_;
}

function totalAssets() public view returns (uint256) {
return asset.balanceOf(address(this));
}

function convertToShares(uint256 assets) public view returns (uint256) {
if (totalAssets() == 0) {
return assets;
}
return totalSupply() * assets / totalAssets();
}

function convertToAssets(uint256 shares) public view returns (uint256) {
return totalAssets() * shares / totalSupply();
}

function deposit(uint256 assets) public {
asset.transferFrom(msg.sender, address(this), assets);
_mint(msg.sender, convertToShares(assets));
}

function burn(uint256 shares) public {
_burn(msg.sender, shares);
asset.transfer(msg.sender, convertToAssets(shares));
}
}


Сценарий атаки
1. Атакующий делает back-run создаваемого пула. Бэк раннинг - это когда хакер увидел транзакцию еще в мемпуле, до включения в блок, и закинул свою транзакцию так, чтобы она шла сразу же за транзакцией создания пула. Буквально «дышит в спину», если переводить по смыслу
2. Атакующий минтит себе один share пула, одну долю то есть
3. Атакующий фронтраннит депозит жертвы на 20_000 USDT
4. Атакующий раздувает делитель в формуле расчета долей до 20_000, для этого можно использовать прямой депозит в обход функции минта
5. Из-за того что в Solidity по умолчанию деление целочисленное, а хакер делает фактически


sharesAmount = 1 * 20_000 / (1 + 20_000), где в верхней части дроби средства жертвы, а внизу то что
внес хакер двумя транзакциями, то есть результат меньше 1 и он округляется до 0

В итоге у хакера на балансе 1 share, за который можно выкупить все средства на балансе, потому что активы учитывают путем проверки средств на балансе напрямую

Что можно предпринять:
1. Учет баланса контракта лучше вести созданными для этого переменными, а не полагаться на asset.balanceOf(address(this));
2. Использовать ERC4626 Router
3. Использовать "dead shares"

При подготовке поста использовалась статья от MixBytes()

https://t.me/web3securityresearch
Telegram Noobing Security Research Изучаю и пишу про безопасность смарт контрактов и агентов
  • ❤ 7
Post #33 227
Второй раз за последние пару месяцев возникает ситуация, где взлом происходит на уровне npm пакетов

Вроде как если вы сегодня не обновляли ничего, то должно быть ок, но это не точно
  • ❤ 9
Post #31 328
Уровни опасности уязвимостей

Сегодня расскажу про базовое понятие, которое надо знать обязательно, если вы решили встать на путь Security research

Строго говоря, единой классификации уязвимостей нет, но все существующие похожи между собой

Выделяются 3-4-5 уровней угрозы:
- Критический
- Высокий
- Средний
- Низкий
- Информационный

Соответственно не все выделяют критический и информационный уровни, но мы их затронем

Мне нравится как представлена оценка уровня угрозы у Numen, собственно таблица из их отчета это первое изображение

У таблицы есть две оси: вероятность (Likelihood) и воздействие (Impact)

Если вероятность велика и воздействие на контракт сильное, то мы получаем критический уровень угрозы, если вероятность велика, а влияние незначительное, то это средний, если веротность низкая, а воздействие сильное, то тоже средний

Но это конечно не идеальное решение, хоть и красивое. Многие считают, и я в том числе, что если вероятность низкая, но вследствие атаки с контракта пропадут деньги, то это высокий уровень угрозы. Взять тот же взлом GMX, я писал пост, уязвимость которого в продакшене висела 5 лет, просто никто не видел её, а в результате удалось вытащить 42кк$. Не похоже на среднюю угрозу

В то же время в информационные обычно входят вещи, которые вообще то могут возникать часто. Например, у вас неэффективная по газу функция. Угрозы в этом может и не быть, но взаимодействие с контрактом могло бы быть дешевле. Эта функция может триггериться при каждом вызове, так что likelihood очень высокий, но это не делает ее medium.

Но в остальном таблица вполне рабочая, а главное дает представление

Еще есть вариант оценки от Secure3, это вторая таблица в этом посте

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

Дорого использовать и урон средний? Оцениваем уязвимость как информационную. Легко использовать, большой урон - высокий уровень опасности

Что такое высокий урон, средний и низкий, какие усилия считаются высокими, средними и низкими расписано в статье, там объемно, так что тут расскажу коротко.

У урона (Damage) есть два вида: финансовый и функциональный. Соответственно кража средств и вывод контракта из рабочего состояния - высокий урон. Кража «пыли» со счетов и неправильно прописанные события - низкий

У стоимости атаки так же два вида оценки: стоимость и сложность. Со стоимостью думаю и так ясно, можно только добавить, что ее оценивают и в сравнении с профитом. Сложность зависит от сложности кода, вероятности исполнения, ресурсов на исполнение

Хотел написать небольшой пост, но видимо так не работает

https://t.me/web3securityresearch
  • ❤ 12
Post #30 481
flashboys.pdf1.4 MB
Ethereum is a dark forest
Знакомы ли вы с концепцией темного леса? В последнее время в моем инфополе она чаще всего звучала в контексте сериала «задача трех тел»

Если коротко, в темном лесу водятся монстры. Единственный способ выжить - либо быть самым сильным, либо не подавать признаков жизни. Подробнее на Википедии

Казалось бы, при чем тут аудит смарт контрактов?
Дело в том, что в сети эфира водятся монстры flashbots, которые слушают наши транзакции. И в случае, когда потенциальный профит превосходит затраты на исполнение, они атакуют

Таким образом атакующий вектор находится вне плоскости программного слоя, в слое самой сети. Это становится возможным, потому что:
- Все транзакции перед включением в блок попадают в mempool, так устроена сеть Ethereum. Мемпул место прозрачное, доступное для чтения
- Приоритет газа существует, увеличив газ можно поставить свою транзакцию вперед других

К чему приводит такой порядок дел

В основном к тому, что атакующий пытается закинуть транзакцию перед или сразу после интересующей его транзакции, либо провести сэндвич-атаку, когда атакуемая транзакция «оборачивается» с двух сторон в манипулятивные транзы. По такому же принципу происходит flashloan атака, писал про нее тут, только там атакующий пишет контракт, а не ловит интересующую его транзакцию в мемпуле

В случае, если в вашем контракте неправильно прописаны трансферы, например вы не проверяете кто инициализирует трансфер, флэшбот может воспользоваться этой дырой для вывода средств с контракта как только увидит такую транзакцию в мемпуле

Очень крутая статья 2020 года про то как ребята пытались вытащить 12к$, которые застряли на видном, но еще не обнаруженном флешботами месте. Спойлер: монстры вытащили ликвидность как только транза мелькнула в сети

Ужас, но не ужас-ужас-ужас
В основном флэшботы крутятся вокруг DEX, они арбитражат разность курсов и тем самым вообще-то выполняют очень важную функцию целостности цен по всему маркету.
Могут правда зацепиться за крупные транзы и внести манипулятивную составляющую, которая неизбежно возникнет при крупной сделке. Могут подсунуть не самый выгодный курс, вынудив купить по бОльшей цене.

Так же они могут первыми показывать на позиции, требующие ликвидации, получая за это бонус.

Есть экзотические атаки, трудно выполняемые в текущих условиях сети эфира, но которые вполне серьезно обсуждались до The Merge (переход с PoW на PoS) типа Fee-based forking attacks или Time-bandit attacks. На них я останавливаться не буду, по крайней мере сейчас

К посту прикладываю одну из первых системных статей по теме, она 2019 года. Какие-то части чуть устарели, но в ней классно описан математически аппарат того, как боты действуют, что лежит в основе их конкуренции и сотрудничества. Любителям теории игр будет интересно

Это первый пост вводный пост по теме flashbots, дальше будет подробнее про виды атак, про способы защиты ваших протоколов и еще больше источников и статей

https://t.me/web3securityresearch
  • ❤ 16
Post #29 347
Дал интервью Яше про работу аудитора, достаточно обзорное, без технической части, техническая часть живет в этом канале

Интервью было текстовое, Яша с помощью нейронок сделал подкаст, достаточно странно слышать как твои слова говорит не твой голос 😅

Яша затеял сделать обзоры на примерно все профессии в веб3, так что если хотите расширить кругозор или понять чем занимаются люди вокруг вас чуть подробнее - чекните канал и подпишитесь
  • ❤ 6
Post #28 380
Уязвимость: Access Control Vulnerabilities

Топ 1 уязвимость на 2025 год, согласно списку от OWASP. На первый взгляд кажется, что это очень простая уязвимость, которую можно избежать средствами уровня "не ставь пароль 12345", но на самом деле бывают намного более сложные случаи.

OWASP — это Open Worldwide Application Security Project, международное сообщество и некоммерческая организация, которая занимается улучшением безопасности программного обеспечения

В чем заключается
Строгое определение такое: уязвимость нарушения доступа - это уязвимость, позволяющая неавторизованным пользователям получить доступ и/или изменять данные и/или функции контракта

Где искать
Возникают чаще всего там, где недостаточно permission checks, например отсутствует модификатор onlyOwner, или функция вывода средств не проверяет что адрес, инициировавший вывод соответствует адресу, с чьего баланса списываются средства. Так же стоит следить за тем, чтобы роли в вашем протоколе не имели бы слишком много полномочий

Пример
В этой короткой статье рассказывается о то, что у функции burn протокола HospoWise не было модификатора onlyOwner, что привело к тому, что сжигать их токены мог любой желающий

Как быть
Хорошая новость в том, что такие очевидные нарушения прекрасно детектируются статическими инструментами анализа, так что надо:
- использовать статические анализаторы типа slither и aderyn
- использовать onlyOwner от OpenZeppelin
- тесты тесты тесты

Важность тестирования в написании контрактов невозможно переоценить
OWASP Foundation OWASP Smart Contract Top 10 | OWASP Foundation OWASP Smart Contract Top 10 - An OWASP other project
  • ❤ 5
Post #27 309
Уязвимость: Price Oracle Manipulation

Это критическая уязвимость может быть обнаружена/использована в контрактах, которые зависят от внешних источников данных о цене актива.

Схема действия достаточно проста: пользователь собирается купить ETH через ваш контракт за USDC/USDT, контракт принимает сумму, на которую следует совершить обмен, а для расчета покупки используется функция, возвращающая текущую стоимость актива при его покупке например на Uniswap

Перед тем, как транзакция выполняется, происходит покупка большого количества одного токена из пары (часто с использованием flash loan буквально на миллиарды долларов), что искажает пропорцию активов в пуле —> искажает цену —> покупка проходит по невыгодной цене —> внесенная ранее ликвидность выносится из пула

Либо наоборот, атакующий покупает актив по очень выгодной цене, в зависимости от стратегии атаки

Пример
Схему на изображении надо читать следующим образом: красные стрелки это путь средств "вглубь" атакуемого контракта, зеленые - это вынос. Все действия происходят в рамках одной транзакции. Схема упрощенная, но суть от этого не меняется

Атакуемый контракт называется NFT Protocol, он позволяет купить NFT за 10 долларов

1. Атакующий (Flash Loan Receiver), получает займ
2. Первоначальная цена NFT при составляет 10 USDC или 1 ETH
4. Атакующий свапает на TSwap USDC на WETH (то есть выкупает ETH, эфира остается мало в пуле), меняя таким образом первоначальную пропорцию с 100 к 10 на 1000 к 1
5. 1 ETH теперь стоит 1000 USDC
6. Так как атакующий контракт берет информацию о цене эфира с TSWAP, то продажа NFT с контракта атакующему происходит за 0.01 ETH вместо 1 ETH
7. Атакующий продает NFT в другом месте за полную стоимость
8. Атакующий свапает ETH на USDC обратно, возвращая TSWAP пул в нормальное состояние
9. Атакующий возвращает Flash Loan + комиссии за использование средств
10. Профит атакующего равен цена NFT - комиссии за флешлоан

Как защититься
- Собирать данные по цене из нескольких источников
- Установить пороговые значения для цен
- Поставить таймлок на обновление цены, чтобы не допустить мгновенных колебаний
- Запрашивать подписи от поставщиков цен

Схему взял отсюда
  • ❤ 6
Post #26 212
Несколько выпал из ведения канала, но новости такие: через неделю после окончания курса у меня появилась part time работа консультантом по безопасности

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

+ уложились в голове некоторые концепции, казавшиеся очень сложными из первой части курса
  • ❤ 8
Post #25 268
Закончил security курс на Cyfrin, про который писал в этом посте про то как и где учиться

Ушло на это около 8 недель, но в середине я потратил около 2.5 недель на курс по базовому foundry

Впечатления сугубо положительные, местами было сложно, но в целом курс просто топовый

Сначала тебя ведут за руку буквально на каждом шагу, постепенно отдавая какие-то вещи на самостоятельную проработку

В итоге в портфолио оказывается 5 отчетов по аудиту, но главное - появляется понимание как вообще работать + десятки полезных ссылок на инструменты/разборы атак и прочее

Дальше по плану сделать отчет по какому нибудь competitive audit, а затем начать второй курс по безопасности по OP кодам и assembly

UPD. Еще кстати отдельно надо отметить, что Патрик (который курс ведет) много уделяет поддержке/подбадриванию и это очень помогает
Telegram Noobing Security Research Какая база нужна и где учиться Security Research? Сразу оговорюсь, что в мою область интересов пока входит только EVM, так что и говорить буду об этом Минимальный багаж знаний выглядит так: - Представление хотя бы в общих чертах как работает блокчейн …
  • ❤ 8
Post #24 250
Дальше атака развивается так:
- Происходит вызов Vault::increasePosition, через который открывается шортовая позиция размером 15.385кк USD в WBTC
- Открытие этой позиции обновляет значение globalShortSizes, которое вырастает мгновенно
- Контракт вызывает unstakeAndRedeemGlp, который должен анстейкнуть и вернуть GLP токены, купленные на flashloan

Здесь остановимся подробнее. Атакующему вернули только 386к токенов GLP, еще 9.731кк USDG были сожжены а 88 BTC отправились на атакующий контракт.

Чтобы понять почему так получилось, надо понимать как работает GlpManager:: _removeLiquidity. В этом методе есть формула подсчета того, сколько USDG должно быть сожжено, выглядит она так

usdgAmount = _glpAmount * aumInUsdg / glpSupply

Потом это подсчитанное количество USDG отправляется в Vault и обменивается на желаемый актив (WBTC), AUM (Assets Under Management - активы под управлением) считается так:

aum = ((totalPoolAmounts - totalReservedAmounts) * price)
+ totalGuaranteedUsd + GlobalShortLoss
- GlobalShortProfits - aumDeduction


Из-за того, что на предыдущем шаге была создана большая шорт позиция, globalShortSizes вырос. А getGlobalShortAveragePrice был уменьшен еще чуть раньше, это привело к тому, что эта шорт позиция считается убыточной. Из-за этого резко возрастает GlobalShortLoss, оказывая влияние на AUM (Он растет, значит GLP стал дороже, а значит за один GLP биржа отдаст больше средств), что позволяет в конечном итоге получать атакующему больше активов, чем положено.

Далее атакующий просто продолжает вызывать unstakeAndRedeemGlp, получая средства от манипуляции размером AUM

На этом я остановлюсь, но в источниках, указанных в начале поста вы можете почитать про то, куда и как выводил деньги атакующий, посмотреть на транзакции, код и прочее.

Единственный непонятный мне момент заключается в том, как именно происходила манипуляция с globalShortAveragePrices, что у нее так сильно снизилось значение. Если найду ответ, до дополню пост
Medium Inside the GMX Hack: $42 Million Vanishes in an Instant Recommendation: Add reentrancy lock protections to core functions and strictly limit the impact of any single factor on pricing mechanisms.
  • ❤ 4
Post #23 205
Взлом GMX, что это было?

TLDR; 9 июля 2025 года хакер обнаружил и использовал уязвимость в смарт-контракте GMX v1, что привело к краже около 42 миллионов долларов из пула ликвидности GLP на сети Arbitrum. Уязвимость типа reentrancy позволилa манипулировать шортами и завышать стоимость токена GLP. В данный момент хакер вернул 40.5 миллионов по соглашению с биржей, а GMX v1 остановлен.

Материал для поста взят из разборов от SlowMist, SolidityScan а так же из X GMX

Ключевые моменты

Атака стала возможной из-за наличия двух фундаментальных недостатков дизайна GMX v1.
1. Некорректная работа с globalShortAveragePrice. Система обновляла значение глобальной цены коротких позиций только при открытии шорт, а при закрытии - нет.
2. Мгновенный рост globalShortSizes. При открытии шорт глобальный размер коротких позиций возрастает немедленно, что оказывает влияние на расчет AUM (Assets Under Management) - средства под управлением и это позволяет манипулировать ценой токена GLP в GlpManager.sol (токен ликвидности пула GMX).

В атаке так же использовалась уязвимость в Timelock.enableLeverage механизме, который вызывался во время работы Keeper (это бот, через который происходит работа с ордерами). Глобально можно сказать, что проблема заключается в десинхронизации внутренних подсчетов механизма расчета цен GMX.

Подготовка к атаке

С атакующего контракта были исполнены две транзакции: открытие длинной позиции и ордер на уменьшение позиции, который позже должен был исполнить keeper.

Когда keeper получил ордер на уменьшение позиции, он вызвал PositionManager::executeDecreaseOrder, который в свою очередь сделал внутренний вызов Timelock.enableLeverage, который в свою очередь поставил флаг _isLeverageEnabled контракта Vault в позицию true (да, атака не самая простая). Постановка этого флага - ключевой момент.

После этого метод OrderBook::executeDecreaseOrder приступает к уменьшению позиции. Позиция скорректирована, и collateral (токен залогa), в данном случае WETH, должен вернуться на атакующий контракт. Но WETH перед трансфером разворачивается в ETH и это вызывает fallback функцию атакующего контракта - здесь и начинается reentrancy

fallback функция отправляет 3001 USDC в Vault::increasePosition и открывает шорт с х30 плечом, и соответствующий ордер на закрытие летит в keeper

Как работает Vault::increasePosition
В функции increasePosition в первую очередь происходит вызов внутренней функции _validate, чтобы проверить разрешено ли использовать плечи (тот самый _isLeverageEnabled, который заранее переведен в true). Такая ситуация возможно только если операцию проводит keeper, то есть прямой вызов контракта приведет к ошибке.

Поэтому атакующий и создал заранее ордер на уменьшение позиции, который исполнит keeper, и так получил доступ к использованию плечей в своей fallback функции, с помощью которой в осуществил повторный вход (reentrancy) и вызвал Vault::increasePosition, напрямую создав короткую позицию.

Ко всему прочему, Vault::increasePosition обновляет значение globalShortAveragePrices, когда шорт позиция открывается, а вот Vault:: decreasePosition не обновляет, когда шорт закрывает.

Это позволило использовать эти 3к USDC многократно, чтобы повлиять на globalShortAveragePrices.

В итоге хакеру удалось уменьшить среднюю цену шорта примерно в 57 раз относительно настоящей цены по маркету WBTC. Все эти операции проводились пока keeper исполнял ордер по уменьшению позиции.

Что было дальше
После того как keeper получил финальный ордер на закрытие позиции, он вызвал OrderBook::executeDecreaseOrder. Затем возврат ETH на атакующий контракт снова запустил fallback функцию, но на этот раз она:
- Взяла flashloan на Uniswap в размере 7.538кк USDC
- Вызвала RewardRouterV2::mintAndStakeGlp, где сминтила и стейкнула 4.129кк GLP за 6кк USDC
  • ❤ 3
Post #22 182
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.4

Оценка нахождения 0-day уязвимостей
6й датасет. Как показано в рисунке 1, PromFuzz успешно находит 30 багов нулевого дня в 6 DeFi-проектах. О них сообщили соответствующим разработчикам, и 24 из них уже получили CVE ID. Общая рыночная стоимость DeFi-проектов, затронутых этими багами, оценивается примерно в $18.2 миллиарда.

Далее авторы приводят два сценария взлома, которые были обнаружены с помощью PromFuzz, один из них реализует рискованный первый депозит, а второй манипуляцию ценой оракула. Обе уязвимости тянут на отдельные небольшие посты, так что я пропущу.

Послесловие

Хотя PromFuzz достигает значительных результатов в обнаружении функциональных багов в смарт-контрактах, у него есть несколько ограничений.

Во-первых, некоторые пропущенные баги (false negatives) возникают из-за неточностей при извлечении критических переменных и присущей случайности анализа на основе LLM. Несмотря на эти проблемы, PromFuzz всё равно превосходит существующие методы в выявлении более сложных функциональных багов.

Кроме того, анализ багов на данный момент ориентирован на четыре основные категории с десятью подкатегориями, что может приводить к пропуску некоторых более сложных типов багов. В будущем авторы планируют дообучить специализированную LLM для более точного обнаружения функциональных багов в смарт-контрактах и разработать новые промпты, чтобы охватить более широкий спектр категорий багов, тем самым повысив полноту PromFuzz.

Более того, поскольку анализ частично опирается на ItyFuzz, который изначально не предназначен для функциональных багов и не использует информацию о состоянии контракта в полной мере, будущие усилия будут направлены на более тесную интеграцию LLM с динамическими методами анализа. Это позволит эффективнее и более полно использовать данные о состоянии контракта, чтобы находить ещё более глубокие функциональные баги.

Мои впечатления
В целом, это хорошая динамика для отрасли, такие исследования и разработки однозначно пойдут на пользу всему сообществу. На данный момент наверное немного замороченно ставить эту систему на свою машину (авторы об этом тоже пишут в начале), но сама структурированность подхода может только восхищать. Даже если не внедрять в свой рабочий процесс PromFuzz полностью, то использование отдельных частей может помочь, написание инвариантов на данный момент краеугольный камень в работе любого аудитора. Потому что это и непросто, и может давать потрясающие результаты одновременно. В любом случае, буду ждать продолжения
  • ❤ 3
Post #20 173
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.3

Подытоживая эту часть можно взглянуть на алгоритм на рисунке 1.
Сначала компилируются целевые смарт-контракты с проверками инвариантов. Затем выполняется фаззинг на этих смарт-контрактах. Когда фаззер активирует проверку инвариантов и обнаруживает несоответствие, он сигнализирует о наличии ошибки. В соответствии с результатами генерируется полный отчет об ошибках, в котором документируются все выявленные функциональные ошибки в смарт контрактах.

Погнали дальше

Оценка системы

Для оценки системы авторы отвечают на 4 ключевых вопроса:
1) Как двухагентная стратегия проектирования промптов влияет на производительность PromFuzz?
2) Какова точность PromFuzz в генерации инвариантных чекеров?
3) Насколько эффективен PromFuzz при обнаружении функциональных ошибок в смарт-контрактах?
4) Способен ли PromFuzz обнаружить функциональные ошибки нулевого дняв реальных смарт-контрактах?

Пару слов о датасете

Было создано 6 датасетов, которые покрывают разные категории багов. Источников послужил DeFiHackLabs, Web3bugs, GPTScan, а так же контракты реальных DeFi проектов.
1) Безбаговый датасет. Тут всё понятно, 303 контракта на 6 ЕВМ сетях
2) DeFi датасет с эксплойтами. 7 контрактов, которые подвергались реальным атакам и были успешно взломаны. 4 случая манипуляции ценой оракула, 2 неавторизованное поведение, 1 некорректный механизм контроля
3) Багованный датасет. 36 контрактов, где были найдены и подтверждены высокорисковые уязвимости на платформах типа Code4Arena, Immunefi. Содержат 10 функциональных багов, из которых 5 незащищенная логика рассчетов, 2 некорректный механизм контроля, 2 неавторизованное поведение, 1 манипуляция ценой оракула.
4) Синтетический с багами датасет. Специально добавлены баги в 44 контракта, всего 6 штук. 4 связаны с неавторизованным поведением, 2 с некорректным механизмом контроля
5) Датасет извлеченных критических переменных и ключевых операторов (те самые statement, которые я не понимаю как правильно перевести). 55 извлеченных переменных и ключевых операторов из 23 контрактов.
6) Датасет реальных DeFi проектов. 6 проектов, которые проходили публичный аудит во время написания статьи

Оценка двухагентной архитектуры
Велась по первому датасету. Сравнивалась с одноагентными архитектурами GPTScan и SMARTINV. Если коротко, то SMARTINV сильно проигрывает (построен на LLаMA-7b), а GPTScan держится по ложно-позитивным менее чем в проценте от PromFuzz архитектуры, оба построены на GPT-4-turbo.

Так же PromFuzz с двумя агентами сравнивали с PromFuzz где есть только аудитор. Аудитор в одиночку справился значительно хуже. В этом сравнении использовались датасеты 2, 3, 4.

Двухагентная версия достигает полноты (recall) 91.30% и F1 53.85%, обнаружив 21 верный баг и имея 34 ложных срабатывания при 2 пропущенных багах.

Общее положение такое, что атакующий находит такие векторы атаки, которых на самом деле нет, а аудитор пропускает потенциальные уязвимости даже высокого ранга. При этом сам GPT не всегда понимает промпты.

Оценка точности чекеров инвариантов
5й датасет.
Извлечение переменных - точность составила 100%.

Извлечение операторов — 83.33%, с одним ложным срабатыванием. Это ложное срабатывание связано со сложной бизнес-логикой в смарт-контрактах, где PromFuzz не смог различить несколько похожих действий в одном случае.

Эти критические переменные и операторы должны были бы дать 23 правильных проверяющих инварианта, но в итоге PromFuzz сгенерировал 22 верных, что соответствует точности 95.65%.

Оценка точности обнаружения функциональных багов
Сравнение PromFuzz с четырьмя готовыми инструментами: GPTScan, SMARTINV, ItyFuzz и SMARTIAN. Здесь проще посмотреть на рисунок 2. TP, FP, FN - это True Positive, False Positive и False Negative соответственно. PromFuzz достигает общей полноты (recall) 86.96% и F1 93.02%, обнаружив 20 верных багов, 0 ложных срабатываний и с 3 пропущенными багами.
  • ❤ 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →