今天(2018-04-22)下午2點多十厢,幣圈鏈圈各個媒體突然爆料 美圖科技發(fā)行的數(shù)字貨幣——美鏈(BEC) 的Token 智能合約出現(xiàn)重大漏洞鸭廷,攻擊者可無限生成代幣多望。
【小蔥獨家:BEC合約出現(xiàn)重大漏洞瘾晃,攻擊者可無限生成代幣】OKEx今日發(fā)布最新公告稱训唱,暫停BEC交易和提現(xiàn)。據(jù)小蔥APP了解,這是因為BEC美蜜合約出現(xiàn)重大漏洞妈橄,攻擊者可以通過代幣合約的批量轉(zhuǎn)賬方法無限生成代幣庶近。 小蔥注:美鏈今年2月在OKex上線BEC交易。美鏈和美圖公司合作幫助美圖旗下的BeautyPlus提升內(nèi)容價值和市場占有率眷蚓,同時Beautyplus作為美鏈的種子應(yīng)用鼻种,協(xié)助美鏈的冷啟動。美鏈發(fā)的Token叫做美蜜BEC沙热。
坊間傳聞下午時候叉钥,美鏈團隊發(fā)現(xiàn)異常交易,于是立刻通知各交易所篙贸,停止 BEC 的交易和提現(xiàn)功能投队。正好實驗室的同事們忙里偷閑,一起分析了下這個出問題的合約代碼爵川。
這個漏洞比較明顯敷鸦,屬于常見的 整數(shù)溢出(overflow)問題。
下面我們來簡單分析下這個出問題的合約函數(shù):
function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {
uint cnt = _receivers.length;
uint256 amount = uint256(cnt) * _value;
require(cnt > 0 && cnt <= 20);
require(_value > 0 && balances[msg.sender] >= amount);
balances[msg.sender] = balances[msg.sender].sub(amount);
for (uint i = 0; i < cnt; i++) {
balances[_receivers[i]] = balances[_receivers[i]].add(_value);
Transfer(msg.sender, _receivers[i], _value);
}
return true;
}
這個函數(shù) batchTransfer(..)
的功能為批量轉(zhuǎn)賬寝贡,是美鏈團隊在 ERC20 標(biāo)準(zhǔn)合約基礎(chǔ)上擴展的函數(shù)扒披。調(diào)用者可以傳入若干個地址和轉(zhuǎn)賬金額,經(jīng)過一些強制檢查交易圃泡,再依次對balances
進行增減操作碟案,以實現(xiàn) Token 的轉(zhuǎn)移:
很明顯,當(dāng)傳入值_value
過大時颇蜡,uint256 amount = uint256(cnt) * _value
會發(fā)生溢出(overflow)价说,導(dǎo)致amount
變量無法正確等于cnt
倍的_value
,變得異常變小风秤,從而使得后面的require
對轉(zhuǎn)賬發(fā)起者的余額校驗可正常通過鳖目。
我們再來觀察攻擊交易詳細信息。
Function: batchTransfer(address[] _receivers, uint256 _value)
MethodID: 0x83f12fec
[0]: 0000000000000000000000000000000000000000000000000000000000000040
[1]: 8000000000000000000000000000000000000000000000000000000000000000
[2]: 0000000000000000000000000000000000000000000000000000000000000002
[3]: 000000000000000000000000b4d30cac5124b46c2df0cf3e3e1be05f42119033
[4]: 0000000000000000000000000e823ffe018727585eaf5bc769fa80472f76c3d7
攻擊者傳入8000000000000000000000000000000000000000000000000000000000000000
作為_value
唁情,而_receivers
數(shù)組的大小為2
疑苔,相乘之后剛好可超過uint256
所能表示的整數(shù)大小上限,引發(fā)溢出問題甸鸟,最終使得原本總量固定的 Token 得到“增發(fā)”惦费,并成功讓兩個目標(biāo)賬戶 Token 余額劇增。對于這種整數(shù)溢出漏洞抢韭,最為推薦的方法是采用 SafeMath
數(shù)學(xué)計算庫來避免薪贫。但是很不幸的是,這個問題合約的其余函數(shù)都正常使用了SafeMath
來避免 overflow 和 underflow 問題刻恭,但是卻在最關(guān)鍵的地方瞧省,漏掉了防溢出檢查扯夭,正所謂“百密而一疏”。
順便提一句鞍匾,上面的問題代碼交洗,僅需這樣簡單修改,即可防止 overflow 問題橡淑。
// uint256 amount = uint256(cnt) * _value; // 問題代碼
uint256 amount = _value.mul(uint256(cnt)); // 使用 SafeMath 庫
如圖中所示的巨額數(shù)量 Token构拳,我們很容易計算下,大約有10的58次方個 BEC梁棠。而事發(fā)前其市場價約為 0.3 美元置森。如果這些幣流入交易所并賣出,其后果不敢想象符糊。而發(fā)幣方美鏈(BEC)則會遇到大麻煩凫海。
國內(nèi)的區(qū)塊鏈團隊如雨后春筍,但是代碼在上線前可能并沒有做過專業(yè)審計男娄,也沒有通過設(shè)置賞金來懸賞漏洞行贪。
對待安全這一問題上,國外的多數(shù)區(qū)塊鏈項目要更成熟一些沪伙,智能合約在上線部署前都會尋求專業(yè)安全審計團隊的幫助瓮顽。
一些大的交易所和錢包也都會要求提供第三方審計報告。去年12月份围橡,美國明星交易所 Coinbase 的一個潛在合約漏洞被荷蘭的一家專業(yè)安全公司發(fā)現(xiàn)并上報,從而避免了巨額的損失缕贡∥淌冢可能有的朋友不明白,為何智能合約的代碼這么短晾咪,還會出這么多的問題收擦?其實,但凡從事智能合約開發(fā)2個月以上的同行都會對 EVM 以及 solidity 的各種坑印象深刻谍倦。
BEC事件不會是個案塞赂,安全問題容易被忽視。實驗室同事也果斷迅速掃描了一下整個以太坊上的全部合約昼蛀,居然發(fā)現(xiàn)了還有 12 個 Token 也存在著幾乎一模一樣的問題宴猾,于是第一時間給相關(guān)開發(fā)團隊發(fā)了個郵件提醒。
同時我們也希望越來越多的團隊能夠選擇上線前叼旋,找專業(yè)團隊做審計工作仇哆。除了代碼上的漏洞和缺陷外,也請大家也更加關(guān)注合約中的規(guī)則漏洞或后門夫植。相比整數(shù)溢出漏洞讹剔,這一類的高級規(guī)則漏洞則是非常,非常,非常不容易被發(fā)現(xiàn)延欠。
在這里我們再次提醒各個區(qū)塊鏈團隊以及智能合約開發(fā)愛好者陌兑,合約發(fā)布需要慎之又慎。
SECBIT實驗室
由一群熱愛區(qū)塊鏈技術(shù)的極客組建由捎,專注于可信智能合約與安全共識協(xié)議研究诀紊。實驗室成員遍布在多個國家,專業(yè)領(lǐng)域涉及區(qū)塊鏈底層架構(gòu)隅俘、智能合約語言邻奠、形式化驗證、密碼學(xué)與安全協(xié)議为居、編譯與分析技術(shù)碌宴、博弈論與加密經(jīng)濟學(xué)等諸多領(lǐng)域。SECBIT實驗室 目前著重于研究區(qū)塊鏈智能合約的安全問題蒙畴,助力區(qū)塊鏈團隊提高智能合約的可靠性與安全性贰镣,同時也開展構(gòu)建智能合約安全框架的理論探索與技術(shù)研發(fā)。