中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Solidity合約中的整數安全問題怎么解決

發布時間:2021-12-07 15:57:41 來源:億速云 閱讀:175 作者:iii 欄目:安全技術

這篇文章主要介紹“Solidity合約中的整數安全問題怎么解決”,在日常操作中,相信很多人在Solidity合約中的整數安全問題怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Solidity合約中的整數安全問題怎么解決”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一. 整數安全回顧

1. 整數安全簡介

在傳統的桌面windows攻防對抗領域,伴隨著微軟和合作伙伴對軟件開發流程推行    SDL規范,同時對安全投入的逐步加大,單一的封包超長和文件特定字段內容超長導致的溢出漏洞在一些大型軟件里幾乎絕跡。剩余漏洞除了瀏覽器中的UAF(有隔離堆和延遲釋放對關鍵類進行利用緩解    ) ,弱類型語言存在的類型混淆,還零星剩下了一些整數類的漏洞。整數類漏洞,最近的如去年的nginx cve-2017-7529。

區塊鏈方向,比較早的整數溢出類漏洞可追溯到2010年的比特幣大整數溢出,CVE-2010-5139 ,黑客通過整數溢出構造了大概    92233720368.54277039 個比特幣,最近的SMT/BEC的整數安全場景與之前比特幣的場景類似。

傳統安全領域中,整數安全與數據模型和整數運算支持的運算符相關,其中數據模型又跟處理器架構體系和操作系統平臺相關。如圖1。

Solidity合約中的整數安全問題怎么解決

圖1        
           

C中容易引發整數安全問題的運算符簡要羅列如下,如圖2。

Solidity合約中的整數安全問題怎么解決

圖2        
   

Solidity合約中的整數安全場景與之類似。

2. Solidity中的整數安全場景

SMT 和 BEC 都是以太坊代幣生態下的一個普通的 ERC-20        代幣。轉賬流通都是通過以太坊的solidity合約進行實現。

區塊鏈1.0的比特幣也有腳本語言,但是為了安全閹割掉了循環和遞歸等圖靈完備性語言才有的功能。以太坊 Solidity設計之初就被定位為圖靈完備性語言。        Solidity的圖靈完備性也為后續的合約漏洞陸續埋下了伏筆,如 The Dao 漏洞事件直接導致以太坊硬分叉成了eth            和舊鏈etc。

Solidity語言暫不支持類似于C中的 float double        等浮點型數據類型。支持int/uint變長的有符號或無符號整型。變量支持的步長以8 遞增,支持從uint8            到uint256,以及int8int256            。需要注意的是,uintint 默認代表的是uint256            和int256uint8 的數值范圍與            C中的uchar相同,即取值范圍是0            到 2^8-1,uint256支持的取值范圍是            0 到 2^256-1,余下數據類型以此類推。

Solidity語言中對于運算符的支持如下。

 比較:<=<            ,==!=>=                ,> ,返回值為bool 類型。

位運算符:&|,(^            異或),(~ 非)。

數學運算:+-,一元運算+            ,*/,(%            求余),(** 平方)。

Solidity合約代碼的邏輯都相對簡單,運算符的使用中加法 減法和乘法居多。

以太坊提供有一個Solidity語言的在線編譯測試工具。http://remix.ethereum.org/#optimize=false&version=soljson-v0.4.23+commit.124ca40d.js        我們以加法和減法運算作為舉例,簡單說明下整數溢出在Solidity 語言中的常規情況。

編寫如下solidity測試代碼。

pragma solidity ^0.4.0;
contract C {
// (2**256 - 1) + 1 = 0
function overflow() returns (uint256 _overflow) {
    uint256 max = 2**256 - 1;
    return max + 1;
    }

// 0 - 1 = 2**256 - 1
function underflow() returns (uint256 _underflow) {
    uint256 min = 0;
    return min - 1;
    }
}

在線測試工具中編譯運行結果如下如圖3圖4。

Solidity合約中的整數安全問題怎么解決

圖3        
Solidity合約中的整數安全問題怎么解決

圖4

可以看到uint256當取最大整數值,上溢之后直接回繞返回值為0 ,        uint256當取0下溢之后直接回繞,返回值為 2^256-1        。這是 solidity中整數溢出場景的常規情況。

3. Solidity中的整數溢出緩解和SafeMath庫

