零时科技 || Bankroll 攻击事件分析
2024-09-29 16:04
零时科技
2024-09-29 16:04
订阅此专栏
收藏此文章


背景介绍

近期,我们监控到一起针对 BNB Smart Chain 的链上攻击事件,

https://bscscan.com/tx/0xd4c7c11c46f81b6bf98284e4921a5b9f0ff97b4c71ebade206cb10507e4503b0


被攻击的项目为 Bankroll Network 的 DeFi 项目



攻击及事件分析

首先,攻击者通过 pancakeSwap 利用 flash 借了 16,000 WBNB ,



随后,调用 Bankroll 的 buyfor 函数,将闪电贷获得的 16000 WBNB 购买了 Bankroll 的 share ,类似于质押。



接着,攻击者大量调用 buyfor 函数,使 Bankroll 自己的合约购买 Bankroll 的 share。



我们看一下 buyfor 函数的定义,如下图:



首先,函数从 _customerAddress 将 token 转入当前合约,其中 token 为 WBNB 。随后,调用 purchaseTokens 购买 share ,最后调用 distribute 函数。


我们看一下该函数的定义:



在该函数中,会更新 profitPerShare_ ,该值为拥有一个 share 的利润。然后,通过 sell 函数将最开始利用 buyfor 转入 WBNB 获取的所有 share 卖出,再通过 Withdraw 提取所有的 WBNB 。


我们看一下 sell 函数的定义: 



可以看到, payoutsTo_[_customerAddress] 和 profitPerShare_ 的关系为, profitPerShare_越大, payoutsTo_[_customerAddress] 越小,且 payoutsTo_[_customerAddress] 为负数。


接下来我们再看一下 withdraw 函数的定义: 



可以看出,提取的金额来源于 myDividends 函数,我们继续跟踪;



由上述分析,我们可以得出结论,只要 profitPerShare_ 越大,相同 share 下可以提取的 WBNB 就越多。那么,由于攻击者一开始通过 buyfor 获得了一定数量的 share ,攻击者只需要操纵 profitPerShare_ ,将其数值拉高即可提空合约中的 Token 。再回到最初分析 buyfor 函数得到的结论,只要调用 buyfor 函数购买 share 即可拉高 profitPerShare_ 。但是 buyfor 函数没有限制 _customerAddress 不能为该合约本身,所以,攻击者通过将 _customerAddress 传入 Bankroll 的合约地址,即可完成不用转入 WBNB 来拉高 profitPerShare_ ,最终完成攻击。攻击者从 Bankroll 合约中获得 16,412 WBNB ,还掉闪电贷的本金和利息 16,008 WBNB ,获利 403 WBNB 约合 230k USD 。 



总结

本次漏洞在于 Bankroll 的代码中,没有做输入限制,导致攻击者可以使购买方为项目方本身。使得每一个单位的 share 被大幅拉升,从而使攻击者将 Bankroll 的所有资产已 share 的利润方式提取。建议项目方在合约上线前,针对智能合约进行充分的审计和交叉审计,避免此类安全问题。

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

零时科技
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开