区块链安全 - 以太坊短地址攻击

0x00 基础知识
EVM虚拟机在解析合约的字节码时,依赖的是ABI的定义,从而去识别各个字段位于字节码的什么地方。关于ABI,可以阅读这个文档:
一般ERC-20 TOKEN标准的代币都会实现transfer方法,这个方法在ERC-20标签中的定义为:
function transfer(address to, uint tokens) public returns (bool success);
第一参数是发送代币的目的地址,第二个参数是发送token的数量。
当我们调用transfer函数向某个地址发送N个ERC-20代币的时候,交易的input数据分为3个部分:
  • 4 字节,是方法名的哈希:a9059cbb
  • 32字节,放以太坊地址,目前以太坊地址是20个字节,高危补0
    • 000000000000000000000000abcabcabcabcabcabcabcabcabcabcabcabcabca
  • 32字节,是需要传输的代币数量,这里是1*10^18 GNT
    • 0000000000000000000000000000000000000000000000000de0b6b3a7640000
所有这些加在一起就是交易数据:

a9059cbb000000000000000000000000abcabcabcabcabcabcabcabcabcabcabcabcabca0000000000000000000000000000000000000000000000000de0b6b3a7640000


0x01 以太坊短地址
当调用transfer方法提币时,如果允许用户输入了一个短地址,这里通常是交易所这里没有做处理,比如没有校验用户输入的地址长度是否合法。
如果一个以太坊地址如下,注意到结尾为0:
0x12345678901234567890123456789012345678 00
当我们将后面的00省略时,EVM会从下一个参数的高位拿到00来补充,这就会导致一些问题了。
这时,token数量参数其实就会少了1个字节,即token数量左移了一个字节,使得合约多发送很多代币出来。我们看个例子:

这里调用sendCoin方法时,传入的参数如下:
0x90b98a11
00000000000000000000000062bec9abe373123b9b635b75608f94eb8644163e
0000000000000000000000000000000000000000000000000000000000000002
这里的0x90b98a11是method的hash值,第二个是地址,第三个是amount参数。
如果我们调用sendCoin方法的时候,传入地址0x62bec9abe373123b9b635b75608f94eb8644163e,把这个地址的“3e”丢掉,即扔掉末尾的一个字节,参数就变成了:
0x90b98a11
00000000000000000000000062bec9abe373123b9b635b75608f94eb86441600
00000000000000000000000000000000000000000000000000000000000002  
                                                               ^^
缺失1个字节
这里EVM把amount的高位的一个字节的0填充到了address部分,这样使得amount向左移位了1个字节,即向左移位8。
这样,amount就成了2 << 8 = 512。


0x02 构造短地址攻击
(1)首先生成一个ETH的靓号,这个账号末尾为2个0

使用一些跑号工具就可以做到,比如MyLinkToken工具,可以很轻易跑出末尾两个0的。


(2)找一个交易所钱包,该钱包里token数量为256000
(3)往这个钱包发送1000个币
(4)然后再从这个钱包中提出1000个币,当然这时候写地址的时候把最后两个0去掉
如果交易所并没有校验用户填入的以太坊地址,则EVM会把所有函数的参数一起打包,会把amount参数的高位1个字节吃掉。
(5)这三个参数会被传入到msg.data中,然后调用合约的transfer方法,此时,amount由于高位的1个字节被吃掉了,因此amount = amount << 8,即扩大了256倍,这样就把25600个币全部提出来了。


0x03 总结
针对这个漏洞,说实话以太坊有不可推卸的责任,因为EVM并没有严格校验地址的位数,并且还擅自自动补充消失的位数。此外,交易所在提币的时候,需要严格校验用户输入的地址,这样可以尽早在前端就禁止掉恶意的短地址。


Reference
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以太坊区块链浏览器是一个可以查看以太坊区块链上所有区块、交易、智能合约等信息的工具。搭建一个自己的以太坊区块链浏览器可以方便地查看和分析以太坊网络中的数据。下面是搭建以太坊区块链浏览器的一般步骤: 1. 安装节点软件:首先需要安装以太坊节点软件并同步区块链数据。以太坊节点软件有很多种,比如 Geth、Parity 等。这里以 Geth 为例,安装方法可以参考以太坊官方文档。 2. 安装数据库:以太坊的数据需要存储到数据库中才能被浏览器查询。目前比较流行的数据库是 MongoDB 和 MySQL。这里以 MongoDB 为例,安装方法可以参考 MongoDB 官网。 3. 安装浏览器软件:常用的以太坊区块链浏览器有 Etherscan、Etherchain 等。这里以 Etherscan 为例,安装方法可以参考 Etherscan 官网。 4. 配置浏览器:在浏览器的配置文件中设置节点和数据库的连接信息,以及其他一些参数。具体配置方法可以参考浏览器的官方文档。 5. 启动浏览器:启动浏览器软件并访问浏览器的网址即可使用。在浏览器中可以查看以太坊网络中的所有区块、交易、智能合约等信息。 需要注意的是,搭建以太坊区块链浏览器需要一定的技术水平和经验,建议有一定的区块链开发经验的人员进行操作。同时,由于以太坊网络在不断发展和变化,搭建过程中可能会遇到各种问题,需要耐心解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值