Обманчивые смартконтракты

Автор публикации: Лукьянов Артур, младший исследователь, CyberOK

Привет! Меня зовут Артур, я являюсь стажёром в компании СайберОК и занимаюсь анализом защищенности. В этой статье я поделюсь с вами тем, как я искал жертву, а нашел хакера, и почему не все уязвимости стоит эксплуатировать.

Блокчейн в сети Ethereum полностью публичен, и каждый может посмотреть, какие контракты запущены в сети, каким образом они взаимодествуют, сколько денег перетекает с контракта на контракт. Но сеть довольно большая и постоянно расширяется. Каждые 14 секунд создается новый блок, возникают новые сущности, иногда с интересными свойствами и уязвимостями. Чтобы не отстать, нужна автоматизация, поэтому на стажировке я начал писать тулу для сбора Threat Intelligence информации из сети Ethereum.

Атака контрактов

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

Технически это несложно, например, можно отслеживать вызовы между контрактами через эмуляцию транзакции. Конечно, нам нужны не все вызовы, но те, которые характерны для конкретных атак и приводят к переводу средств. Сферические Гонки в Эфире мало кому интересны.

Реализовав данную стратегию для reentrancy attack, мы сразу обнаружили интересный контракт.

Обманчивые смартконтракты

Рассмотрим транзакцию подробнее:

Обманчивые смартконтракты

Это выглядит как неудачная попытка эксплуатации reentrancy — выполнение транзакции закончилось через revert, а деньги не были пересланы на атакующий контракт.

Интересно, почему атака не прошла? Мы быстро сделали PoC и запустили его в testnet. Но что-то пошло не так, и вместо ожидаемых эфиров мы увидели скучный revert. При дебаге транзакции, изучив вызываемые функции я заметил кое-что подозрительное. Эксплойт работает — контракты вызывают друг друга в этой рекурсии. Однако при выходе из рекурсии начинает происходить что-то странное — вызывается совсем другой адрес, от которого и происходит revert.

Разбор найденных смарт-контрактов

Рассмотрим смарт-контракт «жертву". Сразу бросается в глаза строчка »msg. sender. call. value(_am) ()" с классической уязвимостью, приводящей к reentrancy. При этом, даже перечитав контракт в шесть глаз, мы не нашли в исходном коде контракта people_BANK и Log ничего, что могло бы помешать проведению атаки.

