1. 摘要
【本文目標(biāo)】
(1)通過本文分析,了解Fomo3D游戲第一輪結(jié)束的交易攻擊流程及具體地址票灰;
(2)介紹“拒絕服務(wù)攻擊”(Denial of Service,DoS)的原理睛竣。
2. Fomo3D游戲規(guī)則
Fomo3D 是近一個(gè)多月以太坊上最火爆的應(yīng)用漫雕,也是個(gè)資金盤賭博游戲,本文的目的是做技術(shù)分析拉庵,所以這里只介紹其結(jié)束的設(shè)定:
- 游戲啟動(dòng)后從 24 小時(shí)開始倒計(jì)時(shí)灿椅;倒計(jì)時(shí)結(jié)束時(shí),最后一個(gè)夠買 key 的玩家將獲得獎(jiǎng)池中 48% 的獎(jiǎng)金钞支;
- 每有一個(gè)玩家購買 key茫蛹,倒計(jì)時(shí)會(huì)增加 30 秒。
所以烁挟,獲勝條件實(shí)際上很簡單:在自己購買 key 之后到游戲倒計(jì)時(shí)結(jié)束婴洼,不再有其他人購買 key。在現(xiàn)實(shí)世界中撼嗓,要做到這點(diǎn)不那么容易柬采,除非所有玩家都沒錢了;但在區(qū)塊鏈的世界中且警,具體到以太坊上粉捻,是可以通過“技術(shù)手段”做到不讓其他人購買的(也就是不讓其他人的“購買交易”得到“網(wǎng)絡(luò)確認(rèn)”)。這就是大家耳熟能詳?shù)摹熬芙^服務(wù)攻擊”(Denial of Service斑芜,DoS)肩刃。
3. Fomo3D的3分鐘交易攻擊過程
從Eetherscan去看看最后的30秒究竟發(fā)生了什么。Eetherscan上的數(shù)據(jù)表明杏头,問題不僅是出在最后30秒盈包,而是最后3分鐘——在這個(gè)時(shí)間以秒記的游戲里,整整3分鐘沒有下一個(gè)玩家出現(xiàn)大州。
交易圖顯示续语,在2點(diǎn)48分之前和2點(diǎn)51分之后,每一分鐘都會(huì)有多個(gè)玩家買入Fomo3D厦画,但獨(dú)獨(dú)在48分和51分之間疮茄,交易完全停止了滥朱。
以太坊在這3分鐘發(fā)生了什么?
2點(diǎn)48分力试,0xa169買key的交易完成徙邻,支付0.0055 eth,支持區(qū)塊高度是6191896(該筆交易信息:https://etherscan.io/tx/0x7a06d9f11e650fbb2061b320442e26b4a704e1277547e943d73e5b67eb49c349)畸裳;3分鐘后缰犁,2點(diǎn)51分,下一筆Fomo3D交易產(chǎn)生怖糊,區(qū)塊高度6191909帅容,但這筆交易來的太遲,永遠(yuǎn)錯(cuò)過了Fomo3D第一輪的競爭伍伤。
在區(qū)塊6191896和區(qū)塊6191909之間并徘,是死亡三分鐘,也是所有問題的答案扰魂。
3.1 區(qū)塊的秘密
區(qū)塊6191896麦乞,一切正常,0xa169的這筆交易也赫然在列劝评。區(qū)塊6191897在6秒之后被挖出姐直,基本正常。
但在下一個(gè)區(qū)塊蒋畜,6191898声畏,出現(xiàn)了一個(gè)0x18e1b664c6a2e88b93c1b71f61cbf76a726b7801的地址,有2筆交易與其有關(guān)姻成。
緊接著砰识,區(qū)塊6191899中,3筆交易與其有關(guān)佣渴;區(qū)塊6191900中辫狼,3筆;區(qū)塊6191901中辛润,2筆膨处;區(qū)塊6191901中,2筆砂竖;區(qū)塊6191902中真椿,4筆;區(qū)塊6191903中乎澄,2筆突硝。
接下來,區(qū)塊6191904置济,該區(qū)塊一共只打包了3筆交易解恰,全部來自0x18e锋八;區(qū)塊6191905中,全部7筆交易中的3筆护盈;區(qū)塊6191906中挟纱,全部的3筆交易。
區(qū)塊6191907中腐宋,全部4筆交易中的3筆紊服;區(qū)塊6191908中,全部5筆交易中的4筆胸竞。
終于欺嗤,到了區(qū)塊6191909,0x18e消失了卫枝。
(查看各個(gè)區(qū)塊的信息可以變更以下地址的區(qū)塊號(hào):https://etherscan.io/block/6191909 )
擺脫0x18e的區(qū)塊一口氣打包了166筆交易剂府,多筆與Fomo3D相關(guān)的交易包含其中,但它們被耽擱的太久剃盾,游戲結(jié)束了。
0x18e有什么特別淤袜?為何死亡三分鐘里以太坊上所有的區(qū)塊都包含與它有關(guān)的2到4條交易痒谴?原因就出在它對(duì)gas的消耗上。
0x18e的一筆交易需要耗費(fèi)360萬或420萬的gas铡羡,兩筆交易加起來是780萬gas积蔚,而ETH一個(gè)區(qū)塊目前能容納的gas總量是800萬左右。
這樣一樣烦周,因?yàn)?x18e總gas費(fèi)高尽爆,會(huì)被優(yōu)先選擇打包,又因?yàn)樗嫉膅as量大读慎,所以兩筆交易就能填滿整個(gè)區(qū)塊漱贱,容不下其他的交易。
于是夭委,在交易消失的3分鐘里幅狮,在區(qū)塊6191896與區(qū)塊6191909之間,所有的節(jié)點(diǎn)都在打包與0x18e相關(guān)的交易(雖然這些交易全因gas超量失敗了株灸,也就是說0x18e并沒有真正的為這些交易付費(fèi))崇摄。
而所有與Fomo3D有關(guān)的交易,同以太坊上其他的交易一起慌烧,被留在了交易池排隊(duì)等候逐抑。
3分鐘很短,但足夠結(jié)束一個(gè)以30秒為倒計(jì)時(shí)的游戲屹蚊。
3.2 詭異的0xa169與0x18e
在0xa169買入最后一個(gè)key后厕氨,0x18e“堵塞”了以太坊3分鐘进每。是巧合嗎?不是腐巢。
0x18e在8月18號(hào)被創(chuàng)建品追,晚0xa169地址3天,之后兩者頻繁互動(dòng)冯丙,應(yīng)該是在測試攻擊模型肉瓦。
8月21號(hào),兩者間的互動(dòng)結(jié)束胃惜,8月22號(hào)泞莉,0xa169發(fā)起了最后一役,它主攻船殉,0x18e掩護(hù)鲫趁。
看看0x18e掩護(hù)0xa169的時(shí)間點(diǎn)。
在最后一次攻擊中利虫,0xa169在6點(diǎn)48分22秒完成交易挨厚,0x18e在6點(diǎn)48分43秒至6點(diǎn)52分01秒之間發(fā)起攻擊,堵塞網(wǎng)絡(luò)糠惫。
但這不是他們第一次配合疫剃,0xa169曾在5點(diǎn)50分42秒發(fā)起一筆交易,0x18e在5點(diǎn)51分10秒至5點(diǎn)52分57秒之間發(fā)起攻擊硼讽;在此之前巢价,0xa169在5點(diǎn)35分46秒發(fā)起交易,0x18e在5點(diǎn)36分49秒至5點(diǎn)37分28秒間發(fā)起攻擊固阁。
0x18e為0xa169爭取到最多時(shí)間的一次壤躲,就是它們成功的一次。在0xa169拿走獎(jiǎng)金之后备燃,0x18e這個(gè)地址再無任何動(dòng)作碉克。
所以,如果你真以為有人用0.8個(gè)ETH贏了Fomo3D并齐,未免天真棉胀。這是一場投入技術(shù)、金錢冀膝,被精心策劃唁奢、全力以赴的戰(zhàn)役。
3.3 錯(cuò)失勝利的人
不過窝剖,如果說這場勝利完全與幸運(yùn)無關(guān)也不全對(duì)麻掸。因?yàn)?xa169能拿走獎(jiǎng)金還跟它的對(duì)手,一個(gè)倒霉的人有關(guān)赐纱。
簡單講講這個(gè)運(yùn)氣不好的家伙脊奋。地址是0x32ad247B94E46bB75caC37B81e6CB53173002370熬北,就是0xa169上方的這一位。
0x32ad是個(gè)狠角色诚隙,因?yàn)樵谶@個(gè)地址上讶隐,它總共就出手一次,而且?guī)捉晒糜帧T摴P交易的地址信息為https://etherscan.io/tx/0x5e7309de3aab2a36286fc04aebcfadec627bcb4aa89af4dad82001a5993d1be1 巫延。
它算準(zhǔn)在最后的時(shí)刻出擊,用極高的gas單價(jià)被選中進(jìn)入?yún)^(qū)塊打包(單個(gè)交易地消,gas費(fèi)551美金)炉峰,它也是整個(gè)死亡3分鐘內(nèi)唯一闖入?yún)^(qū)塊打包環(huán)節(jié)的Fomo3D交易(區(qū)塊6191907)。
但它失敗了脉执,緣于一個(gè)有趣的不幸疼阔。它設(shè)置的Gas Limit是379000,但交易耗費(fèi)的gas超過了379000半夷。
在Fomo3D中婆廊,幾乎沒有g(shù)as超過379000的交易,但這一次巫橄,最重要的一次淘邻,偏偏就超了。
4. 原理總結(jié)
在目前成熟的 Web 服務(wù)技術(shù)里嗦随,制造 DoS 攻擊一般是通過大量的并發(fā)請(qǐng)求和/或大數(shù)據(jù)量的獨(dú)立請(qǐng)求,將 Web 服務(wù)的帶寬/服務(wù)資源占滿敬尺,而使其無法再相應(yīng)正常的數(shù)據(jù)請(qǐng)求枚尼。在以太坊中,則可以通過制造大量的“垃圾合約調(diào)用”來達(dá)到同樣的效果砂吞。
這里需要來講一個(gè)機(jī)制了:交易池(transaction pool)署恍。在礦工/礦池節(jié)點(diǎn)上,通常都會(huì)有一個(gè)交易池蜻直,網(wǎng)絡(luò)上廣播的所有新的交易都會(huì)被首先加入這個(gè)“池”盯质,而后再由礦工/礦池選擇那些“經(jīng)濟(jì)性更好”的交易優(yōu)先打包確認(rèn)。這里說的“經(jīng)濟(jì)性”概而,即由交易發(fā)送者在交易數(shù)據(jù)中指定的 gasPrice呼巷,gasPrice 越高,執(zhí)行交易所附帶的合約代碼的執(zhí)行費(fèi)用也就越高赎瑰,而這些費(fèi)用通常是會(huì)作為手續(xù)費(fèi)支付給礦工的王悍。所以,礦工/礦池會(huì)從交易池中選取那些 gasPrice 明顯高于其他交易的交易來優(yōu)先打包執(zhí)行(確認(rèn))餐曼。并且压储,礦工并不能從技術(shù)上判斷一個(gè)交易中附帶的程序代碼是否是“垃圾合約調(diào)用”(它們也沒有這個(gè)“責(zé)任”)鲜漩,它們僅僅選取那些執(zhí)行費(fèi)用更高的交易來優(yōu)先執(zhí)行〖铮基于這個(gè)原理孕似,就允許了攻擊者通過調(diào)高包含了“垃圾合約調(diào)用”的交易的 gasPrice,來在短時(shí)間內(nèi)用這些“無效交易”占用區(qū)塊的可用 gas刮刑,以使其他“正常交易”無法被打包進(jìn)區(qū)塊喉祭。
這里還有幾個(gè)基礎(chǔ)知識(shí)需要科普一下:
- 以太坊中的區(qū)塊可包含的交易(計(jì)算量)是由區(qū)塊的 gasLimit 來控制的,而并不是像比特幣那樣用數(shù)據(jù)大小來限制为朋;以太坊中目前區(qū)塊的 gasLimit 上限是 800 萬 gas臂拓,礦工可以做 5% 以內(nèi)的上下浮動(dòng);區(qū)塊內(nèi)能包含多少交易习寸,是看這些交易執(zhí)行所消耗的總 gas 是否達(dá)到這個(gè)區(qū)塊的 gasLimit胶惰;
- 以太坊中執(zhí)行交易的費(fèi)用,是用交易基礎(chǔ)執(zhí)行費(fèi)用的 21000 gas霞溪,加上交易中附加的代碼的字節(jié)大小的費(fèi)用(這里有一個(gè)折算公式孵滞,不詳細(xì)講了)以及實(shí)際執(zhí)行代碼所消耗的 gas 的總和乘以交易中指定的 gasPrice 來計(jì)算的;這個(gè)交易費(fèi)用鸯匹,會(huì)從交易發(fā)送者賬戶中自動(dòng)扣除坊饶;如果交易發(fā)送者賬戶余額不足,交易不會(huì)被打包進(jìn)區(qū)塊殴蓬;
以太坊中的交易的實(shí)際執(zhí)行所要消耗的 gas 是可以根據(jù)交易執(zhí)行時(shí)的“世界狀態(tài)”明確知道的匿级,也就是這個(gè)交易的實(shí)際執(zhí)行費(fèi)用是明確知道的,礦工就是據(jù)此來判斷打包交易的“經(jīng)濟(jì)性”染厅。
在 Fomo3D 游戲的后期(即獎(jiǎng)池金額已經(jīng)很高)痘绎,大多數(shù)玩家都會(huì)選擇在倒計(jì)時(shí)的最后數(shù)分鐘內(nèi)才去購買 key,以讓游戲能繼續(xù)下去肖粮。這時(shí)孤页,如果有一個(gè)機(jī)會(huì),在攻擊者自己購買了 key 之后(這只會(huì)給剩余時(shí)間增加 30 秒)涩馆,能在其后數(shù)分鐘內(nèi)讓網(wǎng)絡(luò)不再確認(rèn)其他人的購買交易行施,攻擊者就可以讓游戲結(jié)束從而贏得大獎(jiǎng)。
加入輝哥知識(shí)星球魂那,可以獲得Fomo3D全套代碼蛾号,包含前端頁面。
5. 參考
1) Fomo3D 游戲的第一輪是如何結(jié)束的
2) Fomo3D死亡3分鐘:黑客用0.8ETH贏下了10000個(gè)ETH