ERC20短地址攻击

今天重看USDT合约的代码,在BasicToken里有如下代码


    modifier onlyPayloadSize(uint size) {
        require(!(msg.data.length < size + 4));
        _;
    }

    function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
       // ......
    }

}

modifier onlyPayloadSize是确保payload是68,意思是前4字节函数选择器(函数签名),后面两个参数每个占32字节,一共是4+32+32=68字节,必须是满足这个长度。详见如下表:

部分 含义 长度(字节)
函数选择器(keccak256("transfer(address,uint256)") 前4字节) 4
_to 参数(address,占 32字节槽,右对齐,左补零) 32
_value 参数(uint256,占 32字节) 32
合计 68 字节

然后,这个是为了预防所谓的短地址攻击

具体短地址攻击手法:
1、攻击者构造了0x1111111111111111111111111111111111111100地址,并掌握私钥。
2、攻击者故意将0x11111111111111111111111111111111111111作为第一个参数 _to,然后第二个参数 _value正常传个金额,比如00000000000000000000000000000000000000000006765c793fa10079d0000000
3、将上述三个部分组装成 calldata传给一个 有缺陷的服务,这个服务提交给EVM执行的时候,会按照如下方式进行参数提取,前4字节不变,_to参数会提取0x1111111111111111111111111111111111111100,但是结尾的“00”实际上是截取的 _value参数的最开头的“00”,然后提取 _value的时候因为前边被截取了“00”会发现少了1个字节,所以会在右侧自动补齐“00”,最后 _value变成了000000000000000000000000000000000000000006765c793fa10079d000000000,相当于16进制左移了两位,变大了256倍!
4、这样攻击者成功的提取了256倍的金额到0x1111111111111111111111111111111111111100地址!

参考:https://ethbook.abyteahead.com/ch10/shortattack.html

posted on 2025-10-21 21:38  肥兔子爱豆畜子  阅读(2)  评论(0)    收藏  举报

导航