2024 年 5 月 28 日,Orion 项目遭到攻击,截至本文撰写时造成约 645,000 美元的损失。让我们来看看这次攻击是如何发生的细节。
概述
攻击者地址: https ://bscscan.com/address/0x51177db1ff3b450007958447946a2eee388288d2
https://bscscan.com/address/0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
攻击合约: https ://bscscan.com/address/0xf8bfac82bdd7ac82d3aeec98b9e1e73579509db6
受害人合同:
https://bscscan.com/address/0xc662cea3d8d6660ca97fb9ff98122da69a199cd8
攻击交易: https ://bscscan.com/tx/0x660837a1640dd9cc0561ab7ff6c85325edebfa17d8b11a3bb94457ba6dcae18c
准备交易:
将资产存入
锁定股权
兑换 Atomic
请求释放股权
兑换 Atomic
将资产存入
锁定股权
兑换 Atomic
请求释放股权
兑换 Atomic
ExchangeWithGenericSwap
实现了一个代币交换和质押平台。用户可以通过调用lockStake
或doRedeemAtomic
函数存入余额进行质押或转账。具体来说,通过转账功能,用户可以推迟负债,而不会影响质押的代币数量,只要负债不超过总余额即可。
漏洞分析
这次攻击似乎遵循了一个简单的模式:攻击者通过一系列准备交易,精心操纵了地址为0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
的账户的负债数组。
首先,他向账户存入 10,000,000 ORN,并调用lockStake
函数来锁定和质押代币,这将 assetBalances 值减少到 0。
之后,他使用redeemAtomic
函数将相同数量的ORN转移到另一个名为B
受控账户。该函数允许用户通过setLiability
机制在转移代币时产生负债。当用户转移的代币数量大于其资产余额时,系统会检查他们是否有足够的余额和授权存入所需数量的代币。如果余额仍然小于0,系统就会为该用户设置负债。该机制由系统的检查来确保,该系统会计算总余额,包括抵押资产和负债资产。
回到真实的案例,攻击者从0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
进行转账,该地址的余额为 0,结果系统给这个地址设置了 10,000,000 的负债,导致账户余额变为 -10,000,000。
接下来攻击者调用requestReleaseStake
取出所有质押的代币,并将这些代币添加到0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
的余额中,使该账户的资产余额恢复为 0。然后他再次调用redeemAtomic
将另外 10,000,000 ORN 转移到B
地址。此操作将0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
的负债数组操纵为包含两个具有相同值的元素: ["ORN", timestamp, 10,000,000]
。
攻击者又存入了 20,000,000 ORN,再次重复了所有步骤。此时0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
的负债数组包含三个元素: ["ORN", timestamp, 10,000,000]
,而该账户的资产余额只有 -10,000,000。
通过操纵负债数组,攻击者利用PancakeSwap
的闪电贷将大量资金从B
账户转回0xf7a8c237ac04c1c3361851ea78e8f50b04c76152
,导致余额从 -10,000,000 变为约 196 万。结合之前的信息,攻击者可以从系统中借到比应得金额更多的资产。随后,攻击者再次利用redeemAtomic
函数将代币转入攻击合约。
如上文所述,有一个检查机制来确保用户的总余额(包括资产余额和质押余额)减去负债余额必须大于 0。
系统首先通过calcAssets
函数计算用户的资产余额。然后,它调用calcLiabilities
将用户的所有负债相加,并通过对这些值进行减法来计算最终状态。只有POSITIVE
状态才可以接受转移代币。
由于用户资产余额约为196万,且负债数组仍然存在,原本应该为负数的liabilityValue
值变成了正数,因此攻击者可以在借入其他代币时绕过健康检查机制,并且通过操控负债数组,攻击者可以借入更大价值的代币。
他利用这种攻击模式转移和提取了价值约 645,000 美元的 ORN、 BNB、BUSD-T 代币及其他代币。
漏洞利用之后,攻击者归还了从PancakeSwap
闪电贷中借入的贷款。
该漏洞的根本原因是受害者没有正确管理负债。当用户的资产余额发生变化时,必须更新负债。然而,在requestReleaseStake
中,在释放资产时未能更新用户的负债是导致此漏洞的关键因素。
此外,系统在更新或删除负债时,应检查用户是否对同一代币有不同的负债。
总之,在余额更新过程中缺乏对负债的有效控制可能会导致严重的财务差异和用户不满。实施强有力的控制措施以实时监控和管理负债水平至关重要,确保用户保持可持续的余额并防止平台内的财务不稳定。通过解决这些问题,我们可以为所有用户营造一个更安全、更值得信赖的环境。