短地址漏洞
漏洞条件:
- 当地址的长度不足 20 byte (40个十六进制字符) 时,以太坊虚拟机 EVM 会进行高位补0x0
- 转发以太币时没有对地址长度进行验证
1. input 数据
交易的 input 数据分为三个部分:
1)4字节,是方法名的Hash值:a9059cbb。
2)32字节,存放以太坊地址,目前以太坊地址是20个字节(40个十六进制字符),高位补0x0,满足32字节,比如 0000000000000000000000001234567890123456789012345678901234567800。
3)32字节,是需要传输的代币数量,不足32字节,高位补0x0,满足32字节,比如00000000000000000000000000000000000000000000000000000adba0ce5362。
这三部分合起来就是交易数据:
a9059cbb000000000000000000000000123456789012345678901234567890123456780000000000000000000000000000000000000000000000000000000adba0ce5362
2. 补足机制
当以太地址长度不够时,EVM会从下一个参数(代币数量)的高位拿到 00 来补充以补成预期的长度,而代币数量不够后,会在其高位补 0x00
例如:以太地址 0000000000000000000000001234567890123456789012345678901234567800 去掉最后一个字节 0x00 ,EVM 就会将代币数量的前一个字节 0x00 作为地址的内容,后面的代币数量缺少的位数就会用 0x00 补充,也就是代币数量末尾添加了 0x00,这里代币数量末尾为 0x2,补位后变成了 0x200,这样就导致代币数量增加了 2^8 倍:000000000000000000000000000000000000000000000000000adba0ce536200
以太地址变化
0000000000000000000000001234567890123456789012345678901234567800 => 去掉00
00000000000000000000000012345678901234567890123456789012345678 => 补足00
0000000000000000000000001234567890123456789012345678901234567800
代币数量变化
00000000000000000000000000000000000000000000000000000adba0ce5362?=> 高位00被借
000000000000000000000000000000000000000000000000000adba0ce5362 => 末尾补足
000000000000000000000000000000000000000000000000000adba0ce536200
pragma solidity ^0.4.11;
contract ShortAddress{
mapping (address => uint) balances;
event Transfer(address indexed _from , address indexed _to, uint256 _value);
function ShortAddress() {
balances[tx.origin] = 10000;
}
function transfer(address to, uint amount) returns(bool success) {
require(balances[msg.sender] > amount);
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
return true;
}
function getBalance(address addr) constant returns(uint) {
return balances[addr];
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!