年底,是系统高危频发和黑客活跃期,来自比特安数据检测中心最新检测的数据,最近一段时间,去中心化交易平台安全隐患不断,成为安全的雷区,其中 DODO 的 wCRES/USDT V2 资金池被黑客攻击,转走价值近 98 万美元的 wCRES 和近 114 万美元的 USDT成为业内比较突出的案例。
这次合约漏洞的作案手法,我们用一个词来形容:偷天换日!
比特安安全审计中心对此次时事件跟进并分析,下面将细节分析给大家参考。
通过查看本次攻击交易,比特安审计的技术人员发现整个攻击过程非常简单。攻击者先将 FDO 和 FUSDT 转入 wCRES/USDT 资金池中,然后通过资金池合约的 flashLoan 函数借出 wCRES 和 USDT 代币,并对资金池合约进行初始化操作。
那么为何存入 FDO 和 FUSDT 代币却能成功借出 wCRES 和 USDT ,并且初始化资金池合约呢?是因为资金池的闪电贷功能有漏洞吗?
比特安团队通过分析具体代码发现,在进行闪电贷时会先通过 _transferBaseOut 和 _transferQuoteOut 函数将资金转出,然后通过 DVMFlashLoanCall 函数进行具体外部逻辑调用,最后再对合约的资金进行检查。可以发现这是正常闪电贷功能,那么问题只能出在闪电贷时对外部逻辑的执行上。
通过分析闪电贷的外部逻辑调用,可以发现攻击者调用了 wCRES/USDT 资金池合约的 init 函数,并传入了 FDO 地址和 FUSDT 地址对资金池合约进行了初始化操作。
到这里就可以发现资金池合约可以被重新初始化。
通过具体的代码分析得出,资金池合约的初始化函数并没有任何鉴权以及防止重复调用初始化的逻辑,这将导致任何人都可以对资金池合约的初始化函数进行调用并重新初始化合约。至此,比特安团队得出了本次攻击的完整流程:
1、攻击者先创建 FDO 和 FUSDT 两个代币合约,然后向 wCRES/USDT 资金池存入 FDO 和 FUSDT 代币。
2、接下来攻击者调用 wCRES/USDT 资金池合约的 flashLoan 函数进行闪电贷,借出资金池中的 wCRES 与 USDT 代币。
3、由于 wCRES/USDT 资金池合约的 init 函数没有任何鉴权以及防止重复调用初始化的逻辑,攻击者通过闪电贷的外部逻辑执行功能调用了 wCRES/USDT 资金池合约的初始化函数,将资金池合约的代币对由 wCRES/USDT 替换为 FDO/FUSDT。
4、由于资金池代币对被替换为 FDO/FUSDT 且攻击者在攻击开始时就将 FDO 和 FUSDT 代币存入了资金池合约,因最终通过了闪电贷资金归还的余额检查而获利。
本次攻击发生的主要原因在于资金池合约初始化函数没有任何鉴权以及防止重复调用初始化的限制,导致攻击者利用闪电贷将真币借出,然后通过重新对合约初始化将资金池代币对替换为攻击者创建的假币,从而绕过闪电贷资金归还检查将真币收入囊中。
比特安审计中心在此提醒大家,安全无小事,对区块链项目智能合约的代码审计势在必行,一个专业的安全审计团队能够为后期项目的安全进行带来安全保障。如本次dodo被黑事件恰恰是因为底层合约的漏洞造成如此严重的后果,比特安安全团队希望以此警示大家,重视区块链项目的安全审计问题,减少直至杜绝此类安全问题再次发生!