Как стать автором
Обновить

Как я нашел уязвимость в онлайн казино и получил $20 000 в качестве награды

Уровень сложностиСредний
Время на прочтение3 мин
Количество просмотров10K

Всем привет!

Сегодня расскажу про то, как мне удалось предотвратить возможную атаку на одно Австралийское онлайн казино, которое потенциально могло бы потерять $2.5 млн за ночь.

Немного теории

Все началось с простого вывода криптовалюты с одной CEX биржи на свой EOA(externally owned account) на блокчейне Ethereum. Дело в том, что при выводе средств, биржа обнуляет нарисованные цифры и высылает вам реальные активы со своих кошельков, на которых лежат депозиты пользователей в соотношении 1:1.

Сама on-chain транзакция имеет следующие атрибуты:

struct Transaction {
  from, \\ the sending address.
  to, \\ the receiving address (if EOA, the transaction will transfer value. If a smart contract account, the transaction will use contract code).
  value, \\ the amount of ETH to be sent from the sending address (denominated in Wei)
  data, \\ can contain code or a message to the recipient.
  gasLimit, \\ the maximum amount of gas units that can be used.
  nonce, \\ a number used to track ordering of transactions and prevent replay attacks
  maxPriorityFeePerGas, \\ the maximum amount of gas to be included as a tip to the miner.
  maxFeePerGas, \\ the maximum amount of gas willing to be paid for the transaction (including baseFeePerGas and maxPriorityFeePerGas).
  signature, \\ derived from the sending account's private key and is created when the sender signs the transaction.
}

Самый важный для нас атрибут, это "gasLimit", который задает лимит сверху на количество потребляемого газа в контексте некоторой транзакции. Если этот лимит нарушается, транзакция ревертится. Так вот, дело в том, что при выводе средств бэкенд должен указывать этот лимит в зависимости от того, какие активы выводятся. Например, для вывода эфира, требуется всего лишь 21к единиц газа, а для вывода стейблкоинов - около 60-70к.


Что происходит, если этот лимит не указан?

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

Этим я и занялся, набросал следующий контракт и задеплоил его:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;
import {console} from "forge-std/console.sol";

contract AttackScenario {
    
    address public admin;
    mapping(uint256 => uint256) doSomethingStupid;


    constructor() {
        admin = msg.sender;
    }
    
    receive() external payable {
       for (uint i = 0; i < 1000; i++) {
            doSomethingStupid[i + 1] = i; // sload operation, takes 20k gas. 
       }
    }

    function withdraw() external {
        require(msg.sender == admin);
        (bool success, ) = payable(admin).call{value: address(this).balance}("");
        require(success);
    }

}

При получении эфира этим контрактом, согласно EVM(ethereum virtual machine), вызовется функция receive() для выполнения логики, которая прописано в самой функции. А в самой функции мы производим кучу бесполезных операций, где каждая запись в storage потребляет 20k единиц газа. Таким образом мы можем сжечь около ~25млн единиц газа, а отправителю придется заплатить около $2000(зависит от стоимости газа/
эфира), даже не подозревая о том, что такое могло случиться при простом выводе.

Пример того, как мне удалось сжечь 25млн газа на сети Polygon(тестировал на дешевой сети): https://polygonscan.com/tx/0x9d8885c8f55d91562f321e9ff4bd1f33d6d4af244c44016fbbcb8b9e5e1385ec


Можно ли каким-то образом получить профит от данной атаки?

Да, вместо выполнения бесполезных записей в блокчейн, мы можем заниматься различными видами MEVa(арбитраж, сендвичи, ликвидации) и успешно уделывать самых крутых mev ботов, т.к газ для нас бесплатный, а они за это платят. Грубо говоря, мы можем приобрести эфир на одной децентрализованной бирже и продать на другой, при этом заработать $15, но потратить $20 за газ. Все эти возможности для нас становятся доступными, т.к казино платит за нас :D Таким образом, мы могли бы вытащить 70-80% из тех денег, которые были под риском.

Заключение

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

P.S. Если кому-то нужны пруфы выплат, гляньте по кошельку: 0xE26754b7aC125c20864a3a2DF1DC1E24587a6b47.
Не хочу делать рекламу казино, оставляя тут ссылку на выплаты :D

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Я находил разного рода уязвимости в web3 протоколах. Имеет ли смысл рассказывать про такое на Хабре?
88.57% Да, интересно, полезно.93
11.43% ~(Да, интересно, полезно.)12
Проголосовали 105 пользователей. Воздержались 13 пользователей.
Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 7: ↑7 и ↓0+7
Комментарии13

Публикации