漏洞原理
这个漏洞发生在第三方合约或应用程序调用智能合约时。当将参数传递给智能合约时,参数将根据 ABI 规范进行编码。第三方合约可以发送比预期参数长度短的编码参数(例如,发送一个只有 38 个十六进制字符,即19 个字节长度,而不是标准的 20个字节长度的地址时)。在这种情况下,EVM 将在编码参数的末尾填充 0,以弥补预期的长度。这样,当智能合约不验证输入时,这就会成为一个问题。最明显的例子是,当用户请求提款时,交易所不验证 ERC20 令牌的地址。
安全隐患
转账函数
考虑标准的 ERC20 转账函数接口,注意参数的顺序:
function transfer(address to, uint tokens) public returns (bool success);
EVM 将按照 transfer()
函数指定的顺序对这些参数进行编码,即先地址然后数量。恶意用户可以通过删除以 0 或多个 0 结尾的以太地址的最后一个 0 来构造这种攻击。
短地址
接收用户数据的智能合约允许小于 20 字节的以太坊地址。通常以太坊地址看起来像:
0xc3Bb35818d58FCA0C4943bA98938cb6F46A91700
如果去掉末尾的两个 0 (一个十六进制字节等于0) 会怎样?EVM 会接受它,但在打包的功能参数的末尾添加额外的零。从给出一个短参数的点开始,传递函数参数将移动一个字节,这将移动传递的令牌数量。
攻击过程
假设用