EOS競猜類遊戲遭黑客攻擊背後:Block.one官方悄然更新
12月05日,新上線的又一款EOS競猜類遊戲 Fastwin 遭到黑客攻擊,區塊鏈安全公司 PeckShield 態勢感知平臺捕捉到了該攻擊行為並率先進行了安全播報披露。資料顯示,當天凌晨03:18—04:15之間,黑客(ha4tsojigyge)向Fastwin遊戲合約(fastwindice3)發起124次攻擊,共計獲利1,929.17個 EOS。PeckShield 安全人員分析發現,該攻擊行為是黑客利用 Fastwin 的合約在校驗合約呼叫方時存在的漏洞,導致“內聯反射(inlineReflex)”攻擊成功。
據 PeckShield 此前釋出的《淺析DApp生態安全》的報告顯示,截止11月底,已經發生了超27起 EOS DApp 安全事件,主要集中在假 EOS 攻擊、隨機數問題等攻擊方式,且在不斷升級演變。而這次看似較小的攻擊事件背後卻暴露出了一個較以往危害性可能更大的新型漏洞:EOSIO 官方系統對呼叫合約自身函式存在不校驗許可權的問題。
(圖一:PeckShield 與 Block.one 郵件溝通)
PeckShield 認為這是一個非常嚴重的漏洞,並第一時間通知了 Block.one 團隊(CVE-2018-20163)。Block.one 官方團隊接受了該漏洞提議,並告知我們有其他研究團隊也事先獨立彙報了該漏洞,最終於週四(12月13日)更新了緊急補丁以補救防禦,同時次日新發布1.5.1和1.4.5兩個版本,完成了該漏洞修復,避免了更多攻擊事件的發生及可能造成的資產損失。
“內聯反射(inlineReflex)”攻擊原理
正常的轉賬流程如圖所示:玩家通過呼叫系統合約(eosio.token),將 EOS 轉賬給遊戲合約,觸發遊戲合約的分發邏輯(apply),進而呼叫相關函式實現開獎。
(圖二:競猜遊戲正常轉賬流程)
而此次的攻擊者(ha4tsojigyge),在自己帳號部署的合約中包含了與遊戲合約相同的操作函式,在轉賬完成後,自行開獎獲得獎金。如圖所示:
(圖三:攻擊者內聯呼叫自身合約開獎)
從圖中可以看出,攻擊者在自身合約的函式(pushck)中,內聯呼叫了與遊戲合約開獎同名的函式(check),再通過通知(require_recipient)的方式將資訊傳送到了遊戲合約。此時遊戲合約的分發邏輯(apply)沒有過濾掉此資訊,並呼叫了開獎函式(check)。
總之,攻擊者利用了 EOSIO 系統中對呼叫合約自身函式不校驗許可權的漏洞,進而使用遊戲合約(fastwindice3)的帳號許可權發起內聯呼叫,致使繞過遊戲合約在敏感函式中校驗呼叫者許可權的方法(require_auth),從而獲取了遊戲合約發放的獎勵。
修復方法
從上述分析能夠發現,攻擊者合約的通知資訊中,實際呼叫的合約是攻擊者合約(ha4tsojigyge),而非遊戲合約(fastwindice3),因此在遊戲合約的分發邏輯(apply)中過濾掉此類資訊即可。而且從系統定義的巨集(EOSIO_ABI或者EOSIO_DISPATCH,如圖四)中能夠看到,分發邏輯處理了此問題。因此 PeckShield 在此提醒開發者在定製化自己的分發邏輯時,需要特別注意其中的呼叫來源。
(圖四:系統EOSIO_DISPATCH程式碼)
需要強調的是:這個問題屬於 EOS 公鏈層的較大漏洞,攻擊者在內聯呼叫中可以偽造任意帳號的許可權執行,但這個修復可能會給部分開發者造成相容性問題,如合約內聯呼叫函式,而執行者帳號(actor)不是自己的時候,會導致整個交易(transaction)執行失敗,如需解決相容性問題請給合約賦予執行者帳號的 eosio.code 許可權。