“黑客拿著房主證明找物業拿鑰匙,證明是假的,卻從物業那里拿到了真的鑰匙”
事件回顧
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)定義如下:哈希樹可以用來驗證計算機中和計算機之間存儲、處理和傳輸的任何種類的數據。它們可以幫助確保從點對點網路中的其他對等體收到的數據塊是未被破壞和未被改變的,甚至可以檢查其他節點是否撒謊和發送假塊,