為了減少solidity合約開發中產生的安全問題,以太坊的官方開發博客陸續發布了一些與 solidity開發安全相關的博文。在        2017年 8月 6日            單獨發過一篇使用SafeMath 庫進行整數安全操作的文章<< SafeMath to protectfrom overflows >> 。詳見鏈接:                 https://ethereumdev.io/safemath-protect-overflows/    


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || 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;
  }
}

可以看到相關的可能產生溢出的操作都單獨封裝成函數,加入assert 斷言做判斷避免溢出。調用 SafeMath庫的方法如圖 5。

 Solidity合約中的整數安全問題怎么解決

圖5

二、SMT合約中的整數安全問題簡析

與大型軟件或者操作系統動輒十萬行甚至千萬行代碼不同,智能合約的代碼行數通常不多,功能也不是很復雜。一起來看下SMT 合約的相關代碼。

SMT的合約地址是 https://etherscan.io/address/0x55f93985431fc9304077687a35a1ba103dc1e081#code

問題存在于transferProxy()函數 代碼如下,如圖6

Solidity合約中的整數安全問題怎么解決

圖6        
       

在進行加法操作的時候沒有采用Safemath庫進行約束。 _feeSmt參數和        _value參數均可以被外界進行控制,  _feeSmt和 value均是            uint256 無符號整數,相加后最高位舍掉,結果為0。如圖7

Solidity合約中的整數安全問題怎么解決

圖7

直接溢出繞過代碼檢查導致可以構造巨大數量的smt代幣并進行轉賬。如圖8

Solidity合約中的整數安全問題怎么解決

圖8 

攻擊者的惡意轉賬記錄可以從如下鏈接進行看到:        
   

https://etherscan.io/tx/0x1abab4c8db9a30e703114528e31dee129a3a758f7f8abc3b6494aad3d304e43f

如圖9

Solidity合約中的整數安全問題怎么解決

圖9

三、BEC合約中的整數安全問題簡析

BEC的合約地址是0xC5d105E63711398aF9bbff092d4B6769C82F793D ,合約代碼可以訪問 etherscan的如下網址進行查看https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d#code        。代碼一共是299行。        
   

問題函數如圖10。

Solidity合約中的整數安全問題怎么解決

圖10

可以看到batchTransfer函數中 ,語句        balances[msg.sender] = balances[msg.sender].sub(amount)和 balances[_receivers[i]] = balances[_receivers[i]].add(_value) 中,調用            Safemath庫中的安全函數來完成加減操作,但是在第三行代碼,   uint256 amount = uint256(cnt) * _value 卻直接使用乘法運算符。

其中變量cnt為轉賬的地址數量,可以通過外界的用戶輸入 _receivers進行控制,        _value為單地址轉賬數額,也可以直接進行控制。乘法運算溢出,產生了非預期 amount 數值,并且外界可以通過調整_receivers            和_value 的數值進行操控。緊接著下面有一句對 amount進行條件檢查的代碼 require(_value > 0&& balances[msg.sender] >= amount);                其中 balances[msg.sender]代表當前用戶的余額。amount代表要轉的總幣數。代碼意思為確保                當前用戶擁有的代幣余額大于等于轉賬的總幣數才進行后續轉賬操作。因為通過調大單地址轉賬數額 _value的數值,amount                溢出后可以為一個很小的數字或者0 ,很容易繞過balances[msg.sender] >= amount                的檢查代碼。從而產生巨大_value數額的惡意轉賬。

攻擊者的惡意轉賬記錄,可以從如下鏈接看到https://etherscan.io/tx/0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f        。如圖11

      Solidity合約中的整數安全問題怎么解決

圖11    

可以從代碼totalSupply進行看到,bec 代幣總量共計才        7 000 000 000枚。 如圖12

         Solidity合約中的整數安全問題怎么解決

圖12

但是攻擊者通過溢出amount繞過后續 require中的判定條件分別向兩個地址惡意轉賬了         57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 枚bec            代幣。       

到此,關于“Solidity合約中的整數安全問題怎么解決”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黄山市| 本溪市| 安塞县| 泸州市| 建昌县| 丰城市| 许昌市| 六枝特区| 神木县| 浪卡子县| 祁连县| 墨脱县| 枣阳市| 高雄市| 华宁县| 武清区| 龙井市| 石狮市| 昌都县| 兰坪| 炉霍县| 洛南县| 乌兰浩特市| 景泰县| 龙南县| 来凤县| 江津市| 兴文县| 师宗县| 普定县| 晴隆县| 沙雅县| 田阳县| 天门市| 措美县| 武隆县| 舒城县| 宜兰市| 岳阳市| 诏安县| 黄平县|