智能合約史上最大規(guī)模攻擊手法曝光,盤(pán)點(diǎn)黑客團(tuán)伙作案細(xì)節(jié)區(qū)塊鏈
2009年,中本聰創(chuàng)造了一個(gè)虛擬的去中心化新世界。這仿佛是一片流著奶和蜜糖的應(yīng)許之地,人們歡呼雀躍,蜂擁而至。但與所有的生態(tài)系統(tǒng)一樣,新世界有生命,就有捕食者。有交易者,就有黑客。區(qū)塊鏈上的應(yīng)用在進(jìn)化,攻擊者也同樣,我們給大家展示的是區(qū)塊鏈?zhǔn)澜绮粸槿酥牧硪幻妫盗饔縿?dòng)。意料之外,也在意料之中。
Last Winner(類(lèi) Fomo3D)游戲大火,導(dǎo)致以太坊異常擁堵,Gas 費(fèi)用暴漲。大量以太幣資金入場(chǎng)。
北京時(shí)間 2018 年 8 月 10 日凌晨 1:38,加州時(shí)間 9 日上午 10:38,安比(SECBIT)實(shí)驗(yàn)室收到合作伙伴美國(guó)硅谷 AnChain.ai 公司消息,基于 AI 的態(tài)勢(shì)感知系統(tǒng)發(fā)出預(yù)警信息,發(fā)現(xiàn)部分游戲合約出現(xiàn)大量交易并且存在異常的資金流動(dòng)情況。安比(SECBIT)實(shí)驗(yàn)室的小伙伴趕緊根據(jù)最新線索,對(duì)相關(guān)合約和交易進(jìn)行觀察、跟蹤、分析。
安比(SECBIT)實(shí)驗(yàn)室由中國(guó)科學(xué)技術(shù)大學(xué)博士郭宇創(chuàng)建,從密碼學(xué)、代碼語(yǔ)義、形式化驗(yàn)證、博弈論、編譯器等多種理論角度切入,在智能合約安全技術(shù)上開(kāi)展全方位深入研究。
AnChain.ai 由辛辛那提大學(xué)計(jì)算機(jī)博士方春生 Victor Fang 創(chuàng)建,方博士是硅谷上市網(wǎng)絡(luò)安全公司 FireEye 史上第一位首席數(shù)據(jù)科學(xué)家,負(fù)責(zé) AI 產(chǎn)品研發(fā)。AnChain.ai 專(zhuān)注安全威脅情報(bào)、區(qū)塊鏈態(tài)勢(shì)感知,憑借 AI 技術(shù)助力區(qū)塊鏈生態(tài)安全。
下文敏感地址只保留前 4 位。片尾有三個(gè)彩蛋,智能合約愛(ài)好者請(qǐng)不要錯(cuò)過(guò)。
悄然上線:莫名火爆的 Last Winner
Last Winner 是一款基于以太坊智能合約的 DApp 游戲,于 8 月 6 日上線,這款游戲一經(jīng)推出,就“異常”火爆。
這款游戲合約地址為 0xDd9fd6b6F8f7ea932997992bbE67EabB3e316f3C。據(jù) Etherscan 顯示,短短六天時(shí)間內(nèi),該游戲合約就已產(chǎn)生 27 萬(wàn)余筆交易。甚至前段時(shí)間以太坊網(wǎng)絡(luò)大擁堵也與 Last Winner 游戲密切相關(guān)。8 月 8 日 和 9 日,在 Last Winner 和 Fomo3D 超大規(guī)模交易量的共同作用下,以太坊未確認(rèn)交易數(shù)量創(chuàng)年內(nèi)新高,平均 Gas 費(fèi)用一度飆升至正常 10 倍以上。
該游戲第一輪獎(jiǎng)池金額為 1.6 萬(wàn)多個(gè)以太幣,而玩家總投資額更超過(guò) 10 萬(wàn)以太幣,資金量巨大。目前游戲第一輪已結(jié)束,第二輪獎(jiǎng)金池已迅速累積至 7000 多以太幣。
瘋狂的現(xiàn)象級(jí)游戲背后暗流涌動(dòng)。
疑團(tuán)重重:前期大量參與者的資金來(lái)歷不明
據(jù)知名媒體「區(qū)塊律動(dòng)」報(bào)道,Last Winner 由名為「蟻群傳播」的資金盤(pán)傳銷(xiāo)組織推廣運(yùn)營(yíng),有著數(shù)量眾多的會(huì)員和極強(qiáng)的推廣拉下線能力 [1]。而據(jù)另一款火爆游戲 Fomo3D 開(kāi)發(fā)團(tuán)隊(duì)稱(chēng),Last Winner 是仿 Fomo3D 游戲,其背后運(yùn)營(yíng)團(tuán)隊(duì)準(zhǔn)備了 20 萬(wàn) ETH 來(lái)進(jìn)行自動(dòng)刷量交易。因此,Last Winner 游戲火爆的背后,可能是一場(chǎng)精心布局的傳銷(xiāo)游戲,初期利用機(jī)器人發(fā)起批量交易,偽造活躍假象,吸引新韭菜入場(chǎng)。
Last Winner 游戲合約存在大量非正常交易,并且伴隨著大量合約的創(chuàng)建與自毀,與正常人類(lèi)調(diào)用行為特征偏離很大,這引起了我們的高度警惕。
瘋狂推廣:只面向國(guó)人,合約源碼卻未公開(kāi)
在各大論壇、媒體、以及微信群中,都可以見(jiàn)到 Last Winner 游戲的推廣文章,而這些文章有著類(lèi)似的描述,并且都附上推廣邀請(qǐng)碼。但 Last Winner 英文相關(guān)資料非常少。
顯然,這是一款針對(duì)中國(guó)人的游戲,有著誘人的推廣(拉下線)獎(jiǎng)勵(lì),因此在網(wǎng)絡(luò)上廣為傳播。并且,這款游戲有適配安卓和 iPhone 手機(jī)的 App,簡(jiǎn)化了使用操作,降低了參與門(mén)檻。
但是,十分可疑的是,作為一款基于智能合約的區(qū)塊鏈游戲,Last Winner 居然沒(méi)有公開(kāi)合約源代碼!這是一個(gè)非常危險(xiǎn)的信號(hào)。為何這樣一個(gè)游戲能這么火爆,吸引這么多人參加?
我們直覺(jué)上感到這款游戲到處透露著詭異的氣息。
安全性存疑:實(shí)則是 Fomo3D 山寨版
Last Winner 官方宣傳語(yǔ)寫(xiě)道:Last Winner(LW)是首款完全去中心化的類(lèi) Fomo3D 游戲 DApp,完全基于以太坊智能合約原生開(kāi)發(fā)。只要下載安裝 App 就可參與游戲。
類(lèi) Fomo3D 游戲,且未公開(kāi)源代碼,這不得不讓人產(chǎn)生懷疑。要知道,短短時(shí)間內(nèi)原創(chuàng)開(kāi)發(fā)一個(gè)好玩又安全的 DApp 游戲難度非常大。
安比(SECBIT)實(shí)驗(yàn)室迅速使用內(nèi)部工具逆向分析了 Last Winner 的合約代碼(字節(jié)碼)。果不其然,這款游戲合約代碼函數(shù)名稱(chēng)與 Fomo3D 高度相似,疑似直接拷貝(抄襲)了 Fomo3D 的源碼,但卻又新增了 10 余個(gè)可疑未知函數(shù)。
盡管 Fomo3D 在 Etherscan 公開(kāi)了源代碼,但這并不代表它開(kāi)源給任何人隨意使用。
安比(SECBIT)實(shí)驗(yàn)室之前報(bào)道過(guò):在 Fomo3D 爆紅之后,各類(lèi)山寨版 Fomo3D 層出不窮。之前這些山寨版游戲往往復(fù)制 Fomo3D 官網(wǎng)和合約源碼,并可疑地在一些地方進(jìn)行修改。而 Last Winner 在此基礎(chǔ)上更進(jìn)一步,推出移動(dòng)客戶(hù)端,并瘋狂推廣,卻不公開(kāi)智能合約源代碼。
智能合約游戲或 DApp 的亮點(diǎn)之一就是公開(kāi)透明。Last Winner 游戲則完全違背了這一點(diǎn),動(dòng)機(jī)十分可疑,參與該類(lèi)游戲的風(fēng)險(xiǎn)極高!
當(dāng)時(shí)嚴(yán)峻的形勢(shì)是:一方面有多個(gè)地址疑似瘋狂發(fā)起攻擊交易,另一方面項(xiàng)目方游戲合約未公開(kāi)源碼,高度可疑卻吸引了巨量資金。我們感覺(jué)到態(tài)勢(shì)十分緊急,于是迅速開(kāi)展分工合作。AnChain.ai 中美團(tuán)隊(duì)日夜交替分析和監(jiān)控異常交易,收集證據(jù),定位攻擊來(lái)源與攻擊規(guī)模。
安比(SECBIT)實(shí)驗(yàn)室的小伙伴們則兵分兩路,分別開(kāi)展對(duì)不透明游戲合約和黑客攻擊手法的逆向分析。
前情回顧:類(lèi) Fomo3D 游戲空投機(jī)制存漏洞
Fomo3D 游戲參與形式是用以太幣購(gòu)買(mǎi)游戲道具,除了最后一個(gè)購(gòu)買(mǎi)的人可以獲得巨額大獎(jiǎng)外,平時(shí)參與者還有機(jī)會(huì)獲得“空投”獎(jiǎng)勵(lì)。
這里有主獎(jiǎng)池和副獎(jiǎng)池的概念,最終的巨額大獎(jiǎng)和空投獎(jiǎng)勵(lì)分別從從主獎(jiǎng)池和副獎(jiǎng)池中獲取。
所有進(jìn)入游戲的以太幣,有 1% 數(shù)量會(huì)進(jìn)到副獎(jiǎng)池。每一次購(gòu)買(mǎi)道具都會(huì)有概率獲得空投。空投的概率從 0% 開(kāi)始,每增加一筆不小于 0.1 ETH 銷(xiāo)售訂單,空投概率會(huì)增加 0.1%。同時(shí)空投獎(jiǎng)金額與購(gòu)買(mǎi)金額也掛鉤,如果購(gòu)買(mǎi) 0.1 ~ 1 ETH,就有概率贏得 25% 副獎(jiǎng)池獎(jiǎng)金,購(gòu)買(mǎi)更多則比例越大。
一進(jìn)入游戲界面,就會(huì)看到鮮明提示,通知當(dāng)前中獎(jiǎng)概率和獎(jiǎng)池金額。這一設(shè)計(jì),原本是想增加游戲趣味性,并起到吸引資金入場(chǎng)、延長(zhǎng)游戲時(shí)間的作用。但實(shí)際情況卻并非如此。
通過(guò)觀察 LastWinner 游戲合約以及部分地址的異常交易行為,我們心中有了初步答案。
讓我們把時(shí)間退回到 20 多天前,早在 7 月 24 日,安比(SECBIT)實(shí)驗(yàn)室和派盾(PeckShield)科技分別同時(shí)預(yù)警:Fomo3D 游戲的智能合約存在隨機(jī)數(shù)漏洞可被利用,F(xiàn)omo3D 及所有抄襲源碼的山寨合約均存在該安全漏洞 [2]。原本設(shè)計(jì)上隨機(jī)性較大的空投游戲可通過(guò)特殊手段操縱,大大提高中獎(jiǎng)概率。
經(jīng)安比(SECBIT)實(shí)驗(yàn)室字節(jié)碼智能掃描工具逆向分析,Last Winner 游戲空投獎(jiǎng)勵(lì)代碼與 Fomo3D 基本一致,相似度達(dá) 91%,可能存在同樣漏洞。隨著游戲火爆進(jìn)行,機(jī)敏的黑客肯定也聞風(fēng)而動(dòng)。
不能說(shuō)的秘密:黑客制造秘密武器攫取高額收益
在區(qū)塊鏈態(tài)勢(shì)感知系統(tǒng)所展現(xiàn)出來(lái)的數(shù)據(jù)面前,我們不由地倒吸一口涼氣。
圖中的這些可疑地址,如同“病毒”一般緊緊纏繞在 Last Winner 合約四周,肆意吞噬著 Last Winner 內(nèi)的資金。
我們觀察到,圖中緊靠 Last Winner 的這些地址,有著類(lèi)似的行為模式。
如:
1.不停地往某合約地址上發(fā)起交易,同時(shí)附帶 0.1 個(gè)以太幣
2.不少交易狀態(tài)為失敗
3.成功的交易又會(huì)涉及大量“內(nèi)部交易”
4.“內(nèi)部交易”調(diào)用邏輯十分復(fù)雜,并伴隨大量合約的創(chuàng)建和自毀
安比(SECBIT)實(shí)驗(yàn)室迅速得出初步結(jié)論:這些不明合約就是黑客用來(lái)攻擊 Last Winner 的秘密武器,黑客正是通過(guò)這些合約,持續(xù)吸走 Last Winner 游戲內(nèi)的以太幣。
案發(fā)現(xiàn)場(chǎng):大量類(lèi)似交易,超高回報(bào)率
上面態(tài)勢(shì)感知圖中,占地面積最大的嫌疑地址引起了我們的注意:0xae58,于是從這個(gè)地址展開(kāi)了追蹤。
8 月 9 號(hào)當(dāng)天,0xae58 地址內(nèi)以太幣余額就以超過(guò) 300 個(gè),而當(dāng)時(shí)他正在大量往地址 0x5483 上發(fā)起交易,每筆交易轉(zhuǎn)賬金額都是 0.1 Ether。顯然,黑客正通過(guò) 0x5483 智能合約向 LW 發(fā)起攻擊。
讓我們觀察下面這條狀態(tài)顯示為成功的交易。表面上看是 0xae58 向攻擊合約 0x5483 轉(zhuǎn)了 0.1 Ether,實(shí)際卻涉及了一大堆地址間的相互轉(zhuǎn)賬,最終隨著 0x7c77 合約自毀,0.189 個(gè) Ether 轉(zhuǎn)移回 0xae58 的賬戶(hù)中。
這十分神奇,攻擊者投入 0.1 個(gè)以太幣,最終收獲 0.189 個(gè),瞬間回報(bào)率高達(dá) 89%,簡(jiǎn)直暴利。
我們很快發(fā)現(xiàn),除了 0xae58 地址外,還有四個(gè)地址也持續(xù)不斷地向 0x5483 合約發(fā)起類(lèi)似交易,持續(xù)獲得高額回報(bào)。
而失敗的交易,僅消耗 27712 燃料(Gas),成本損耗十分低。
研究目標(biāo)立刻鎖定為攻擊合約 0x5483。由于無(wú)法獲得源碼,安比(SECBIT)實(shí)驗(yàn)室立刻使用內(nèi)部工具展開(kāi)逆向分析。
暴利:數(shù)據(jù)面前我們?cè)俅握痼@
8 月 13 日,當(dāng)我們沉浸在研究黑客的攻擊合約各種細(xì)節(jié)優(yōu)化和精巧設(shè)計(jì)之時(shí),黑客攻擊數(shù)據(jù)全景分析新鮮出爐。
其中,攻擊獲利最大的是以 0x820d 地址為首的團(tuán)隊(duì)。他們累計(jì)獲利超過(guò) 5000 個(gè)以太幣。AnChain.ai 團(tuán)隊(duì)和安比(SECBIT)實(shí)驗(yàn)室將該黑客團(tuán)伙精確定位,并將其命名為 BAPT-LW20 (Blockchain APT – Last Winner)。
BAPT-LW20 團(tuán)隊(duì)在短短 6 天時(shí)間內(nèi),共發(fā)送將近 5 萬(wàn)筆交易,從中攫取 5194 個(gè) Ether,獲利價(jià)值將近 1200 萬(wàn)人民幣。
由下圖每小時(shí)發(fā)起的攻擊交易數(shù)量趨勢(shì)圖(下圖),我們可以看出攻擊的高峰期發(fā)生在 8 月 8 日 ~ 10 日,每小時(shí)平均攫取將近 100 以太幣,將近 22 萬(wàn)人民幣。這正好也是 LW 游戲最火爆的時(shí)間段。隨著游戲進(jìn)入后期,入場(chǎng)資金急劇下降,收益降低,黑客也不得不也降低了攻擊頻率。
再看看黑客每小時(shí)攫取以太幣數(shù)量趨勢(shì)圖(下圖)。慘淡的漫漫熊市里,黑客卻在狂賺以太幣。
下圖是“Last Winner 中黑客的交易量占比和攫取 ETH 占比”,可見(jiàn)黑客發(fā)送的交易量只占總交易量的 9.877%,但是去攫取了Last Winner獎(jiǎng)金池中49%的獎(jiǎng)金。黑客的嫻熟攻擊技能,為他們帶來(lái)了普通玩家難以企及的好運(yùn),而普通玩家在這場(chǎng)游戲里面幾乎很難獲得空投獎(jiǎng)勵(lì)。
火線追兇:BAPT-LW20 團(tuán)隊(duì)攻擊 LW 始末
安比(SECBIT)實(shí)驗(yàn)室嘗試追蹤復(fù)原 BAPT-LW20 團(tuán)隊(duì)攻擊時(shí)間線。
下圖是 BAPT-LW20 團(tuán)隊(duì)某賬戶(hù)余額變動(dòng)情況。
0x820d 是 BAPT-LW20 團(tuán)隊(duì)所有攻擊合約的部署者,也是攻擊的實(shí)施者之一,可認(rèn)為是 BAPT-LW20 團(tuán)隊(duì)的隊(duì)長(zhǎng)。0x820d 地址最早活躍于 7 月 20 日,賬戶(hù)中的初始以太幣均由 0x73B6 地址轉(zhuǎn)入。而 0x73B6 也是同一天開(kāi)始活躍的新地址,它的初始以太幣來(lái)自總部位于美國(guó)舊金山的 Kraken 交易所。
0x820d 在收到來(lái)自 0x73B6 的 10 個(gè)以太幣后,隨即部署了它的第一個(gè)合約。可能有些地方不太理想,他并沒(méi)有繼續(xù)使用該合約。三分鐘后,0x820d 部署下了第二個(gè)合約,攻擊對(duì)象是 Fomo3D。在一組準(zhǔn)備工作設(shè)置、若干次失敗的調(diào)用以及兩次雖然成功但卻沒(méi)有收益的嘗試過(guò)后,0x820d 應(yīng)該是發(fā)現(xiàn)了攻擊合約里的 bug 和優(yōu)化空間。
在接下來(lái)的 14 個(gè)小時(shí)內(nèi),他依次部署了 8 個(gè)合約進(jìn)行攻擊測(cè)試,無(wú)奈都不成功。終于在第 9 個(gè)合約 0xBad7 中首次完成攻擊,以 0.1 ETH 的投入換回了 0.125 ETH。
0xBad7 是 0x820d 團(tuán)隊(duì)首個(gè)可以正常工作的攻擊合約,他們?cè)?7 月 21 日至 7 月 23 日三天時(shí)間內(nèi)總計(jì)調(diào)用該合約 11551 次,小有斬獲。
7 月 23 日,0x820d 又部署了新的合約,將攻擊對(duì)象轉(zhuǎn)移為另一款 Fomo3D 山寨游戲老鼠會(huì) RatScam (0x5167350d082c9ec48ed6fd4c694dea7361269705),0x820d 團(tuán)隊(duì)在一天時(shí)間內(nèi)使用了 2299 次攻擊合約。
一天后,0x820d 又找到了新目標(biāo),一個(gè)名為 FoMoGame(0x86D179c28cCeb120Cd3f64930Cf1820a88B77D60) 的山寨游戲,部署新合約(0xb599)進(jìn)行攻擊。這款游戲知名度不高,入場(chǎng)資金并不多,黑客調(diào)用了 126 次之后就放棄。
接下來(lái)的三天內(nèi),0x820d 前后部署了 10 個(gè)新合約進(jìn)行優(yōu)化與攻擊測(cè)試。
終于,在 7 月 26 日上線了他們的新版攻擊合約(0x5483)。該合約總共發(fā)生過(guò) 23835 筆交易,最近一次活躍時(shí)間在 8 月 10 號(hào)(7 天前)。這款攻擊合約,可由攻擊者 自定義受害游戲合約地址。因此 0x820d 在接下來(lái)的幾天內(nèi),持續(xù)混合攻擊 Fomo3D 原版、RatScam、FoMoGame 等游戲,并持續(xù)觀察其他山寨游戲的動(dòng)態(tài),等待時(shí)機(jī)。同時(shí),繼續(xù)部署若干個(gè)新合約進(jìn)行調(diào)優(yōu)測(cè)試。
終于,8 月 6 日 Last Winner 游戲上線,24 小時(shí)后 0x820d 團(tuán)隊(duì)就使用準(zhǔn)備好的 0x5483 合約,針對(duì) Last Winner 發(fā)起第一次攻擊,并在接下來(lái)的 4 天內(nèi)集中力量,瘋狂利用空投漏洞展開(kāi)攻勢(shì)。
8 月 10 日,0x820d 調(diào)用 0x5483 攻擊合約 withdraw 接口,提走了里面的余額,攻擊疑似暫停。
原來(lái),他們?cè)缫呀?jīng)部署了新版合約攻擊合約 0x9C10,又發(fā)起了超過(guò) 30000 筆交易,至今仍在活躍攻擊。
不僅僅是空投:BAPT-LW20 黑客團(tuán)隊(duì)拿走 LW 最終大獎(jiǎng)
北京時(shí)間 8 月 17 日上午,Last Winner 游戲第一輪最終結(jié)束,最終大獎(jiǎng)由 0x5167 地址獲得,獎(jiǎng)金額總計(jì) 7,754 以太幣。
而這個(gè)地址正是 BAPT-LW20 黑客團(tuán)隊(duì)的五個(gè)地址之一。
如下圖,14 小時(shí)前,黑客還在利用攻擊合約獲取空投獎(jiǎng)勵(lì)。隨后,他改變了方案,直接用自身地址購(gòu)買(mǎi)道具參與游戲,不斷嘗試奪取最終大獎(jiǎng)。在此之后,又繼續(xù)調(diào)用合約攻擊 LW 游戲。
安比(SECBIT)實(shí)驗(yàn)室猜測(cè)黑客潛伏很久,早已做好充分的準(zhǔn)備,長(zhǎng)時(shí)間利用腳本監(jiān)控 LW 游戲狀態(tài),最終才能在眾人放松警惕之時(shí)獲得大獎(jiǎng)。
BAPT-LW20 黑客團(tuán)隊(duì)利用空投漏洞獲利超 5,194 Ether,同時(shí)又奪取最終大獎(jiǎng) 7,754 Ether,累計(jì)獲利 12,948 Ether。
同行相殺:Zethr 團(tuán)隊(duì)兩天時(shí)間就成功利用漏洞
這場(chǎng)超大規(guī)模的類(lèi) Fomo3D 智能合約游戲被攻擊事件,攻擊者使用的秘密武器也正是智能合約。
據(jù)安比(SECBIT)實(shí)驗(yàn)室調(diào)查分析,0x20C9 地址最先成功利用原版 Fomo3D 空投漏洞并獲取獎(jiǎng)勵(lì)。我們將他定位,并將其命名為 BAPT-LW10。
0x20C9 于 7 月 8 日 10 點(diǎn) 07 分創(chuàng)建了攻擊合約 0xe7ce,在接下來(lái)的十分鐘內(nèi),前后調(diào)用了三次,最終在第四次時(shí)成功獲得獎(jiǎng)勵(lì),投入 0.1 以太幣,收回 0.19 個(gè),回報(bào)率高達(dá) 90%(見(jiàn)下圖)。
此后,0x20C9 繼續(xù)部署多個(gè)攻擊合約,進(jìn)行調(diào)試優(yōu)化。最終,在 7 月 23 日部署了最終版本 0x39ac 攻擊合約,接下來(lái)的時(shí)間前后調(diào)用過(guò) 90 余次,而攻擊對(duì)象涉及 Fomo3D 原版、Last Winner 以及其他山寨版 Fomo3D。
據(jù)我們觀察,0x20C9 是最早研究并成功利用空投漏洞的黑客。研究過(guò)程中,安比(SECBIT)實(shí)驗(yàn)室發(fā)現(xiàn) 0x20C9 與另一款游戲 Zethr 密切關(guān)聯(lián)。
最終我們?cè)?Zethr 游戲合約代碼中發(fā)現(xiàn)了他的身影。他是熱門(mén)游戲 Zethr 的八位核心開(kāi)發(fā)者之一,代號(hào)為 Etherguy。
顯然,作為 DApp 游戲開(kāi)發(fā)同行,Etherguy 以及他所在的 Zethr 團(tuán)隊(duì)很早就研究了 Fomo3D 項(xiàng)目代碼。Fomo3D 合約 7 月 6 日部署上主網(wǎng),Etherguy 兩天后就發(fā)現(xiàn)并成功利用了漏洞。從調(diào)用規(guī)模來(lái)看,Etherguy (BAPT-LW10) 應(yīng)該主要還是出于研究目的,并沒(méi)有太多獲利。
讓其他黑客獲利最多的正是 Last Winner 游戲。
游戲細(xì)節(jié):Last Winner 為何讓黑客如此瘋狂
從最初 Fomo3D 上線后不久,空投漏洞就已被人發(fā)現(xiàn)并成功利用。隨著游戲的廣泛傳播,以及該漏洞被逐漸披露,空投漏洞的攻擊手段也在這一過(guò)程中不斷升級(jí)進(jìn)化,最終部分黑客團(tuán)隊(duì)完成了精巧的攻擊方案,可低成本、高效率獲得獎(jiǎng)勵(lì),并可大規(guī)模工程化地攻擊任意任何同類(lèi)游戲合約,瘋狂收割以太幣。
據(jù)安比(SECBIT)實(shí)驗(yàn)室分析,除 LW 游戲以外,不少黑客團(tuán)隊(duì)都曾嘗試攻擊其他類(lèi) Fomo3D 游戲合約。但獲利都遠(yuǎn)小于 BAPT-LW20 團(tuán)隊(duì)在 LW 游戲中所得。
我們?cè)噲D從 LW 游戲本身尋找答案。
LW 游戲是 Fomo3D 山寨版,本身沒(méi)有太多創(chuàng)新,但入場(chǎng)資金完全集中在游戲開(kāi)始后的第 2 天至第 5 天內(nèi)。巨量入場(chǎng)資金,會(huì)讓游戲空投獎(jiǎng)池迅速累積,因此這段時(shí)間也是黑客攻擊的黃金時(shí)機(jī)。
更要命的是,Last Winner 團(tuán)隊(duì)修改了空投游戲參數(shù),使進(jìn)入副獎(jiǎng)池(空投獎(jiǎng)池)的以太幣比例由 1% 調(diào)整到 10%,相當(dāng)于空投獎(jiǎng)勵(lì)金高了 10 倍!
一方面,游戲運(yùn)營(yíng)團(tuán)隊(duì)可能是利用高額空投獎(jiǎng)勵(lì)吸引用戶(hù)瘋狂加入;另一方面,他們可能并不知道空投漏洞的嚴(yán)重性,而提高獎(jiǎng)勵(lì)比例則會(huì)讓該問(wèn)題進(jìn)一步放大。
Last Winner 游戲簡(jiǎn)直成為了黑客的提款機(jī)!
特別地,前面提到 Last Winner 游戲第一輪入場(chǎng)資金已達(dá) 10 萬(wàn)以太幣,這也就是說(shuō),單單這一款游戲就有超過(guò) 1 萬(wàn)個(gè)以太幣都持續(xù)暴露在被攻擊的風(fēng)險(xiǎn)下,成為黑客的囊中之物。要知道,這款游戲第一輪最終獎(jiǎng)池也才 1.6 萬(wàn)余以太幣。本來(lái)空投獎(jiǎng)勵(lì)都是很小的金額,但黑客持續(xù)利用空投漏洞,積少成多,終成 Last Winner 最大贏家。
我們追蹤到有多個(gè)團(tuán)隊(duì)對(duì) Fomo3D 及山寨合約開(kāi)展大規(guī)模自動(dòng)化攻擊,企圖攫取利益。
而 BAPT-LW20 團(tuán)隊(duì)在游戲開(kāi)始后 24 小時(shí)左右就加入了戰(zhàn)局,并迅速擴(kuò)大作戰(zhàn)規(guī)模,最終占得先機(jī),獲取巨額收益。
安比(SECBIT)實(shí)驗(yàn)室追蹤到還有其他黑客團(tuán)隊(duì)向 Last Winner 合約開(kāi)展攻擊。部分黑客 8 月 11 號(hào)以后才入局,雖規(guī)模也很大,但終究因?yàn)殄e(cuò)過(guò)黃金時(shí)機(jī)而獲利較少。
攻擊合約:設(shè)計(jì)復(fù)雜又精巧
攻擊合約 0x5483,創(chuàng)建于 7 月 26 日,創(chuàng)建者為 0x820D,同時(shí)也是持續(xù)調(diào)用攻擊合約的五個(gè)地址之一。
起初,攻擊合約的創(chuàng)建時(shí)間讓我們感到疑惑,前面提到 LW 游戲合約于 8 月 6 日才部署上主網(wǎng)。難道 0x820D 可以未卜先知,或者他與項(xiàng)目方有什么不可告人的秘密?
帶著這個(gè)疑問(wèn),我們嘗試從合約 0x5483 的代碼(字節(jié)碼)中尋找答案。
經(jīng)過(guò)逆向發(fā)現(xiàn),該合約有七個(gè)公開(kāi)函數(shù),其中一個(gè)疑似函數(shù)名是 withdraw(uint256),用于將攻擊合約中積累的以太幣轉(zhuǎn)走。
安比(SECBIT)實(shí)驗(yàn)室在字節(jié)碼中發(fā)現(xiàn)了上面提到的五個(gè)地址。原來(lái)這兩個(gè)函數(shù)都會(huì)跳轉(zhuǎn)到同一個(gè)內(nèi)部函數(shù),檢查交易發(fā)起人是否是這五人地址之一。如果是,則可繼續(xù)執(zhí)行,如果不是,則提前讓交易失敗。
這也解釋了為什么偏偏是這五個(gè)地址一直在調(diào)用攻擊合約。因?yàn)樗麄兪且粋€(gè)團(tuán)隊(duì),合約特地為他們而設(shè)計(jì),而其他人根本無(wú)法正常調(diào)用。
初步猜測(cè),攻擊合約這么設(shè)計(jì)是為了分散權(quán)限和資金,降低出問(wèn)題或被發(fā)現(xiàn)的風(fēng)險(xiǎn)。
上圖正是一筆攻擊交易的傳入?yún)?shù)。第一部分是調(diào)用函數(shù)哈希 ID,后面跟著三個(gè)參數(shù)。注意看第一個(gè)參數(shù),攻擊者傳入的明顯是一個(gè)地址。顯然,這個(gè)地址正是 LW 游戲合約地址。
原來(lái)如此,攻擊目標(biāo)對(duì)象可以作為參數(shù)傳入。“黑客真機(jī)智!”,我們不由地感慨。之前的一個(gè)困惑被解開(kāi),早在 LW 游戲上線前就已部署好的攻擊合約 0x5483,其實(shí)是一個(gè)通用型武器。
繼續(xù)研究,接下來(lái)合約的復(fù)雜程度出乎我們意料。我們沿著生成的控制流程圖(CFG)追蹤合約函數(shù)調(diào)用過(guò)程,程序指令以及分支情況非常之多(下圖是一小部分截圖),讓人難以完全跟上。
安比(SECBIT)實(shí)驗(yàn)室使用動(dòng)態(tài)追蹤調(diào)試技術(shù),結(jié)合逆向分析結(jié)果與攻擊交易內(nèi)部記錄,搞清楚了黑客所使用的手法。
其他攻擊交易也都是類(lèi)似的過(guò)程,黑客調(diào)用攻擊合約,攻擊合約再調(diào)用提前創(chuàng)建好的合約,進(jìn)而創(chuàng)建新的合約,以新合約的身份參與 LW 游戲,買(mǎi)游戲道具,然后幾乎必定獲得空投獎(jiǎng)勵(lì)。
這一過(guò)程中不斷新建的合約,就是態(tài)勢(shì)感知系統(tǒng)中預(yù)警的大量異常合約創(chuàng)建與自毀。
追蹤攻擊合約調(diào)用歷史,發(fā)現(xiàn)攻擊者在部署完攻擊合約后,就立即多次調(diào)用特定函數(shù),每次新建 10 個(gè)新合約。而函數(shù)總共恰好調(diào)用了 100 次,因此新建了 1000 個(gè)新合約(記住這個(gè)細(xì)節(jié))。
在攻擊交易中,攻擊合約最先調(diào)用的就是這預(yù)先創(chuàng)建好的 1000 個(gè)合約之一,似乎是特地從中挑選出來(lái)一個(gè)地址。
智能合約:一切皆可預(yù)測(cè)
攻擊函數(shù)控制流程圖(CFG)中一個(gè)相隔很遠(yuǎn)的循環(huán)引起了我們的注意。
我們恍然大悟。攻擊函數(shù)所做的就是不斷循環(huán)地在 1000 個(gè)合約中,挑選“合適”的地址來(lái)完成下一步新建合約操作。所謂“合適”的地址,就是指能確保每次參與游戲都能獲得空投獎(jiǎng)勵(lì)。
前面提到,以太坊智能合約中可以很容易的預(yù)測(cè)隨機(jī)數(shù),因?yàn)殡S機(jī)數(shù)的來(lái)源都是區(qū)塊或者交易中特定的一些公開(kāi)參數(shù),如交易發(fā)起者地址、區(qū)塊時(shí)間戳、區(qū)塊難度等等。因此空投游戲利用隨機(jī)數(shù)來(lái)控制中獎(jiǎng)概率是不可行的。
而這里,黑客利用了另一個(gè)以太坊的特征,一個(gè)地址(賬戶(hù))創(chuàng)建一個(gè)合約,合約地址是可按照特定規(guī)則計(jì)算得到的,任何人都可以根據(jù)已知信息進(jìn)行推算。
因此,黑客循環(huán)利用自己控制的 1000 個(gè)合約地址,推算各地址下一次新建的合約地址,而該地址恰恰是空投游戲中獎(jiǎng)數(shù)字的隨機(jī)源。攻擊合約通過(guò)一系列預(yù)演推算來(lái)篩選出“合適”的地址來(lái)完成攻擊操作(技術(shù)細(xì)節(jié)后文會(huì)詳細(xì)討論)。
這才是黑客能夠以超高概率獲得空投的真正原因!
技術(shù)流:攻擊手法細(xì)節(jié)披露
類(lèi) Fomo3D 游戲空投漏洞的根本原因在于,以太坊智能合約環(huán)境中難以生成無(wú)法預(yù)測(cè)的隨機(jī)數(shù)。而 Fomo3D 開(kāi)發(fā)者在其合約中增加了「判斷調(diào)用者是普通人類(lèi)還是合約」的邏輯來(lái)嘗試規(guī)避,但此邏輯實(shí)現(xiàn)存在漏洞。黑客利用攻擊合約提前預(yù)測(cè)隨機(jī)數(shù),并通過(guò)在構(gòu)造函數(shù)內(nèi)調(diào)用游戲合約的方法來(lái)偽裝成普通人類(lèi)(非合約)地址,從而大大增加自身中獎(jiǎng)概率。
時(shí)間再次回到 7 月 23 日,以太坊基金會(huì)開(kāi)發(fā)團(tuán)隊(duì)負(fù)責(zé)人之一 Péter Szilágyi 在 Reddit 上首次公開(kāi)爆出這個(gè)漏洞并給出 1.0 版本的 POC 方案(詳細(xì)可以參考引文 [3])。這主要是利用了這些特點(diǎn):
空投游戲用來(lái)控制中獎(jiǎng)概率的隨機(jī)源,可被提前獲得
用戶(hù)能否獲得空投獎(jiǎng)勵(lì)以及獎(jiǎng)勵(lì)金額,可在另外一個(gè)合約中提前計(jì)算出來(lái),從而決定后面的操縱邏輯
Fomo3D 空投機(jī)制中嘗試限制只有非合約地址(普通人類(lèi))才能參加游戲以防止上述情況的發(fā)生。但該判斷方法存在漏洞,在構(gòu)造合約的過(guò)程中(即合約構(gòu)造方法里)參與游戲即可繞過(guò)該限制。
因此攻擊者可以部署一個(gè)智能合約,并在合約的構(gòu)造方法中計(jì)算出自己是否能夠獲益,如果能則投入以太幣參加游戲空投獲利,否則就不參加(參見(jiàn)下圖)。
Péter 提出的這個(gè)方案只是一個(gè)最簡(jiǎn)單的原型,因?yàn)槊看尾渴鸷霞s都要消耗不少 Gas,而且工作效率很低且收益率并不高,采用該方案攻擊,發(fā)起上千筆交易,都不一定能夠真正獲得空投獎(jiǎng)勵(lì)。
看到這里你可能會(huì)有疑問(wèn),上文的攻擊者似乎手法更高明,而且實(shí)際成功攻擊的發(fā)生時(shí)間要早得多。
Zethr 開(kāi)發(fā)者 Etherguy 早在 7 月 8 日就已使用更高明的手法成功獲利,解決了上文 1.0 方案中的部分問(wèn)題,我們姑且稱(chēng)之為 2.0 版本。
這個(gè)思路是通過(guò)合約循環(huán)創(chuàng)建子合約(參見(jiàn)下圖),直到子合約滿足空投條件可以獲利為止。這樣做的好處是,在 Gas 充足的情況下,每次調(diào)用合約幾乎一定可以獲得收益,提高了工作效率。然而這種方案和 1.0 版本的攻擊成本接近,并沒(méi)有從本質(zhì)上提高收益率。
而這次事件的最大獲利者 BAPT-LW20 團(tuán)隊(duì),就是在 2.0 版本的思路上進(jìn)行了進(jìn)一步優(yōu)化降低了投入成本,提高了收益率。 3.0 版本則瘋狂創(chuàng)建代理合約,通過(guò)利用計(jì)算下一步新建合約地址的技巧提前預(yù)判,篩選出符合條件的代理合約再創(chuàng)建出新的子合約,在子合約的構(gòu)造函數(shù)中再完成上述攻擊(見(jiàn)下圖)。而且攻擊目標(biāo)地址可配置,可多人同時(shí)協(xié)作攻擊。當(dāng)游戲獎(jiǎng)池金額不足以覆蓋攻擊成本時(shí),發(fā)出的攻擊交易會(huì)自動(dòng)提前失敗,僅消耗很低的 Gas 費(fèi)用。
在分析各類(lèi)攻擊合約過(guò)程中,我們還見(jiàn)到另外一種更高明的做法:主攻擊合約有著良好的設(shè)計(jì)模型,支持核心算法動(dòng)態(tài)替換與升級(jí)。原理上則是利用了 delegatecall 進(jìn)行操作。安比(SECBIT)實(shí)驗(yàn)室會(huì)持續(xù)關(guān)注這批黑客的動(dòng)向。
彩蛋一:空投與挖礦
我們知道在 PoW 挖礦的時(shí)候,礦工通常需要進(jìn)行如下計(jì)算:
BlockHash = Hash(Header Nonce) Check(BlockHash < Diff)
當(dāng) BlockHash 結(jié)果小于當(dāng)前難度值的時(shí)候,代表找到了一個(gè)合法的 Nonce。
在 Fomo3D 的空投獎(jiǎng)勵(lì)里有著類(lèi)似挖礦的機(jī)制:
function airdrop() private view returns(bool) { uint256 seed = uint256(keccak256(abi.encodePacked( (block.timestamp).add (block.difficulty).add ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add (block.gaslimit).add ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add (block.number)))); if((seed - ((seed / 1000) * 1000)) < airDropTracker_) return(true); else return(false); }
用戶(hù)唯一可以操縱的就是 msg.sender 字段,我們是否可以將 msg.sender 作為 Nonce 來(lái)挖礦呢?
答案顯然是可以的,智能合約的地址是根據(jù) 發(fā)起者賬戶(hù) nonce 決定的,于是有了第 1 代方法:
創(chuàng)建合約 用戶(hù)(地址 nonce0) --------------------> 新合約(嘗試攻擊) 用戶(hù)(地址 nonce1) --------------------> 新合約(嘗試攻擊) 用戶(hù)(地址 nonce2) --------------------> 新合約(嘗試攻擊) 用戶(hù)(地址 nonce3) --------------------> 新合約(嘗試攻擊)
但是這種方式需要用戶(hù)持續(xù)部署合約,消耗的礦工費(fèi)代價(jià)非常大,且成功率極低,每次都是以 1/1000 的中獎(jiǎng)概率在嘗試。
由于第 1 代驚人的失敗率,顯然無(wú)法利用,于是有了第 2 代攻擊方法:
這種方法的主要思想是,合約創(chuàng)建的新合約地址由 合約地址 nonce 確定:
部署合約 |------------------| hash(caddr, nonce) 用戶(hù) ----------> |循環(huán)創(chuàng)建合約, | -------> 新合約(嘗試攻擊) |直到攻擊成功或到達(dá)終 | -------> 新合約(嘗試攻擊) |止條件才停止,可能需 | -------> 新合約(嘗試攻擊) |要部署大量合約。 | -------> 新合約(嘗試攻擊) |----------------- |
這種方式類(lèi)似于挖礦,固定區(qū)塊頭部,不斷修改 nonce 來(lái)試探能否成功獲得獎(jiǎng)勵(lì),但是問(wèn)題在于,如果在循環(huán)第 1000 次才發(fā)現(xiàn)合法的 nonce,那么意味著之前部署的 999 個(gè)合約都屬于浪費(fèi) Gas 的操作。
那么如何更高效地尋找合法的 nonce 呢?
我們回想比特幣挖礦,一個(gè)挖礦任務(wù)中,不僅有 nonce,還有 extraNonce [4]。
在比特幣區(qū)塊的 Coinbase 字段中,有一個(gè)自由修改的區(qū)域,修改這個(gè)區(qū)域會(huì)導(dǎo)致 MerkleRoot 被修改,從而實(shí)現(xiàn) Header 被修改,具有 nonce 的效果,因此被稱(chēng)作 extraNonce。
為什么需要引入 extraNonce 呢?原因在于 nonce 為 32 bit 數(shù)字,搜索范圍只有 2^32,礦機(jī)幾乎一瞬間就遍歷完了,通過(guò)不斷修改 extraNonce 來(lái)擴(kuò)大本地搜索范圍,我們甚至可以不修改 nonce 只修改 extraNonce 來(lái)挖礦。
也許黑客也想到了這一點(diǎn),他們通過(guò)提前部署 1000 個(gè)代理合約來(lái)實(shí)現(xiàn)有 1000 個(gè) extraNonce 的效果。 至此,攻擊方法升級(jí)到了第 3 代:
部署合約 用戶(hù) --------------------------------------> 管理合約 C 調(diào)用合約C,預(yù)先創(chuàng)建代理合約(extraNonce) 用戶(hù) --------------------------------------> 1000個(gè)代理合約 調(diào)用合約C,循環(huán)嘗試可以成功攻擊的代理合約 用戶(hù) --------------------------------------> 部署合約(嘗試攻擊)
顯而易見(jiàn),這種攻擊方式同時(shí)實(shí)現(xiàn)了 2 個(gè)效果:
提升了攻擊成功率
減少了攻擊合約部署數(shù)量,大大減少了 Gas 消耗。
彩蛋二:黑客預(yù)先創(chuàng)建的合約數(shù)量與中獎(jiǎng)概率
前文提到黑客預(yù)先部署 1000 個(gè)代理合約,這個(gè)數(shù)字有什么講究呢?
if((seed - ((seed / 1000) * 1000)) < airDropTracker_)
seed 經(jīng)由一系列以太坊鏈上環(huán)境以及多次 Hash 運(yùn)算得出。Hash 結(jié)果對(duì) 1000 取余數(shù),可以得到 0~999 的偽隨機(jī)數(shù)。
我們假設(shè)哈希輸出結(jié)果是均勻的,并且哈希是抗碰撞的,那么平均每次中獎(jiǎng)的概率為 1/1000。
模擬結(jié)果:
公式運(yùn)算結(jié)果:
盡管更多合約能夠提供更高的中獎(jiǎng)概率,但是需要考慮到 Gas 消耗與 Gas Limit 等因素,不宜過(guò)大。
安比(SECBIT)實(shí)驗(yàn)室認(rèn)為黑客選擇部署 1000 個(gè)合約,是根據(jù)概率代碼 1/1000 想當(dāng)然做出的判斷。
彩蛋三:黑客可能利用了空投概率計(jì)算的另一個(gè) bug
黑客仍然需要更高效地攫取利潤(rùn),他們甚至“發(fā)現(xiàn)”了 Fomo3D 空投規(guī)則在這種攻擊方式下暴露出的缺陷。
攻擊合約需要在最開(kāi)始獲取空投獎(jiǎng)勵(lì)信息,作為后續(xù)操作的依據(jù)。因此,攻擊合約會(huì)先依次調(diào)用游戲合約的兩個(gè)查詢(xún)接口,分別是 0xd87574e0 airDropPot_() 和 0x11a09ae7 airDropTracker_()。
Fomo3D 空投獎(jiǎng)勵(lì)的 airDropTracker_ 計(jì)算方式為如下方法:
if (_eth >= 100000000000000000) { airDropTracker_ ; if (airdrop() == true) {...} }
Fomo3D 判斷是否能中空投獎(jiǎng)勵(lì)使用了如下方法:
if((seed - ((seed / 1000) * 1000)) < airDropTracker_) return(true);
根據(jù)我們分析,0x820d 后期更新的攻擊合約直接去除了對(duì) airDropTracker_ 的判斷,但這樣做其實(shí)有利有弊。
如果你了解細(xì)節(jié),猜出了黑客的用意,或者知曉這種做法的優(yōu)缺點(diǎn),歡迎添加小安同學(xué)微信(secbit_xiaoanbi),她會(huì)把你加入到「SECBIT 智能合約安全技術(shù)討論」的群里。
尾聲:下一個(gè)是誰(shuí)?
8 月 14 日,BAPT-LW20 黑客團(tuán)隊(duì)的 0x820d 再次部署了兩個(gè)新版攻擊合約,這一次他們將炮筒又對(duì)準(zhǔn)了另一款一天前新部署的不知名合約。
望著大屏幕上 AnChain.ai 態(tài)勢(shì)感知態(tài)勢(shì)感知平臺(tái)不斷閃爍的紅點(diǎn),安比(SECBIT)實(shí)驗(yàn)室和 AnChain.ai 都很清楚,區(qū)塊鏈?zhǔn)澜缋锏膽?zhàn)役還遠(yuǎn)遠(yuǎn)沒(méi)有結(jié)束。
2009年,中本聰創(chuàng)造了一個(gè)虛擬的去中心化新世界。這仿佛是一片流著奶和蜜糖的應(yīng)許之地,人們歡呼雀躍,蜂擁而至。但與所有的生態(tài)系統(tǒng)一樣,新世界有生命,就有捕食者。有交易者,就有黑客。區(qū)塊鏈上的應(yīng)用在進(jìn)化,攻擊者也同樣,我們給大家展示的是區(qū)塊鏈?zhǔn)澜绮粸槿酥牧硪幻妫盗饔縿?dòng)。意料之外,也在意料之中。
1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會(huì)明確標(biāo)注作者和來(lái)源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請(qǐng)轉(zhuǎn)載時(shí)務(wù)必注明文章作者和"來(lái)源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為T(mén)MT觀察網(wǎng)或?qū)⒆肪控?zé)任;
3.作者投稿可能會(huì)經(jīng)TMT觀察網(wǎng)編輯修改或補(bǔ)充。