BEC和SMT出現的合約漏洞是怎么回事

最近在幣圈很多人討論的BEC代碼漏洞柜去,損失了64億人民幣。那黑客是如何做到的拆宛?其實是通過bec代幣合約的整型溢出漏洞嗓奢,讓自己的地址憑空產生了大量的bec代幣。

什么是整型溢出

那什么是整型溢出呢浑厚?在solidity編寫合約時蔓罚,定義整型一般是用uint8, uint256。一個變量如果定義為uint8表示的無符號的8位整型瞻颂,即表示的范圍為0-255豺谈。當給這個變量賦值256時,即整型溢出變成了0贡这,以此類推257變成了1茬末。

下面通過合約代碼實例說明:


pragma solidity ^0.4.21;

contract HelloWorld{
    

    function add(uint8 a, uint8 b) returns (uint8){
        
        uint8 result = a + b;
        
        return result;
        
    }
    
}

這個合約代碼很簡單,將傳入的兩個整數相加盖矫,但是我定義的返回類型是uint8丽惭,即最多表示255蔚携。

這時我們傳入參數255和1键科,即255+1剪廉,按照我們前面說的姨伟,這時會出現整型溢出蛙紫,result為0唉堪。

通過remix 執(zhí)行add函數結果也為0炸卑。

BEC源碼分析

回到BEC的問題上亡蓉,它的問題也是類似的证芭,只不過BEC合約是uint256的整型溢出瞳浦。先看一下這筆漏洞的交易:https://etherscan.io/tx/0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f

可以看到這筆交易是通過調用bec合約的方法,分別轉了57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968到兩個賬戶废士。

通過Input Data 可以看出是調用了batchTransfer方法實現bec代幣的轉賬叫潦。

打開BEC代幣合約源碼,找到batchTransfer這個方法:

這個函數的功能是:
調用該方法的人可以從自己的賬戶扣除相應的bec代幣官硝,給其他賬戶發(fā)送等額的代幣矗蕊。_receivers為需要發(fā)送bec的地址數組,_value表示每個地址發(fā)送多少bec氢架。

再來看該函數的邏輯:

uint cnt = _receivers.length;

首先取出接受地址個數傻咖,這筆交易發(fā)送給兩個地址,cnt為2达箍,這沒什么問題没龙。

uint256 amount = uint256(cnt) * _value;

然后算出總共需要消耗多少個代幣,看似也沒什么問題,但問題就出現在這里硬纤,我們繼續(xù)看后面的邏輯解滓。

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

這里做了兩個判斷,主要看下面那個:發(fā)送者(sender)的代幣余額要大于等于剛剛算出來的amount才能夠繼續(xù)操作進行轉賬筝家,這樣的邏輯判斷也很合理洼裤,錢不夠銀行也不會給你轉賬。

但是問題來了:
如果在之前amount的乘法計算時溪王,amount溢出了為0腮鞍,那這個require(_value > 0 && balances[msg.sender] >= amount);判斷不就失效了。

黑客正是利用了這個漏洞莹菱,因為uint256表達的范圍是0到(2的256次方減1)移国,黑客只需要向兩個地址分別轉入(2的255次方)數量的代幣,最后合約計算出amount為2的256次方道伟,剛好溢出為0迹缀。導致balances[msg.sender] >= amount判斷失效。這樣黑客就可以憑空在自己的兩個賬戶產生大量的bec代幣蜜徽。

SMT合約漏洞

smt出現的合約漏洞也類似祝懂,也是通過整型溢出。
合約地址:https://etherscan.io/address/0x55f93985431fc9304077687a35a1ba103dc1e081#code
溢出攻擊交易:
https://etherscan.io/tx/0x1abab4c8db9a30e703114528e31dee129a3a758f7f8abc3b6494aad3d304e43f

可以看出如果feeSmt和_value相加的結果剛好為2的256次方拘鞋,出現整型溢出結果為0砚蓬,第206行的判斷將失效,讓攻擊者憑空產生代幣盆色。

如何防止整型溢出

使用SafeMath庫來進行算數運算灰蛙,在合約中添加代碼:

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    assert(c / a == b);
    return c;
    
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

將BEC合約257行的乘法運算改為:

uint256 amount = uint256(cnt).mul(_value);

這樣在SafeMath執(zhí)行mul時,由于c計算出為0傅事,所以assert(c / a == b);將不通過缕允,拋出異常。
這里講一下require和assert的區(qū)別蹭越,assert會消耗執(zhí)行該函數的gas,而require只會消耗當前執(zhí)行的gas教届。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末响鹃,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子案训,更是在濱河造成了極大的恐慌买置,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件强霎,死亡現場離奇詭異忿项,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門轩触,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寞酿,“玉大人,你說我怎么就攤上這事脱柱》サ” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵榨为,是天一觀的道長惨好。 經常有香客問我,道長随闺,這世上最難降的妖魔是什么日川? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮矩乐,結果婚禮上逗鸣,老公的妹妹穿的比我還像新娘。我一直安慰自己绰精,他們只是感情好撒璧,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著笨使,像睡著了一般卿樱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硫椰,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天繁调,我揣著相機與錄音,去河邊找鬼靶草。 笑死蹄胰,一個胖子當著我的面吹牛,可吹牛的內容都是我干的奕翔。 我是一名探鬼主播裕寨,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼派继!你這毒婦竟也來了宾袜?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驾窟,失蹤者是張志新(化名)和其女友劉穎庆猫,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體绅络,經...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡月培,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年嘁字,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杉畜。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡纪蜒,死狀恐怖,靈堂內的尸體忽然破棺而出寻行,到底是詐尸還是另有隱情霍掺,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布拌蜘,位于F島的核電站杆烁,受9級特大地震影響,放射性物質發(fā)生泄漏简卧。R本人自食惡果不足惜兔魂,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望举娩。 院中可真熱鬧析校,春花似錦、人聲如沸铜涉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芙代。三九已至吊奢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纹烹,已是汗流浹背页滚。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铺呵,地道東北人裹驰。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像片挂,于是被迫代替她去往敵國和親幻林。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355