深扒EOSDice被攻擊事件始末, TA是如何把遊戲體驗搞臭的?

安全是區塊鏈領域舉足輕重的話題。本期咱們聊聊 EOS 僞隨機數漏洞引起的安全隱患。 「區塊鏈大本營」攜手「成都鏈安科技」團隊重磅推出「合約安全漏洞解析連載」,以講故事的方式,帶你回顧區塊鏈安全走過的歷程;分析漏洞背後的玄機。讓開發者在趣味中學習,寫出更加牢固的合約,且防患於未然。 當然,這些文章並不是專爲開發者而作的,即使你不是開發者,當你讀完本連載,相信再有安全問題爆出時,你會有全新的理解。

道高一尺,魔高一丈,愈進愈阻,永無止息。——清·譚嗣同《仁學》四三

上回書說到

官方標準用心良苦

編寫合規不容小覷

我們用十五期內容結束了對以太坊智能合約常規漏洞、高危漏洞的分析和總結。縱觀整個以太坊安全生態發展歷史,有太多的教訓和痛楚值得我們銘記。

有相關統計,區塊鏈產業導致財產損失的安全事件中有30%是由智能合約漏洞引起的。所以按照以太坊開發語言的使用規範,正確書寫每一行合約代碼,是保障合約安全的基本要求。倡導上鍊前的合約審計,確保項目安全啓航,是我們對開發者和項目方真誠的建議。

本期話題

EOS遊戲屢遭毒手,隨機數漏洞屢禁不絕

除了以太坊,EOS也是目前比較流行的區塊鏈平臺。

EOS同樣是基於智能合約和區塊鏈搭建而成,而在遊戲和DApp領域,由於沒有交易費和處理能力強等特性,EOS在技術和設計理念上佔有先天的優勢。但是,無獨有偶,EOS智能合約的安全問題也層出不窮。

本期我們借用最近發生的EOS遊戲被攻擊事件展開對EOS智能合約漏洞的分析。

攻擊事件歷史

EOSDice 第一次被攻擊

2018年11月4日 上午3:15開始 EOSDice合約被賬戶jk2uslllkjfd攻擊,攻擊者盜取了2500左右EOS並充值入火幣。

EOSDice第二次被攻擊

11月10日上午11:19開始,coinbasewa11賬戶再次攻擊了EOSDice遊戲,盜取4900 EOS轉入bitfinex交易所,這個賬戶對遊戲合約進行了95次攻擊,攻擊過程可以檢索到。

隨機數生成問題

我們在第六期遊戲合約漏洞提到過,截止至目前,以太坊和EOS官方均未提供隨機數接口,這對遊戲開發確實是一個不利的影響,比如抽獎模塊的開發。爲了實現類似的功能,遊戲開發者需要自己編寫隨機數生成函數,這些函數往往利用區塊信息作爲參數,然後進行一系列運算,獲得一個“隨機數”。

但是,由於使用區塊信息作爲參數,這將導致在同一個區塊上,使用相同算法的隨機數函數將會得到相同的值攻擊者可以利用這點,部署中間合約,然後不停的嘗試生成隨機數,當生成滿意的隨機數時,再利用中間合約參與遊戲,影響遊戲的公平性。我們把這類隨機數問題統稱爲“僞隨機數漏洞”

EOSDice僞隨機數漏洞分析

由於EOSDice在第一次被攻擊後提高了警惕,並且修改了隨機數生成的算法,所以我們分兩次進行分析。

第一次攻擊分析

由於EOSDice合約開源,我們主要看一下該合約的random函數,該合約抄襲了另一個EOS合約的random函數實現。

該隨機函數中使用的隨機因子主要爲:

  • tapos_block_prefix() 該交易refer區塊信息
  • tapos_block_num() 該交易refer區塊信息
  • name (user賬戶名)
  • game_id (自增)
  • current_time()(當前時間)
  • pool_ol_eos.amount (合約當前的餘額)

其隨機性主要依賴於refer區塊 (refer block) 信息及當前時間、合約餘額信息。

在該遊戲中,開獎時間是可以根據delay時間推算得到,餘額信息在只有一個用戶訪問時也可以根據計算得到。

那麼唯一不確定的因子只剩下refer block的信息了。

在實際遊戲執行邏輯中開獎的reveal action是由下注的action衍生出來的deferred action,該action的refer block信息並不是由用戶指定的,而是由eos鏈來指定的,代碼詳見:

