Back to Blog

Потеряно около $542 тыс.: эксплуатация уязвимости MakerDaoBot | Еженедельный обзор BlockSec

Code Auditing
14 октября 2026 г.
6 min read
Key Insights
  • В этом отчёте рассматривается 1 инцидент безопасности в сети Ethereum с оценочным ущербом около $542K.

  • В функции MakerDaoBot, позволявшей любому вызывающему передать внешнему контракту контроль над внутренними балансами бота, отсутствовала проверка прав доступа.

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

За прошедшую неделю (2026/10/05 - 2026/10/11) мы зафиксировали 1 инцидент безопасности с совокупным ущербом примерно $542K.

Дата Инцидент Тип Оценка ущерба
2026/10/06 MakerDaoBot Отсутствие контроля доступа ~$542K

Бесплатная проверка безопасности

Быстрая проверка безопасности с помощью нашей собственной системы автоматизированного анализа.

Проверить бесплатно

Главное за неделю: MakerDaoBot

6 октября 2026 года злоумышленник воспользовался отсутствием контроля доступа в MakerDaoBot, устаревшем боте для ликвидаций MakerDAO в сети Ethereum, и вывел 200 ETH стоимостью около $542K. Уязвимая функция позволяла любому вызывающему указать внешний контракт, предоставить ему контроль над балансами бота и выполнить его код. Злоумышленник воспользовался этим, чтобы в одной транзакции завершить четыре старых аукциона по продаже залога и перевести высвободившиеся ETH.

Контекст

MakerDaoBot участвовал в аукционах по продаже залога ETH-A в устаревшей системе MakerDAO через Flipper — контракт аукционов, который использовался в прежней системе ликвидаций. Бот управлял разрешениями Vat, вносил и выводил ETH и DAI, а также обрабатывал задачи ликвидации.

Vat — это внутренний реестр MakerDAO. Он учитывает свободный залог каждого адреса по типу залога в gem[ilk][address] и внутренний баланс DAI в dai[address]; отдельного кошелька или контракта счёта нет. Поэтому балансы MakerDaoBot в Vat — это записи реестра, привязанные к адресу самого контракта бота.

Вызов hope(usr) не переводит эти средства. Он устанавливает can[msg.sender][usr] равным 1, позволяя usr пройти проверку разрешения wish() в Vat и распоряжаться балансами, записанными за msg.sender. Такие функции, как flux() и move(), используют эту проверку при переводе внутреннего залога или DAI.

mapping(address => mapping (address => uint)) public can;
function hope(address usr) external note { can[msg.sender][usr] = 1; }
function nope(address usr) external note { can[msg.sender][usr] = 0; }
function wish(address bit, address usr) internal view returns (bool) {
    return either(bit == usr, can[bit][usr] == 1);
}

mapping (bytes32 => mapping (address => uint)) public gem;  // [wad]
mapping (address => uint256)                   public dai;  // [rad]

function flux(bytes32 ilk, address src, address dst, uint256 wad) external note {
    require(wish(src, msg.sender), "Vat/not-allowed");
    gem[ilk][src] = sub(gem[ilk][src], wad);
    gem[ilk][dst] = add(gem[ilk][dst], wad);
}
function move(address src, address dst, uint256 rad) external note {
    require(wish(src, msg.sender), "Vat/not-allowed");
    dai[src] = sub(dai[src], rad);
    dai[dst] = add(dai[dst], rad);
}

Анализ уязвимости

Первопричиной стало отсутствие контроля доступа к функции 0x8804d1de() в контракте MakerDaoBot по адресу 0x6839...5546. Функция рассматривала varg0 как адрес внешнего контракта (далее — адаптер) и вызывала по этому адресу drip(), vat(), а затем join(). Получив адрес Vat через vat(), бот проверял, может ли адаптер распоряжаться его балансами в Vat. Если нет, бот вызывал hope(varg0), предоставляя разрешение, а затем вызывал join() у того же адаптера.

Другие привилегированные точки входа в том же контракте перед выполнением операций проходили проверку ds-auth. На сравнении ниже видно, как две защищённые точки входа передают селектор bytes4 и msg.sender во вспомогательную функцию авторизации, а при неудачной проверке отменяют выполнение с ошибкой ds-auth-unauthorized. В функции 0x8804d1de() аналогичной проверки вызывающего не было.

Таким образом, функция 0x8804d1de() позволяла любому вызывающему выбрать адрес, который получит разрешение в Vat. Бот предоставлял этому адресу разрешение через hope() и сразу вызывал его функцию join(). Во время этого внешнего вызова разрешение оставалось действующим, позволяя коду по выбранному адресу распоряжаться внутренними балансами залога и DAI бота.

Анализ атаки

Приведённый ниже анализ основан на транзакции 0xbb6940...f3a88c.

  • Шаг 1: Внешний аккаунт злоумышленника вызвал развёрнутый им атакующий контракт. Этот контракт развернул вредоносный адаптер, а затем вызвал функцию 0x8804d1de() MakerDaoBot, передав адрес адаптера. Бот не обнаружил существующего разрешения в отображении can контракта Vat и вызвал hope(), позволив адаптеру распоряжаться балансами, записанными за адресом бота.
  • Шаг 2: MakerDaoBot вызвал функцию join() адаптера. Пока разрешение действовало, вредоносный код вызвал deal(uint256 id) у выведенного из эксплуатации контракта Flipper для ETH-A и завершил аукционы 1457, 1458, 1459 и 1460. Затем адаптер воспользовался разрешением Vat, чтобы перевести себе 200 единиц залога ETH-A с баланса MakerDaoBot, вывел их через ETH Join, получив 200 WETH, и перевёл токены атакующему контракту.
  • Шаг 3: Атакующий контракт обменял 200 WETH на ETH и отправил 200 ETH на внешний аккаунт злоумышленника. На тот момент их стоимость составляла около $542K.

Начните работу с Phalcon Explorer

Изучайте транзакции, чтобы принимать взвешенные решения

Попробовать бесплатно

Заключение

Первопричиной стало отсутствие контроля доступа в MakerDaoBot, а не ошибка в системе разрешений Vat от MakerDAO. Публичная функция позволяла любому вызывающему выбрать внешний контракт, предоставить ему контроль над внутренними балансами бота и выполнить его код. Злоумышленник воспользовался этим, чтобы завершить четыре аукциона в устаревшей системе и вывести 200 ETH.

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

Лучший аудитор безопасности для Web3

Проверьте архитектуру, код и бизнес-логику до запуска

О BlockSec

BlockSec — поставщик комплексных решений в области безопасности блокчейна и соблюдения нормативных требований в сфере криптовалют. Мы разрабатываем продукты и услуги, которые помогают клиентам проводить аудит кода (в том числе смарт-контрактов, блокчейнов и кошельков), предотвращать атаки в реальном времени, анализировать инциденты, отслеживать незаконно полученные средства и выполнять требования ПОД/ФТ на всех этапах жизненного цикла протоколов и платформ.

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

Sign up for the latest updates

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit