
9 月5 日,由Odaily主辦、36Kr 集團戰略協辦的POD 大會在北京舉行。在大會的安全論壇上,安比(SECBIT)實驗室創始人郭宇與眾嘉賓共同探討區塊鏈的安全問題。郭宇就近期的安全熱點話題Last winner 展開報告,詳細解釋其中內幕。
二級標題
二級標題
以下為安比(SECBIT)實驗室創始人郭宇演講實錄:
我是安比實驗室的郭宇,今天分享一下一些比較有意思的事情。
8 月10 日,一個合作夥伴突然跟我說以太坊似乎有一些很奇怪的事情,問我們能否分析一下。我們接過來後也覺得事情奇怪。這其中有連續且大量的失敗交易,標紅色的點中發現帶的全都是0.1 ETH,這些大量重複的東西好像在攻擊什麼。而且這些所有交易來源方均來自於一個前四個字母是0x5483 的詭異智能合約。該智能合約的交易量還很大,一分鐘有幾十個,這很容易造成以太坊嚴重擁堵,這是我們發現一個初步特徵。覺得奇怪,又感到很可疑,我們也想知道它到底要幹什麼。
之後我們發現除了大量的失敗交易外,還存在更大量的成功交易。成功交易沒什麼顯著特徵,投進去0.1 個,出來有0.19 個,這就特別奇怪。同時,失敗交易的一個特別特徵是Gas 消耗特別低,感覺是一個非常高效的挖礦機,回報率相當高。
之後我們就發現,0X5483 實際上是一個攻擊Last winner 的攻擊合約,精心構造且非常強大,攻擊步驟也特別複雜。合約中存在大量轉賬,比如PPT 中的這個合約,扔進去的0.1 ETH,最後出來是0.18 ETH 或者0.12 ETH 等。
Last winner 是什麼?它是Fomo3D 山寨版,主要面向國內。在百度能看到大量廣告信息,還有很多微信群、QQ 群。此外,Last winner 還有安卓以及iOS 客戶端可以下載。當時高峰時期有16000,參與的人非常瘋狂。
Fomo3D 是什麼?這是前一段時間一個現象級的智能合約遊戲,瞬間對以太坊用戶造成擁堵。遊戲中有一個巨大的獎勵誘惑,規則是這樣的。首先是需要兌換key,在拿到key 之後扔給類Fomo3D 遊戲合約。這其中包括三種獲利方式,第一種方式存在主獎池,可以有機會拿到最終大獎,即這個遊戲不停倒計時,最後一個買key 的人拿到最後的巨額獎勵;第二種方式有一個副獎池,方式為隨機概率抽獎,即兌換key 時就有機會抽獎;第三種方式為小額度獎勵,買key 時間越早,就可以越早享受後來人進來的分紅。基於這三種誘人的獲獎模式,Fomo3D 推出之後就一度造成以太坊擁堵。
7 月24 日,安比實驗室就已發現剛才第二項空投存在漏洞,有人可以通過不公平方式拿到抽獎結果,我們在8 月10 日才收到警告。
之前被曝光的空投抽獎的模式,是有人公開了一個可以攻擊的方案,但攻擊方式非常低效,甚至不一定成功。大家知道但沒有人去試,好像賺不到什麼錢。但是這個攻擊合約不一樣,經過統計該合約成功率將近60%。
第二天,我們開始對該合約進行分析後發現有三個疑點。一是有五個地址來調用攻擊合約;二是Last winner 合約地址作為參數傳入攻擊合約;三是每筆成功中獎的攻擊交易中都帶有合約的創建與自毀。當時也不知道為什麼,但是可以肯定這是一個團夥,對其數據分析後發現,這個團夥做了很多別的事情,他們共同去攻擊不同的遊戲合約。我們把該攻擊者組織命名為“BAPT-LW20”。
12 日,團隊開始嘗試逆向分析該合約代碼。由於手上工具有限,只能看自解碼,摳了一天還是沒什麼進展,分析過程陷入僵局。第二天,小伙伴建議把這個攻擊合約拷貝下來,將攻擊合約中的攻擊者地址替換成我們的地址,是不是可以像他一樣去拿到獎勵?我們重新部署攻擊合約,並發起試探性攻擊。但經過多次嘗試後,均無法贏得抽獎。我們做了非常完備的替換,並且跟踪這個過程,就不知道為什麼,就是成功不了,也是挺鬱悶。
晚上12 點,最後方案決定對合約進行死磕,開始對合約進行逆向分析。合約逆向很累,我們怎麼辦?我們思路就是開發逆向分析輔助工具。手頭上並沒有什麼東西,我們要做幾件事情。首先,針對EVM 逆向分析工具很少,我們決定自己開發;再者合約多層嵌套很難跟踪;同時EVM 字節碼中的循環過程不易定位。
我們花了三天時間開發工具,事情開始出現轉機。第一個工具為awesome-tx-tracer(合約行為跟踪),借助這個能夠把智能合約整個過程產生若干個tracer,並把很多交易行為全部tracer 分析,進而產生大量數據;第二個我們做了用來做逆向的工具——minievm(合約執行模擬器),借助該工具能夠批量定性分析很多tracer;第三個工具為ida-evm(合約流圖分析器),這是基於evm 的插件修改而來。產生的tracer 可以自動往前往後,來回執行,這樣就能夠比較容易的把整個過程反复看。
最終,我們終於發現真相,攻擊合約是一個母合約,母合約驅動1000 個子合約,這樣能大大提高隨機數的中獎率。同時,每個子合約攻擊的時候會創建一個幽靈合約來發起攻擊。什麼是幽靈合約?就是在攻擊的時候創建,等攻擊完立即自毀,在區塊鏈存儲區域不留下任何痕跡。黑客通過某一個母合約驅動1000 個子合約,又創建無數的自毀合約,自毀合約最終去攻擊Last winner,這是一個非常巧妙的玩意。
在17 日早上開始復盤,我們敲定的最終結果是6 天內抽走抽獎池50%,發起近5 萬筆攻擊調用,創建2 萬多個幽靈合約。 Last winner 很有意思是把空投獎池比例由Fomo3D 的1% 提高到10%。因此,黑客在攻擊Last winner 成功以後,但是對Fomo3D 並不那麼了解。這個母合約在Last winner 上線第一天幾個小時之內就發動了攻擊,在前幾天每小時幾十萬的收入。
巧合的是,上午10 點Last winner 大獎開出,即剛才說的三種獲利模式中的第一個大獎。大獎被這五個攻擊者其中一個人拿走,攻擊者地址為0X5167,獎勵額度也超高,比他們空投抽到的還要大。
事情還沒有結束。五天以後,下午3 點02 分,我們又有了一個驚人發現,Fomo3D 第一輪結束,大獎被拿走。是被一個人拿走的嗎?不是,他們用了同樣手法拿走大獎。為什麼?當時我們看到Fomo3D 大獎的時候,就發現熟悉的一幕。在大獎開出時,出現一組連續的異常區塊,且這組連續的異常區塊中的消息數量驟減。最後,同一個知名miner 打包獲獎交易。 Last winner 結束前後,也出現過類似的異常區塊,獲獎消息也是由同一個miner 打包,這時候我們就發現這太巧了。我們開始懷疑,礦池是不是真的對Fomo3D 作弊?第一時間跟礦池負責人聯繫後,並把我們知道的所有信息拿出來跟對方對比發現,礦池並沒有參與這次作弊,而是這個異常區塊隱藏著一個巨大的秘密。這個秘密就是異常區塊中的消息均調用同一個合約,這裡面存放一些非常詭異的交易,所有交易的Gas 相當於正常的Gas 的100 倍;而這個合約的創建者與中獎者是同一個人。
礦工並沒有作弊,而是攻擊者利用礦工打包策略,即礦工會優先選擇手續費很高的交易打包,這對礦工最有利。通過製造超高手續費來造成區塊鏈的擁堵,阻隔其他玩家。攻擊者也非常聰明,攻擊合約能夠智能判斷是否啟動網絡阻塞功能,使其效益最大化,成本最小化。
總之,這個合約構造的非常巧妙。若攻擊者沒有拿走大獎,它依然會存在於很多礦池的應用池,等待時機成熟,這些交易就會順勢變成交易費用非常高的交易。
所以說,這個遊戲漏洞使得前面主獎池和副獎池可以很輕鬆被攻擊。還有一個問題,大家還記得Last winner 攻擊母合約,為什麼需要Last winner 作為合約地址?事實上,這個攻擊母合約是一個通用母合約,能夠攻擊很多類Fomo3D 遊戲。在Fomo3D 上線第二天就有人發現空投抽獎漏洞,並攻擊成功。
你面對的是全世界非常頂尖的黑客,你隨時有可能受到損失。因此,智能合約安全嚴重性遠超大家的想像,大家想像的未來去中心化世界真的那麼美好嗎?在享受去中心化世界帶來好處的時候也同樣會付出一些代價和麵臨一些新的安全風險。謝謝大家。