https://github.com/EOSIO/eos/blob/master/libraries/chain/apply_context.cpp#L251

經過實際測試,deferred action的refer block信息爲執行當前action的前一個區塊信息,示意如下圖:

所以,其實開獎時的使用的tapos_block_prefix()其實在下注前就已經產生,那麼再結合對時間和餘額的預測,就可以提前預測開獎結果;根據交易情況分析,eosdice第一次被攻擊很可能就是使用的此種攻擊方式。

第二次攻擊分析

這裏要先介紹一個EOS的小知識:

當EOS轉賬時,EOSIO.Token會同時通知到from和to賬戶,但會先執行對from賬戶的通知,如下圖所示:

EOS在第一次攻擊事件發生後,修改了隨機數生成算法,我們來看一下修改後的隨機數是否真的隨機。隨機數計算公式如圖所示:

利用上面提到的轉賬通知知識,遊戲合約收到向自己的轉賬通知時開始執行下注邏輯,觸發deferred action:reveal1,reveal1觸發deferred action:reveal進行開獎發獎;那麼在開獎(reveal)時取的refer block信息是下注轉賬action所在的區塊信息,不可以預測。

但是在EOSDice對隨機函數random進行了修改後,這個函數還使用到了賬戶餘額這個隨機因子。攻擊者可以在轉賬後自己也接收EOS轉賬通知,並且自己模擬出跟EOSDice相同的defered action:defered2,然後defered2觸發defered action:defered。

經此一番操作,此時攻擊者的defered 和遊戲合約的reveal是處在同一個區塊(block)中運行。那麼就可以在defered中通過修改隨機因子中的餘額amount計算random(amount+x)的值,使其滿足自己的下注條件。需要注意的是,計算這個值需要進行碰撞試驗才能猜準。

攻擊者隨後向隨機因子賬戶中轉入amount爲x的eos;那麼當運行到reveal開獎的時候,就可以使自己必定中獎。整個攻擊流程可以總結爲下面這個圖:

加上之前經過對攻擊交易分析,可以確定此次攻擊者利用的攻擊方式是控制隨機因子中的餘額

漏洞修復

使用與tapos_block_num類似的參數都可能會引發僞隨機數漏洞,包括EOS餘額和head_block_id,這些參數的特點就是具有一定可控性。

如果非要使用tapos_block_preifx作爲隨機數因子,可以在開獎reveal執行之前多執行一次defered action跳轉,保證開獎時獲取到的block信息在下注之後生成,這樣tapos_block_prefix纔是不可預測的。

僞隨機,真漏洞

EOS與以太坊採用了不同的技術和設計理念,比如:

  • 以太坊被設計爲對於所有可能建立在其基礎上的應用中立的平臺,而EOS則提供了一些功能例如加密的實現和區塊鏈工具的應用,對應用開發者比較友好。
  • 兩者的共識機制不同,相較於以太坊採用的PoW,EOS的DPoS機制類似於董事會機制。
  • 以太坊受到CPU單線程性能限制,其網絡交易速度大約只有10次/秒,而且每次交易還需要提供手續費。EOS的並行技術解決了交易速度的問題,並且移除了手續費。

EOS的特性,尤其是第三點特性決定了在其基礎上的遊戲能夠滿足延遲低,交互流暢的需求,同時能夠處理商業級的應用需求。這也是EOS在遊戲方面應用較多的原因。但是與以太坊一樣,EOS官方並沒有提供相應的隨機數生成功能。以太坊官方已經推薦用戶使用鏈外的Oraclize庫生成隨機數。

EOS的隨機數問題依然是一個令開發者頭疼的問題,11月還未結束,EOS DApp已經出現了三次針對隨機數的漏洞攻擊事件,說明在隨機數問題的解決上,亟需一個可靠的解決方案。

希望廣大DApp開發者在目前沒有可靠方案的時候,依靠現有的經驗和安全審計,做到將合約內的“僞”隨機修復爲“真”隨機,讓EOS DApp有趣、公平、可靠。

參考文章

[1] EOS與以太坊有哪些區別

https://blog.csdn.net/qq_42204339/article/details/80463686

[2] 玩EOS上擲骰子的遊戲

https://www.jianshu.com/p/b72c71cd3614

[3] 遊戲skr而止,漏洞周而復始 —— 遊戲合約漏洞全面彙總

https://mp.weixin.qq.com/s/0h68eI7fawy1Gi0TZYzH3A

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章