智能合約安全審計之路-訪問控制漏洞

核心問題:publi c的惡意使用(本次案例合約為例) ) )

作者-畢竟話少

描述:合約沒有設置合理的訪問控制模型,以及沒有對合約有效的校驗導致訪問控制漏洞的發生

核心問題:public的惡意使用(本次案例合約為例)

漏洞描述

智能合約的訪問控制漏洞主要體現在以下倆個方面:

  • 代碼層面可見性

針對函數和變量,限制其所能被修改和調用的作用域

  • 邏輯層面權限約束

通常針對函數,限制某些特權用戶訪問

代碼層面可見性的函數普及:

  • public

默認狀態下,可以進行任何形式的調用

  • external

可以通過其他合約或者交易來調用,不能在合約內部進行調用

  • internal

只能在合約(含子合約)內部進行調用

  • private

只能在合約(不包含子合約)內部進行調用

邏輯層面的權限約束的函數普及:

  • modifier

1.用於函數執行前的函數檢查

2.可以設置參數

3.特殊符號「_」用於指代函數代碼的執行位置

modifier noReetrancy() {     if (locked) throw;     locked = true;     _;     locaked = false;  }

漏洞合約分析

pragma solidity ^0.4.24;    contract AccessGame{        uint totalSupply=0;      address public owner;      mapping (address => uint256) public balances;        event SendBouns(address _who, uint bouns);        modifier onlyOwner {          if (msg.sender != owner)              revert();          _;      }        constructor() public {          initOwner(msg.sender);  //initOwner()初始化管理員權限      }        function initOwner(address _owner) public{          owner=_owner;      }        function SendBonus(address lucky, uint bouns) public onlyOwner returns (uint){          require(balances[lucky]<1000);          require(bouns<200);          balances[lucky]+=bouns;          totalSupply+=bouns;            emit SendBouns(lucky, bouns);            return balances[lucky];      }  }

漏洞點:第21行,在進行初始化管理員的時候,並沒有對init0wner()函數設置合理權限,使用public函數進行調用(默認狀態下,可以進行任何形式的調用),攻擊者可以自己調用init0wner()函數使自己成為管理員,從而調用SendBonus()增加自己的balances

使用Remix進行進行調試

  • 首先對合約進行編譯(Current version設置為0.4.24,Auto compile,Enable Optimization全部勾上。編譯完成後會出現1個合約為AccessGame
  • 首先部署AccessGame(漏洞合約),Account設置默認管理員地址(0Xca3…a733c),點擊Deploy,部署完成後,首先點擊owner,查看管理員為(0xca3…a733c),到這裡漏洞合約就已經部署完成了
  • 模擬攻擊調試,Account換一個地址為攻擊者地址(0x147…c160c),由於init0wner()函數是使用public自由調用的,所以這裡直接將攻擊者地址(0x147…c160c)複製粘貼到init0wner處點擊即可,這裡使用owner查看發現管理員為(0x147…c160c),已被成功越權替換,由於這裡攻擊者地址已經被設置為管理員權限了,所以可以直接調用SendBonus()為自己賬戶添加ETH(lucky設置為0x147…c160c,bouns設置為100 wei ETH),點擊transact進行充值,充值完成後使用Balances進行查看,發現攻擊者賬戶為100 wei ETH,實驗成功。

漏洞預防

  1. 設計合理的訪問控制模型,並在代碼中進行校驗
  2. 合理使用可見性約束和modifier
  3. 使用形式化驗證檢測智能合約的訪問控制漏洞