3月2日,0xDAO v2 原计划上线前的几个小时,Cobo 区块链安全团队启动对该项目的 DaaS 投前例行安全评估工作,随后快速地在 github 开源的项目代码中发现了一个严重的安全漏洞。经评估,如果 0xDAO v2 此时继续上线,该漏洞预计会造成数亿美金的资产损失。
Cobo 区块链安全团队立即启动应急预案,快速通过多个渠道联系到 0xDAO 项目方,提交该漏洞的完整攻击流程,紧急叫停了项目上线,随后协助 0xDAO 项目方对该漏洞进行了修复。 日前,0xDAO 官方发布推文向 Cobo 区块链安全团队表示了感谢,并且表示会按照严重漏洞级别(Critical) 给予 Cobo 区块链安全团队漏洞赏金奖励。
项目方针对漏洞影响的反馈。
关于0xDAO
1月21日,0xDAO 项目 v1 版本上线。0xDAO v1 的目的主要是为了提高 TVL 争夺 Andre Cronje 的 veNFT 的空投份额。项目上线后很短时间内即达到 40 亿美金 TVL。在成功夺取到最大 veNFT 最大份额后,0xDAO 进入第二阶段。v2 版本的 0xDAO 将成为 Andre Cronje 新项目 Solidly 的收益聚合器(Yield Hub),项目方启动新的合约开发工作。
本次漏洞出现在 0xDAO v2 版本合约代码中。
漏洞原理
UserProxyFactory 创建的 UserProxy 是可升级合约,合约 owner 为用户地址。用户可以通过升级合约来任意修改合约代码及 storage,意味着该合约内容完全是用户可控的。 UserProxy 合约代码如下:
用户所有操作都将通过 UserProxy 合约作为中间代理与 0xDAO 协议交互。 下面是以用户执行 deposit 操作为例。UserProxyInterface 的 depositLp 方法实现如下:
用户正常的 deposit 流程为: 1. 用户首先将自己的 LP token 授权给 UserProxyInterface 合约 2. 用户调用 UserProxyInterface.depositLp 函数。 3. 根据 depositLp 代码的逻辑,用户资产先会转移到 UserProxyInterface 合约中,再授权给 userProxy 合约。 4. 最后调用 userProxy.depositLp 完成后续的 deposit 操作。
漏洞利用
根据前面的漏洞原理,Cobo 区块链安全团队实现了一个攻击脚本 Demo,代码如下:
通过调用上述合约的 run 方法,即可将任意用户授权给 UserProxyInterface 合约的任意资产转移到黑客账户中。完整的复现环境见:https://github.com/CoboCustody/cobo-blog/tree/main/0xdao_exploit在这个复现中,攻击者通过漏洞成功将受害者地址授权给 UserProxyInterface 合约的 ERC20 Token 全部转移到了攻击者地址中。
漏洞修复
经过 Cobo 区块链安全团队与 0xDAO 项目方的沟通,项目方很快确认了漏洞的存在,并部署了新的合约完成了漏洞修复。漏洞合约https://ftmscan.com/address/0x8dc8105fcc1b13a6ad1db83c35112a230e617e5a#code修复后的合约https://ftmscan.com/address/0xd2f585c41cca33dce5227c8df6adf604085690c2#code核心补丁代码如下:
补丁代码直接使用 msg.sender 作为 userProxyOwnerAddress 进行后续操作,从而避免了 userProxyOwnerAddress 与 msg.sender 不一致的情况。小结在此 Cobo 区块链安全团队提醒进行 DeFi 项目投资的机构与个人,在进行投资时要留意在新项目投资中可能存在的安全风险。建议:选择开源且在上线前经过知名安全厂商进行过代码审计的项目。选择非匿名、在业界有一定知名度的项目方团队。链上交易过程中,检查交互的合约与项目合约地址的一致性,防范前端钓鱼攻击。尽量避免使用 ERC20 无限授权。关注区块链安全事件,发现风险及时响应。Cobo 区块链安全团队将持续关注区块链、DeFi 安全的前沿攻防技术,保障客户资产安全,并为整个区块链行业安全水平的提高贡献自己的力量。