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 官方正在調查,暫未提供退還跨鏈橋資金的說明。
安全建議
建議合約初始化時對傳入參數進行針對性賦值,避免出現默認零傳參導致合約風險
建議合約開發人員對審計報告中風險提示嚴格驗證,避免疏忽風險內容引起合約風險