高手過招:這波騙子的目標是區塊鏈專業技術人員!區塊鏈
實際應用中,廣大用戶或開發者不能完全依賴于某一款區塊鏈瀏覽器所提供的數據。
近日,一種新型蜜罐合約正在泛濫。這類合約利用區塊鏈瀏覽器 Etherscan 顯示特性,蓄意隱藏特定合約調用記錄,布局欺騙游戲參與者。且該類蜜罐合約的設計者具有較強的技術積累并能很好把握玩家心理,針對目標多為具備一定區塊鏈專業素養的人員。當前市場上的同類合約數已達48個,其中近一半合約已有玩家受騙。
出于好奇,我參與了一款猜答案游戲
Martin Derka是加拿大滑鐵盧大學的一名博士,擁有10余年計算機軟件相關的科研與工作經歷,今年6月份,他加入了知名安全團隊Quantstamp,現擔任QSP高級軟件研發工程師一職。
7月的一個周末,Martin Derka在家中閑來無事,便開始瀏覽區塊鏈瀏覽器(Etherscan)上新增的ICO項目及游戲項目,其中一份名為QUESTION的合約勾起了他的興趣,合約地址為0xcEA86636608BaCB632DfD1606A0dC1728b625387
這份合約寫的是一個游戲,大致規則是:
合約創建者會設置一個問題;
任何玩家都可以通過向合約打入不低于1ETH的手續費參與作答;
若猜中答案,將得到合約里所有的ETH作為獎勵;
若猜不中,無任何獎勵,且事先支付的ETH會轉入該合約。
Martin Derka看到合約時,里面有1.03個ETH。
Martin Derka初次見到的QUESTION合約狀態
一個以太幣的金額不少,只需要回答一個問題就能到手?Martin Derka隱約覺得這個游戲有貓膩,于是他開始查看合約的構造邏輯。
一番瀏覽后,他發現合約的設計似乎存在很多不得當之處。例如,Solidity編譯器版本老舊,標注不規范,合約方案設計既費力又浪費以太坊GAS,不過他把這些都視作以太坊“初學者的失誤”。
“我的第一印象是,這份合約肯定是剛接觸Solidity 和以太坊的初期開發者撰寫的”Martin Derka事后回憶時表示。
他進一步分析代碼,發現了更多疑點:
合約存在一些怪異、低效的構造;
合約想要隱藏一些私有的數據;
存在一些低級錯誤:玩家能通過在以太坊瀏覽器上查看交易記錄準確破解出答案。
至此,Martin Derka基本確定這份合同是個騙局,合約中的以太坊余額大概是個誘餌,很大可能會讓玩家損失其加入游戲時支付的ETH,因為他覺得這個合約的設計實在有太多無法解釋的地方。
帶著種種猜測與疑惑,Martin Derka加入了游戲,試圖摸清騙局真相。
我十分謹慎,但我被騙了1.05個ETH
Martin Derka十分謹慎地留意合約創建者所進行的每一個動作:
首先合約創建者在5873826區塊高度上通過一筆交易創建了一個智能合約;
其次,合約創建者啟動游戲,將問題“Imagine you are swimming in the sea and a bunch of hungry sharks surround you. How do you get out alive?”和答案“Stop Imagining”以及1.03個ETH寫入了高度為5873943的區塊,1.03個ETH順利打入其創建的智能合約;
除此之外Etherscan上未見到任何其他交易記錄。
啟動游戲的交易記錄:包括問題和答案(答案是明文顯示的)
Martin Derka首先對正確答案進行了判斷。
QUESTION游戲中與設置問題和答案相關的接口只有兩個(一個是啟動游戲,一個是更新問題)。啟動游戲接口只在最開始時調用才有效,一旦啟動了下次再調就無效;更新問題接口要在游戲啟動后才能調。游戲啟動以后,若調用了更新問題接口,則最后一次更新設置的問題和答案才是游戲當前真正的問題和答案,若沒有調用更新問題,則第一次啟動游戲的時候設置的問題和答案就是正確的問題和答案。
從etherscan上的交易記錄來看,該合約只調用了一次啟動游戲,所以Martin Derka判斷這條交易記錄中記錄的就是正確答案,而由于合約設計者的“失誤”,答案是以明文傳輸的,交易記錄中直接就能獲取到。
Martin Derka隨后轉了一些ETH到自己的Metamask錢包賬戶里。
不過謹慎的Martin Derka第一次回答這個問題時沒打ETH進合約,因為他想創建個交易驗證一下,創建者提交的正確答案是不是能夠被準確破解;如果是,SHA256應該產生相同結果;他調用合約方法并進行一番驗證后,覺得沒什么問題。
第二次,他將1.05個ETH連同正確答案一同提交參與作答,然后等待答題結果。
當他的交易被挖掘出來時,預料中的騙局出現了:游戲合約的余額增加到超過2.08個ETH,而Martin Derka錢包里的1.05個ETH不見了。
按照游戲規則,Martin Derka提交了正確答案、且事先支付了1.05個ETH,他理應贏得合約里所有以太坊余額的,但他卻賠了。以太坊瀏覽器上也真實記錄了他的1.05個ETH轉入游戲合約的記錄。
圖中Etherscan記錄的最近2筆交易正是Martin Derka創建的
一時間,Martin Derka 有點不相信自己的眼睛。他一直在檢查代碼和交易,絲毫沒有放松過,但騙子就在他眼皮底下騙走了他的以太幣。他開始重新梳理這個過程,交易的排序是正確的,代碼也看不出任何蹊蹺,他在本地部署了代碼,并進行測試驗證,一切都好像沒什么問題。
而就在這時,游戲合約的余額突然降到了0,問題創建者終止了游戲,此時距離Martin Derka 答題結束大約1個小時。
我看到的一切,都只是對方想讓我看到的
恰恰是合約創建者急忙提走2.08個ETH的這筆交易揭開了謎底。
Martin Derka注意到,合約余額(2.08ETH)并未被轉移到某個錢包,而是被轉入了另一個專用源碼合約。并且他在交易歷史中,發現有一筆指向游戲合約的內部交易并未被以太坊瀏覽器記錄。
經過一番查證分析,他發現之前他所看到的并非全貌,其實游戲合約創建者實際的行動順序是:
(1)合約創建者先創建了一份中間合約,合約地址為:
0x4B2838d9326bD5126F0573D9b5c71C0626Ab28f2
(2)合約創建者創建當前的游戲合約,合約地址為:
0xcEA86636608BaCB632DfD1606A0dC1728b625387
(3)合約創建者向中間合約發起一筆交易。這筆交易使得中間合約向游戲合約發起兩次調用,這兩次調用在 Etherscan 的交易歷史中都不會顯示,但可以在交易的Trace中查看到,兩次調用及其參數皆可通過合約的 ABI 解碼得出,從解碼結果來看:
第一次是調用了 啟動游戲接口,傳入了問題和答案兩個參數,其中問題為“Imagine you are swimming in the sea and a bunch of hungry sharks surround you. How do you get out alive? ”答案為“sZs”(明文顯示的)。
第二次是調用了更新問題接口,更新了問題和答案,傳入的問題與上一次調用時是一致的,而答案則是一串哈希值。
第一次調用詳情
第二次調用詳情
也就是說,在啟動游戲并設置好問題和答案之后,合約創建者又迅速更改了一次問題和答案,而第二次調用時設置的答案才是問題的真正答案,但這筆交易記錄被隱藏了。
(4)合約創建者又向游戲合約發起了一筆交易,調用啟動游戲接口,傳入問題“Imagine you are swimming in the sea and a bunch of hungry sharks surround you. How do you get out alive?”和答案“Stop Imagining”,而由于啟動游戲只有第一次調用有效,本次調用實際上不會改變合約的任何狀態,答案自然也不是正確答案。但設計者故意讓玩家看到這筆交易記錄。
因此Martin Derka將“Stop Imagining” 作為正確答案輸入,結果必定錯誤。
“調查之后,我才發現這是一段精心編寫的代碼,他們只是在假裝天真。”Martin Derka在事后的回憶文章中這樣評價QUESTION合約,并表示“十分欽佩這份合約的設計”。
我們再簡要回顧一下這個高明的騙局。
合約設計者拋出游戲規則并在合約中打入一定的ETH,吸引玩家繳費進場答題賺ETH;同時設局讓玩家自認為能通過交易歷史破解答案,然后不聲不響地賺取ETH。而實際上是螳螂捕蟬、黃雀在后,合約創建者讓你邊竊喜邊發現的答案并非真實答案,技術帝們憑借“機智”最終不僅賺不到合約中的ETH,還會賠光預先繳納的手續費。
安全專家:已“繳獲”48個同類蜜罐合約
上述玩法是典型的蜜罐合約,陷阱設計精巧嫻熟,往往讓人防不勝防,這不連QSP團隊的安全大神Martin Derka也沒能幸免。
“設計該類蜜罐合約需要一定的技術積累和對玩家心理的把握,而受騙者大部分都是具備一定專業知識的技術人員,且這些人員往往也更容易參與到DAPP游戲中”安比實驗創始人郭宇向小蔥表示。
“這類蜜罐合約就是這樣,讓玩家以為發現了游戲的漏洞,而實際上只是游戲設計者的圈套,我們調查統計了當前市場上的同類合約,發現這一詐騙手段屢試不爽”,他補充道。
據安比實驗室智能合約風險監控平臺顯示,同類合約的數量已高達48個,最近的部署為3天前。其中,已有玩家受騙的合約逾21份,累計受騙金額超過 25 ETH。
以下是部分成功套取ETH的蜜罐合約地址:
小蔥APP特此提醒各位DApp 游戲愛好者提高警惕,切勿參與到上述合約地址的游戲中,也不要參與各種安全性不明的游戲合約。
“該類蜜罐合約通常都在有玩家受騙后短時間內迅速結束套利,受騙群體較小,金額較少,不會造成大范圍的影響,故而也比較容易被忽視”安比實驗室安全專家p0n1告訴小蔥。
不過,他提醒說“3天前還有一份剛部署的合約,目前尚無玩家受騙,可見這種詐騙手段還在繼續。”合約地址是:0x3fAb284a3cD0A6d88d18D0fdA4bc1a76cdacd68A。
此外,p0n1指出,由于合約中終止游戲接口的實際功能是使問題提出者取走合約中所有 ETH,并不是真正終止合約。簡言之,即使問題提出者成功套取利益,游戲也并未真正結束,玩家還是有繼續掉入合約陷阱中的風險。
小蔥小結
不得不感嘆騙子水平的提升,不僅積極鉆研代碼技術,還懂得參悟人性心理。
不過除了驚訝于騙子的高明外,我們也應該看到,區塊鏈瀏覽器作為一種工具,其產品特性存在著一定的針對性和局限性。本文QUESTION合約的設計者正是利用以太坊瀏覽器中部分交易記錄不顯示的特點成功欺騙玩家。
因此實際應用中,廣大用戶或開發者不能完全依賴于某一款區塊鏈瀏覽器所提供的數據。當然,各類區塊鏈瀏覽器網站也應在用戶界面上作出改進,盡可能降低被利用風險以及由此導致的用戶損失。
作為一個爆發式增長的領域,智能合約技術和應用的革新離不開大量涌入的專業人員的貢獻,但這其中也不免摻雜了諸多不和諧的因素,諸如本文所提到的合約以及不久前爆出的另一種蜜罐合約。不過,也正因這些因素的存在,才促使行業不斷尋找新的解決方案,促進技術和社區進步,整個過程需要包括安全團隊在內的更多專業人士共同努力。
文末,附上安比實驗室提供的QUESTION合約源碼分析詳情,對該合約的詳細功能實現做了完美梳理,保證看完你也會寫了。
游戲合約的設計:埋坑的基礎實踐
QUESTION合約的源碼中包含5個接口:啟動游戲,玩家猜答案,終止游戲,更新問題以及空的回落函數。
啟動游戲
由問題提出者啟動游戲(StartGame()),設置問題和答案,傳入的答案以哈希的形式保存在合約中。而游戲啟動僅第一次操作有效。
玩家猜答案
任何人都可調用Play() 接口,參與游戲猜答案,游戲玩家需支付 1 ETH 以上的費用(否則即使猜中也無獎勵)。
若猜測錯誤,無法任何獎勵,且事先支付的ETH會轉入該合約。若猜測正確,將得到合約中所有的ETH作為獎勵。
另外,問題發布者還具有兩個權限:終止游戲和更新問題。
終止游戲
問題提出者有權終止游戲(StopGame()),但終止游戲并非將游戲徹底終結,而是由問題提出者轉出合約中的所有 ETH ,但后續玩家依舊能繼續參與游戲。也就是說,問題創建者能隨時取走合約中所有的ETH。
更新問題
問題提出者可將問題和答案換掉(NewQuestion()),玩家后續針對新問題進行作答。
這是ERC 20 Token 中的經典問題——reApproval,依賴交易順序的漏洞進行作惡。
一個玩家猜中答案,并發起一筆交易來提交正確答案時,該筆交易會等待被打包;
而同時,問題提出者也提交一筆交易來更改問題,若更改問題的交易先被礦工打包,則玩家即使先猜中了答案也拿不到獎勵。
這里,雖然都是傳入問題和答案,但StartGame() 和 NewQuestion() 接口傳入的參數卻有所區別。StartGame() 函數傳入的第二個參數是問題答案的明文。然而,以太坊上接口調用的參數是可以查詢到的。簡單說,只要找到啟動游戲的那筆交易,就能找到問題的答案。
當然,合約中那些特殊權限的隱患只是障眼法,其實套路才剛剛開始。接下來我們看看游戲陷阱是如何設置的。
蜜罐陷阱的實現:巧借 Etherscan 缺陷
由于 Etherscan 上僅涉及ETH轉賬或 Token 轉賬的交易,部分交易不會顯示,合約創建者利用這一特性來隱藏設置答案的交易,將假的答案暴露在Etherscan 上。讓聰明且有心者誤以為發現了問題答案。
首先,合約創建者創建一份中間合約;
其次,合約創建者創建當前的游戲合約;
然后,合約創建者向中間合約發起一筆交易。這筆交易使得中間合約向游戲合約發起兩次調用。但這兩次調用在 Etherscan 的交易歷史中都不會顯示出來。我們可以在交易的Trace中查看到,兩次調用及其參數又可以通過合約的 ABI解碼得出。
從解碼后結果來看,第一次是調用了StartGame() 接口,傳入了問題“Imagine you are swimming in the sea and a bunch of hungry sharks surround you. How do you get out alive? ”和答案“sZs”。第二次調用了 NewQuestion() 接口,傳入的問題與上一次調用一致,答案則是一串哈希。至此,游戲的真實問題和答案偷偷設置完成,第二次調用的參數中的答案才是問題真正答案。
最后,合約創建者又向游戲合約發起了一筆交易。調用StartGame() 接口,傳入的問題與之前一致,答案正是Martin Derka看到的“Stop Imagining”。而由于啟動游戲只有第一次調用有效,本次調用根本不會改變合約的任何狀態,自然也不是問題的正確答案。
安比實驗室在另一個區塊鏈瀏覽器上進行查詢,也證實了這一問題。
在Martin Derka轉入1.05 個 ETH 到 QUESTION 合約不久后,合約創建者立刻就終止了合約,并取走合約中所有的ETH,至此游戲提出者成功得騙取ETH,一輪流程結束。
1.TMT觀察網遵循行業規范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網的原創文章,請轉載時務必注明文章作者和"來源:TMT觀察網",不尊重原創的行為TMT觀察網或將追究責任;
3.作者投稿可能會經TMT觀察網編輯修改或補充。