攻击简述
黑客(地址:0x489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec)利用跨链桥消息验证机制基础库代码IVAL TREE中的漏洞,伪造提现恶意消息,最终导致跨链桥向黑客发送两笔BNB,每次都是100万个BNB,价值约$600M美金。由于币安及时的响应,只有价值约$100M 美金的资产被转移了出去。很显然即使这样,也是很严重的损失。相关tx地址:
https://bscscan.com/tx/0xebf83628ba893d35b496121fb8201666b8e09f3cbadf0e269162baa72efe3b8b
图1相关tx地址
漏洞利用原理分析
这次攻击发生在BSC链上,BinanceBridge是给BSC来提供流动性,通过分析我们可以发现这次攻击是由于BSC L1链上的一个IAVL tree(https://github.com/cosmos/iavl)的库实现有漏洞,这个库代码原本是COMOS实现的,BSC chain直接使用了这个库。
IVAL tree是用来校验,验证发送给币安跨链桥消息的合法性的。
一般情况下,IAVL 树会拒绝黑客伪造的消息,然而,攻击者在 IAVL 验证过程中发现了了漏洞,这使他能够欺骗 IAVL 树接受任意消息。黑客通过精心构造消息,从而跨链桥中提取了2M个BNB。
关于IAVL tree,顾名思义,是一个 avl tree(named after inventors Adelson-Velsky and Landis)的实现,是自平衡的二叉搜索树。这种数据结构的目的是为键值对(比如存储账户余额)提供持久存储,以便可以计算确定性的默克尔根哈希。
黑客在跨链桥合约里调用了handlePackage函数,再调用预编译的合约用来验证MerkleProof的合法性。
图2预编译的校验合约
何为预编译?
预编译在这里类似操作系统的syscall的作用,当操作系统识别到syscall的num(num类似这里的0x65)的时候,就会执行相应的系统调用,正常情况下合约地址是在合约部署的时候生成的,而这里直接写死了0x65,当BSC L1发现这个地址的时候,就会直接去调用MerkleProof的过程,也就是去调用IVALTree的代码。
一句话概括本次攻击过程
黑客通过部署合约,调用BSC 跨链桥合约的handlePackage函数
(https://bscscan.com/address/0x0000000000000000000000000000000000002000#code#L1082)伪造proof数据,使得IVAL tree校验成功,最终使得跨链桥向黑客转移了2M BNB。
图3 handlePackage函数
最后
Samczsun已经对具体的漏洞细节进行了一些推测,但是目前尚不能完全确认所有细节正确,Numen 安全实验室正在分析调查,至于更多攻击细节,我们会陆续公布。