PolyNetwork攻击事件分析:黑客拿着房主证明找物业拿钥匙

CertiK中文

    
    “黑客拿着房主证明找物业拿钥匙,证明是假的,却从物业那里拿到了真的钥匙”
    事件回顾
    2021年8月10日,PolyNetwork遭受了跨链攻击,被转移了6亿美金的加密资产(之后攻击者开始陆续归还被盗资产)。攻击者在多条公链上进行了攻击交易,并通过跨链管理合约和中继器组件完成了攻击。
    用上面物业的例子来解释的话,黑客用假房主证明(源链上的invalid transaction),从物业(中继器)那里拿到了真的钥匙 (Alliance Chain上经过签名的Merkle证明)。
    攻击解析
    一、 黑客在源链上初始化了一个本应是无效的攻击交易。
    二、攻击交易在没有被充分检查的情况下被写入源链,之后被中继器纳入了Alliance Chain的Merkle tree并签字,然后发布到Alliance Chain区块中。
    三、 黑客在目标链上用步骤二的有效Merkle证明,调用Poly Network的ECCM合约,将keepers改成黑客控制的公钥。
    四、 获得keepers权限后,黑客就可以在多条公链上任意解锁资产了。
    这里值得注意的是,Poly Network在有些链上的中继器没有通过攻击交易,所以即使智能合约相似,某些目标链上资产并未受影响。
    
    细节分析
    一、黑客于北京时间2021年8月10日17:32:32在源链发起了一笔攻击交易。
    https://explorer.ont.io/tx/F771BA610625D5A37B67D30BF2F8829703540C86AD76542802567CAAFFFF280C#
    
    我们对交易进行了解码,得到了以下参数映射。
    
    二、此攻击交易调用了一个method "66313231333138303933",其对应的签名等于0x41973cd9(与之后调到的putCurEpochConPubKeyBytes函数签名相同)。这笔交易应该是无效交易, 可是却被写入源链并被中继器纳入了Alliance Chain的Merkle tree并签字,然后发布到Alliance Chain区块中。Merkle tree是用来证明交易是否真实存在的。其产生的跨链交易如下:
    https://explorer.poly.network/tx/1a72a0cf65e4c08bb8aab2c20da0085d7aee3dc69369651e2e08eb798497cc80
    三、跨链交易在目标链上调用了Poly Network合约的EthCrossChainManager.verifyHeaderAndExecuteTx(),第一个参数包含了Merkle证明,解析如下:
    
    四、这个函数解析了Merkle证明,发现证明是有效的,此攻击交易确实存在于已被签名的Merkle tree中。之后调用了EthCrossChainManager._executeCrossChainTx()函数去执行此交易,即调用toContract指向合约 (0xcf2afe102057ba5c16f899271045a0a37fcb10f2)中的method (0x6631313231333138303933),传入参数args (010000000000000014a87fb85a93ca072cd4e5f0d4f178bc831df8a00b)。而这个method指向putCurEpochConPubKeyBytes(bytes),因为其函数签名与步骤二中提到的method签名相同 (均为0x41973cd9,此处为哈希碰撞),所以被顺利执行,将keepers的公钥改成了黑客的公钥。以太坊上的交易如下:?
    https://etherscan.io/tx/0xb1f70464bd95b774c6ce60fc706eb5f9e35cb5f06e6cfe7c17dcda46ffd59581
    五、黑客改变公钥后,即可以随意解锁资产。
    事件总结
    此次攻击是由一连串交易构成的,其攻击根源分析如下:
    一、攻击交易在没有充分检查的情况下被写入源链。
    二、中继器会接收任意含有"makeFromOntProof"事件的交易。
    三、中继器将步骤一中的交易发布到了Alliance Chain上。
    四、在步骤二中,此攻击交易被纳入到Alliance Chain的Merkle tree上,产生了有效的Merkle证明。
    五、原链上的ECCM合约通过步骤二产生的Merkle证明,验证了该交易在源链上“确实存在”,原始数据并未被破坏、未被修改。不过需要强调的是,在构建将被发送到目标链的Merkle证明之前,应该对交易进行全面验证。正如设计文档中所示。
    “The management contract fetches the block headers from chain A, verifies whether or not the cross chain parameters and the proof are valid, and then transmits the necessary information to chain B in the form of an event;”
    "管理合约从A链获取区块头,验证跨链参数和证明是否有效,然后将必要的信息以事件的形式传送给B链;"
    因此,目标链(即B链)应使用Merkle证明来验证所收到的信息是未被破坏和未被改变的,而交易信息应在发送至目标链之前进行全面验证。
    附:Merkle tree(https://en.wikipedia.org/wiki/Merkle_tree)定义如下:哈希树可以用来验证计算机中和计算机之间存储、处理和传输的任何种类的数据。它们可以帮助确保从点对点网络中的其他对等体收到的数据块是未被破坏和未被改变的,甚至可以检查其他节点是否撒谎和发送假块。