0x1 事件背景
零时科技区块链安全情报平台监控消息,北京时间2022年8月2日,跨链解决方案 Nomad 遭到黑客攻击。WETH、WBTC、USDC 以每次百万美元的频次转出,合约中仍有 1.26 亿美元可能存在风险。零时科技安全团队及时对此安全事件进行分析。
0x2 攻击信息
-
部分攻击交易
0x96a2cfadb19cac9ba2a21c1f32b6f21b6132afe1b4f4698dee563ca01ec20e01 转移 USDC
0x811a54270e38154c30e65bdb8ee484883f5a9659dd16f1a335f9ff8f7eee342f 转移 WETH
0x12efbc03ecc8d56ebbadd637dbfc30c0d709b463e2c831034233427dfaecf777 转移 FRAX
0xc78bc10c77ca92693513e5b97b4a0063167ca8488b019f6b740bc9f8cad103bf 转移 CQT
0x8c65b2b25be2c929d86f1fb556aa0b981bd54c2ad54d8de63d3876c4c833293e 转移 DAI
0x5304e01a4cb926523f681bc34a8b71a1dfae35b5a5159f78aecc7f685f42422c 转移 CARDS
-
被攻击合约
0xB92336759618F55bd0F8313bd843604592E27bd8 Replica
0x3 攻击分析
从上述攻击交易进行分析,攻击者在该笔交易中进行10次相同流程从Nomad:ERC20 Bridge中转移资金操作。
每次调用流程中均会调用Replica.process()方法,并且传入的参数基本一致,唯一不同的是当时生成合约地址。
跟进Replica.process()方法
这里process方法注释中,明确了该方法会检查传入消息是否包含可接受的默克尔根,如果消息没有被证明,就会回退。这里主要的判断在185行。
这里传入的参数,赫然是0x000...000,跟进判断方法acceptableRoot()
上图的判断中,前两个if判断条件均不会成立,传入_root为零,而Replica合约中LEGACY_STATUS_PROVEN和LEGACY_STATUS_PROCESSED均已设置不为零。
下面的判断条件中,当_time为零,结果会是 false,也就是acceptableRoot方法返回值为true只有一种可能性,confirmAt[0x000...000]不等于零,该值初始化时会赋值为1,难道初始化传入的是0x000...000,并且从结果来看执行成功。
这是什么情况,继续跟进Replica合约的初始化传参。
41天前,该平台人员将合约部署后,执行了初始化操作,并且这里初始化内容均为0。到这里就非常清楚了,由于初始化将 0x000..000 merkle根赋予了可以接受的根,所以在默认的情况下每一条消息都会通过证明,从而转移Nomad桥资金。
0x4 攻击核心
Replica.initialize
由于Replica合约初始化时,_committedRoot传入了零值,导致之后合约中的confirmAt[0x000...000]均为true。在process方法中可直接通过判断条件,导致每条消息在默认情况下都被证明有效,任何人都可以发送构造消息转移资金。
0x5 总结及建议
截止目前Nomad中已转移资金超过1.8亿美元,通过此次攻击来看,合约部署者在初始化合约时未对传入参数进行针对性赋值,而是传入全零的值,导致合约中部分判断条件恒为true,任何人都可通过发送构造消息转移资金,目前 Nomad 官方正在调查,暂未提供退还跨链桥资金的说明。
安全建议
-
建议合约初始化时对传入参数进行针对性赋值,避免出现默认零传参导致合约风险
-
建议合约开发人员对审计报告中风险提示严格验证,避免疏忽风险内容引起合约风险