Under 和 Over 兩種模式的勝率均為 [2%, 95%],獎勵倍數為【97 / 勝率百分數】。
PeckShield 安全人員在深入逆向分析 TronWow 合約時發現,TronWow 合約在檢查下注範圍時存在缺陷,允許使用者在非頁面下注時構造惡意輸入。換而言之,一旦使用者避開遊戲頁面,直接呼叫遊戲合約的下注函式,即可設法繞過合約中的下注範圍檢查條件,實現 100% 勝率以及最高回報倍數(97倍)。
下面以正常下注交易和惡意下注交易對該合約漏洞進行說明。
在 TronWow 合約程式碼中,函式 placeBet(uint24 _betMask,uint256 _commit,bytes32 _r,bytes32 _s) 為下注函式,引數 uint24 _betMask 為玩家的下注資訊。
其中正常下注交易呼叫 placeBet 函式時輸入如下:
這是一個選擇了 Under 模式且下注數字為 95 的正常交易,換而言之,當遊戲生成的隨機數小於等於 95 時玩家獲勝。
在此交易中,引數 _betMask 的值 24321 轉換成十六進位制為 0x005F01,我們將其分拆為三個位元組,分別如下:
其中:
1. 0x00 為十進位制 0;
2. 0x5F 為十進位制 95;
3. 0x01 為十進位制 1.
其中第一部分 0x00 表示若當該輪遊戲產生的隨機數計算結果處於 [0x01, 0x5f] 之間,則玩家獲勝;相反,前兩位不為 0x00 時表示若該輪遊戲產生的隨機數計算結果處於 [0x01, 0x5f]之外,則玩家獲勝。
在逆向過程中,我們將下注函式的部分彙編指令還原成虛擬碼,如下圖所示:
閱讀上述下注函式虛擬碼可以發現,合約只對玩家下注資訊中的勝率百分數進行了檢查,要求其小於等於 95,卻未對下注數字做數值限制。故玩家可透過構造下注數字來繞過該檢查。
下圖為攻擊者發起的諸多攻擊交易之一:
其中 _betMask 引數被構造為 130971,十六進位制為 0x01FF9B。其中前兩位 0x01 表示若該輪遊戲產生的隨機數計算結果處於 [0x9B, 0xFF]之外,則玩家獲勝。而 0x9B、0xFF 對應的十進位制分別為 155、255,則根據合約撰寫的勝率百分比計算規則,winRate = 100 - (0xFF - 0x9B) + 1,即等於 1,從而成功繞過下注範圍檢查函式,並將本次交易的獎勵倍數設定為 97。需要特別強調的是,在頁面下注中,獎勵倍數最高僅為 48.5 倍。
接著,我們將開獎函式 settleBet(uint256 _reveal, bytes32 _txHash) 的判斷遊戲輸贏部分彙編指令還原成虛擬碼:
其中 rollResult 為本輪遊戲的隨機數計算結果,取值範圍為 [1,100]。而在攻擊者設定的惡意引數中,rollResult 必然處於 [155,255] 區間之外,滿足贏得本輪遊戲的條件,從而確保了攻擊者遊戲結果穩贏。
總結:
對於 TronWow 合約被攻擊事件,PeckShield 安全人員分析發現:TronWow 合約在檢查下注範圍時存在缺陷,允許使用者在非頁面下注時構造惡意輸入,實現 100% 勝率。需要注意的是,該漏洞已在 TronWow 上線的新版本合約中被修復,遊戲方增添了對下注範圍的約束檢查。
在此,PeckShield 安全人員提醒廣大專案方及交易所應當重視區塊鏈世界中的任何安全問題,確保專案方及使用者的資產安全可靠。安全無小事,採取不公佈原始碼來抵禦駭客攻擊的行為,在駭客面前形同虛設。DApp 開發者應杜絕僥倖心理,在合約上線前做好必要的安全措施和已知攻擊特徵檢查,必要時可聯絡第三方安全公司進行漏洞排查,避免造成不必要的數字資產損失。