... pragma solidity ^0.4.25; contract PEOPLE_BANK { function Collect(uint _am) public payable { ... if(msg.sender.call.value(_am)()) { ... LogFile.AddMessage(msg.sender,_am,"Collect"); } ... function PEOPLE_BANK(address log) public{ LogFile = Log(log); } }

Но факт остается фактом, эксплуатация контракта приводила к отмене транзакции — revert. Возможно стоит заглянуть глубже, в байткод контрактов.

Декомпилируем байт-код на etherscan и обнаруживаем странное… Части кода вообще нет в исходнике!

Обманчивые смартконтракты

Если мы выводим деньги с контракта (операция начинается с 'C' — то есть 'Collect'), то требуется чтобы количество выводимых средств было меньше, либо равно нулю. Есть исключение — адрес, который находится на storage slot 6 — "0x0a494fec232c75df8ba0a781015c2382fef5abc8". Это и мешает проэксплуатировать такую простую уязвимость.

Так же важно отметить, что solidity 0.4.25 имеет интересную особенность. При неудачной эксплуатации будет вызываться revert, который отменяет все вызовы через call, а криптовалюта, посланная на этот контракт, остается на нем. Учитывая, что для попытки эксплуатации требуется перевести 1 ETH, взлом уже не выглядит таким заманчивым для атакующего. Ведь по сути, при попытке эксплуатации он фактически подарит владельцу «контракта-жертвы» один маленький Эфир. Очень похоже на горшочек с медом, который уж очень странный предмет, да-да-да!

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

Однако, мы решили пойти дальше и понять поведение не только контрактов, но и злоумышленников.

Расследование

В «горшочке» находилось 20 ETH (~1.900.000 рублей на момент написания статьи). Отследив их путь, можно заметить что PEOPLE_BANK переехал на новый адрес: https://etherscan. io/address/0xe07e724a96866daae308870d1a5eb41258436b53

Обманчивые смартконтракты

Взглянем на цепочку транзакций, которая привела ETH на адрес этого контракта, используя утилиту CyberOK для Threat Intelligence в блокчейне (да, именно с нее все и началось).

Обманчивые смартконтракты

Из графа можно сделать следующие выводы:

  • Наша тула обнаружила в сети большое количество ханипотов которые связаны друг с другом.
  • Часть средств поступила через биржи (выглядят как большое скопление адресов) .
  • Существовало две цепочки, которые соединились некоторое время назад.

Попробуем раскрутить эту цепочку. Первый интересный факт — смартконтракт всё время "переезжает" на новые адреса. Вероятнее всего, это было сделано, чтобы код контракта отображался в выдаче от etherscan (500 последних verified контрактов) и привлекал новых любителей "багбаунти". Код контракта не меняется, но его имя образуется как `<случайное слово>_BANK`.

Обманчивые смартконтракты

Кроме того, существует ещё один контракт, связанный с BANK (1), находящийся на параллельной цепочке, Game (2). Его код отличается от BANK и не имеет явных уязвимостей, но схожее поведение (именование, «переезды») и пересечение цепочек транзакций на некоторых адресах, не оставляет сомнений что эти два контракта принадлежат одному владельцу.

Глубже в цепочке можно обнаружить и другие honeypot-ы:

Обманчивые смартконтракты

Время от времени на эти ханипоты попадается по несколько человек:

Попытки вывести криптовалюту с Game: https://etherscan. io/address/0xe37b75941d9b8e3139e16a774faa2d9fb1fc9f28

Обманчивые смартконтракты
Обманчивые смартконтракты

Ещё имена контрактов-ханипотов:

  • ?_BANK
  • PreSaleFund
  • try_to_Play
  • ?_GAME
  • For_Test
  • GO_GO_GO
  • Loan
  • Distributor
  • Multiplicator
  • Conductor
  • Gift_?
  • enigma
  • experimental_ETH_auction
  • AddressLotteryV2

Первый контракт («SiriusFund") был создан 1 сентября 2017 года и с небольшими изменениями (изменённые названия контрактов, имена некоторых переменных) существует и по сей день. За это время в "горшочек» 252 исследователи уязвимостей сложили 177 эфиров, которые владелец разделял между различными аккаунтами. Он старается не держать на контракте больше 30 эфиров и обычно переезжает на новый адрес раз в 4 дня.

Заключение

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

Резюмируя:

  • Всегда следует проверять байткод контракта и зависимостей, вне зависимости от того, что написано в исходниках.
  • Эксплойты надо обязательно проверять на тестнете, даже если уязвимость кажется банальной.
  • Контракты, которые требуют от вас ввода крипты, требуют особой осторожности при анализе.
  • Хакер, не дай себя хакнуть!
33
8 комментариев

Да ладно, у каждого есть ханипот в эфире, один или три.

+1 в список "Ещё имена контрактов-ханипотов:" ;))
Чем эта байда отличается от Quake Champ в 90-х, непонятно. Ну, набор псевдо англоязычных ников. Ну и что?

Товарищ "стажер", в чем смысл искать связи между виртуальными honey pots, если на улицах полно honey traps в лице очаровательных первокурсниц?

Наша тула обнаружила в сети большое количество ханипотов которые связаны друг с другом.И принадлежат Васе Пупкину из соседнего московского офиса, о чем он рассказывает всем, кто угостит его хорошим виски ..

Ну тоска ведь полная, как можно исследовать МММ, чтобы узнать, что это 3М, чтобы узнать что это 1М - зиц-председатель Мавроди ;(

Вся эта ну очень сложная аналитика имеет ровно два выхода:
1. Американцы обнуляют очередную крипто-биржу со всеми её участниками, желающими вывести бабки, когда биржа захватывает больше 5% реального рынка по вводу/выводу, а не внутренним перетасовкам в криптовалюте, которые блин ничтожны.
2. Неустановленные лица очень просят зиц-председателя биржи перевести его накопления и что там на бирже собрано на указанные кошельки, после чего он исчезает.
Иногда 1 и 2 совмещаются невероятным образом.