1.美鏈攻擊程序
美鏈代幣BEC為發行在以太坊上的ERC20代幣,其具體合約的代碼在該鏈接中合約代碼,
向美鏈發起攻擊的交易鏈接為攻擊交易hash,
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;
美鏈攻擊的具體流程分為以下四步:
1.首先構造一個_value值,使得_receivers.len() * _value產生向上溢位,結果為一個極小值amount,比如使用_receivers.len()為2,_value值為2**255,那么在上述代碼中計算得到的amount值為0,
2.amount,value通過require驗證,
3.在msg.sender中減去amount數量的代幣,
4.為每個_receivers賬戶增加value數量的代幣,
其中value為一個極大值,相當于對美鏈的BEC代幣進行了增發,對應的_receivers賬戶可以獲取大量BECtoken,
2.solidity中上溢與下溢
在solidity中變數進行+、-、*運算時會產生溢位,如加法運算和乘法運算會產生向上溢位,減法運算產生向下溢位,如2**255變數乘以2,獲得的結果為0,具體溢位情況可參考以下合約代碼:
pragma solidity 0.4.20;
contract TestFlow {
uint256 public zero = 0;
uint256 public max = 2**256 - 1;
uint256 public mm = 2**255;
function subUnderFlow() public constant returns (uint) {
uint256 a = zero - 1;
return a;
}
function addOverFlow() public constant returns (uint) {
uint256 a = max + 1;
return a;
}
function mulOverFlow() public constant returns (uint) {
uint256 a = mm * 2;
return a;
}
}
3.定義安全庫
在對數字進行運算時,要采用安全函式,保證結果正確且不發生溢位,安全的數學運算庫的使用如下所示,
第一步:匯入SafeMath庫檔案
pragma solidity >=0.4.22 <0.6.0;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
第二步,參考
pragma solidity >=0.4.22 <0.6.0;
import "./safemath.sol";
contract jisuan{
uint a=2;
uint b=5;
uint c=8;
//引入safemath庫
using SafeMath for uint256;
//加法
function addNum()public view returns(uint d){
d=a.add(b);
}
//減法
function subNum()public view returns(uint d){
d=b.sub(a);
}
//乘法
function mulNum()public view returns(uint d){
d=a.mul(b);
}
//除法
function divNum()public view returns(uint d){
d=c.div(a);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296486.html
標籤:其他
上一篇:Upload-labs
下一篇:php反序列化漏洞基礎
