Advertisement

智能合约之短地址攻击

阅读量:

在深入理解以太坊智能合约中的短地址攻击之前,在深入理解以太坊代币中ERC-20 TOKEN的基本知识之前

复制代码
    // Abstract contract for the full ERC 20 Token standard
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
    pragma solidity ^0.4.21;
    
    
    contract EIP20Interface {
    /* This is a slight change to the ERC20 base standard.
    function totalSupply() constant returns (uint256 supply);
    is replaced with:
    uint256 public totalSupply;
    This automatically creates a getter function for the totalSupply.
    This is moved to the base contract since public getter functions are not
    currently recognised as an implementation of the matching abstract
    function by the compiler.
    */
    /// total amount of tokens
    uint256 public totalSupply;
    
    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) public view returns (uint256 balance);
    
    /// @notice send `_value` token to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _value) public returns (bool success);
    
    /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
    /// @param _from The address of the sender
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    
    /// @notice `msg.sender` approves `_spender` to spend `_value` tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _value The amount of tokens to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _value) public returns (bool success);
    
    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens allowed to spent
    function allowance(address _owner, address _spender) public view returns (uint256 remaining);
    
    // solhint-disable-next-line no-simple-event-func-name
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    }

下面来简单介绍一下各个函数的功能:
balanceOf() :查询_owner地址持有的Token数量
transfer() :从msg.sender地址发送_value Token到_to地址
transferFrom():从_from的地址发送_value Token到_to地址
approve():Token所有者可以调用这个函数授权spender代表它使用value数量的token
allowance():用来查看owner给spender的token剩余额度

以下是改写后的文本内容

Token转账的地址为32字节,高位用0填充:
00000000000000000000000015022eCbc4Fc993d1Fd179A41F7b985fA9C0b787

转账代币的数量为32字节,1个TOKEN:
00000000000000000000000000000000000000000000000000000000000000001

最终向EVM移交的数据为:

复制代码
    a9059cbb00000000000000000000000015022eCbc4Fc993d1Fd179A41F7b985fA9C0b78700000000000000000000000000000000000000000000000000000000000000001

这些信息是对ERC-20协议中的TOKEN及其转账数据生成流程的一个概述。这些信息包括Token的具体定义、创建流程以及转账操作的基本机制。这些信息还包括Token的具体定义、创建流程以及转账操作的基本机制。

复制代码
    pragma solidity ^0.4.21;
    
    contract Short AddressAttack{
    	 mapping(address => uint) public balances;
    	 event transfer(address indexed _from,address indexed  _to, uint256 _value);
    	
    	function AddressAttack() {
    		balances[msg.sender] = 1000;
    	}
    	
    	function transfer(address _to, uint256 _value) public returns (bool success){
    		if(balances[msg.sender] <  _value)  return false;
    		if(_value <  0)  return false;
    		
    		balances[msg.sender]  -=  _value;
    		balances[ _to]  +=  _value;
    		event transfer(msg.sender,_to,_value);
    		return ture;
    	}
    }

实际上短地址攻击是一种常见的欺诈手段,在这种攻击中交易目的地地址末尾以一个零字节结束(这种情况越多越好)。当发起转账请求时恶意程序会截断交易目的地地址中的末尾零字节数据,并让智能合约自动填充缺失的部分。调用函数前4个字节:a9059cbb 转账地址:该笔交易的智能合约接收端口地址为……1 转账金额:该笔交易金额为……1

如果恶意删除转账地址末尾的一个字节(即0),其数据如下:
调用函数前四个字节:a9059cbb
交易地址:0000000000000000000000015 522eCbc4Fc 993d1Fd179A41F7b 985fA9C 78b
转账金额:$1
将生成相应的交易数据

复制代码
    a9059cbb00000000000000000000000015022eCbc4Fc993d1Fd179A41F7b985fA9C0b700000000000000000000000000000000000000000000000000000000000000001

数据到EVM中解析进行数据还原:

调用函数前四个字节的值为:a9059cbb

到这里意识到没有呢?原来仅仅转账1个TOEKN,在遭受攻击后却能转账256个TOKEN,这就是说短地址攻击的工作原理。

针对这个漏洞来说实在话以太坊不得不承认存在无法推卸的责任因为EVM没有严格的地址位数校验而且还会自动填充缺失的位数这使得漏洞得以存在。与此同时在提币的过程中交易所必须进行严格的地址验证以确保前端能够及时拦截恶意短地址

全部评论 (0)

还没有任何评论哟~