说明
网络上没有明确地对于这个漏洞分析,仅有blocksecteam发布的一条twitter状态,ATK on BSC was attacked。后面经过对于ATK和相关的合约分析,最终确认是一个邀请获取奖励的漏洞。
漏洞合约是一个闭源合约,ATK代币只是合约用来查看用户的ATK代币的数量用于确定发放的奖励。
漏洞分析
攻击分析
再对攻击分析之前,首先通过漏洞合约正常的交易分析其功能实现。
分析正常的交易0x8878b7ec586215a9da59ee7473473d4b60d28d08791c13ab2273ba7566b3bacf
可以看到漏洞合约向调用者放松了两次ATK的token。
分析0x8878b7ec586215a9da59ee7473473d4b60d28d08791c13ab2273ba7566b3bacf的调用栈信息
基本上就明确了0x8a809095()(claimToken1())函数作用,确定目标账户中的ATK和BUSD的数量,根据这两者的数量,发放对应的ATK作为奖励。
分析攻击合约:0x55983d8701e40353fee90803688170a16424ee702f6b21bb198bb8e7282112cd
攻击者利用闪电贷获取获取到BUSD,然后调用claimToken1()获取奖励。
分析攻击交易0x55983d8701e40353fee90803688170a16424ee702f6b21bb198bb8e7282112cd的调用栈信息
通过攻击交易的代币转移和调用栈的分析,基本上确定了攻击流程:
- 通过闪电贷获取
BUSD的代币 - 调用漏洞合约的
claimToken1()获取奖励 - 获取奖励并完成闪电贷还款
漏洞复现
确定了漏洞攻击原理之后,我们就可以进行漏洞复现了。复现代码如下:
1 | function testExploit() public{ |
通过forge test测试获得的调用栈信息,基本上符合我们的预期。最终获得的ATK的奖励是:
1 | [PASS] testExploit() (gas: 510142) |
我们通过闪电贷的方式,最终成功获得了44142787,实施了一次完整的攻击。
调用栈结果如下所示:
调用栈的信息也基本上和我们之前分析的是一致的。通过闪电贷获取BUSD,然后调用claimToken1()获取奖励,最终获取了44142787个ATK。
总结
整体来说,本次的漏洞原理比较好理解,最关键的地方是需要分析出漏洞合约中的claimToken1()存在奖励漏洞。这个需要我们对这个漏洞合约进行细致的分析从而分析判断出存在问题,然后利用闪电贷获得奖励。
目前这种奖励漏洞基本上都是相似的问题,但是这个漏洞合约基本上都是闭源的,导致之前被攻击的概率较少。目前的情况是,现在这种闭源的合约慢慢地也开始受到了攻击。存在这样漏洞的合约肯定不止这几个。
对于我们安全分析来说,最好是能够总结发现目前已经披露出来的奖励漏洞,总结出规律,看看如何能够在闭源合约中发现这种漏洞。
参考
https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/ATK_exp.sol