ERC20 Short Address Attack

  • 什么是ERC20
  • Application Binary Interface(ABI)
  • ERC20 Short Address Attack
  • 开始攻击
  • 怎么利用?
  • 攻击防范

什么是ERC20

代币大家应该都很熟悉了,代币也叫 token, 他不是像比特币,以太坊等虚拟币这样建立在大量技术人员的辛苦工作基础之上,用于维持公链运行的虚拟货币。代币一般是依赖于以太坊平台,就是一个以太坊平台上面的一个智能合约里面记录的数字。

所以说token没有任何价值,每个人都可以在1分钟之类创建出无限的token。那么为什么现在有这么多的token价格这么高,还有这么多人去交易呢? 一般来说,发行token的人会将整个token绑定一个很有前途的项目,什么纳米科技,卫星技术,新型动力,怎么牛逼怎么往上面靠,然后找几个币圈有名气的人站台,然后通过各种渠道发布这个token很了不起的舆论,接下来就是上交易所收割韭菜了,至于他们当时标榜的跨时代的项目就不知道是不是能够真的完成了,毕竟钱已经收到口袋里面了。

不可否认,有些token确实很有良心,也真的按照设想的去做了事情。这里不深究发行token的对与错,这里我们讲下ERC20。

大家都来发token,那么这么多的token没有一个统一的标准,不好在以太坊平台进行通用的转让呀,为了便于token的流通,于是出现了一个token的标准叫做ERC20,简单点说,ERC20规定了token智能合约必须要实现的9个方法和2个事件。

具体的方法和事件名请看 ERC-20标准说明

Application Binary Interface(ABI)

这篇文章其实是讲ERC20攻击的,要想攻击ERC20,我们首先要知道怎么去跟以太坊虚拟机进行交互。在以太坊Ethereum 生态系统中, 应用二进制接口Application Binary Interface(ABI) 是从区块链外部与合约进行交互以及合约与合约间进行交互的一种标准方式。 数据会根据其类型按照约定的方法进行编码。

简单点说,一个ABI包括一个函数选择器和函数的参数。

函数选择器是一个函数调用数据的前 4 字节,指定了要调用的函数。这4个字节是函数签名通过 Keccak(SHA-3)哈希之后的前 4 字节。

函数的参数会被编码成32字节,不足32字节的将会补全。ERC20 Short Address Attack 就是在这个函数补全上面出现的。

ERC20 Short Address Attack

我们先看一个简单的token合约,用来转账。

pragma solidity ^0.4.11;contract MyToken {
mapping (address => uint) balances;event Transfer(address indexed _from, address indexed _to, uint256 _value);function MyToken() {
balances[tx.origin] = 10000;
}function sendCoin(address to, uint amount) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
return true;
}function getBalance(address addr) constant returns(uint) {
return balances[addr];
}
}

很简单的一个智能合约, 这里我们看下sendCoin的方法,他接收2个参数,一个是接收token的地址,一个是数目。

如果想进行调用,那么生成的ABI可能是这样的:

0x90b98a11
00000000000000000000000062bec9abe373123b9aabbcce608f94eb8644163e
0000000000000000000000000000000000000000000000000000000000000004

其中:
0x90b98a11 是Keccak (SHA-3) 运算之后的方法标记 sha3(sendCoin(address,uint))。
00000000000000000000000062bec9abe373123b9aabbcce608f94eb8644163e 是 20字节的目标地址,被补全到32字节。
0000000000000000000000000000000000000000000000000000000000000004 是 1个字节的4被补全到32字节。

开始攻击

如果攻击者不按常理出牌,并不将参数补全到32字节,那么总的ABI长度会比预料的要小,那么会出现什么问题呢?

还是上面的例子,我们要发送4个token到62bec9abe373123b9aabbcce608f94eb8644163e。
但是我们把地址的最后1个字节“3e”去掉,那么ABI如下所示:

0x90b98a11
00000000000000000000000062bec9abe373123b9aabbcce608f94eb8644163e00
00000000000000000000000000000000000000000000000000000000000004^^

我们可以看到,最后的04后面其实是少了一个字节的。

那么如果我们把这个ABI传给以太坊虚拟机,会出现什么问题呢?

以太坊虚拟机会将ABI补全,就是在04后面加一个字节00。

参数如下:

_from: 0x58bad47711113aea5bc5de02bce6dd332211aabb
_to: 0x62bec9abe373123b9aabbcce608f94eb8644163e00
_value: 2048

我们看到两个变化,第一目标地址变了,第二转移的数值变了:4<<8 = 2048。
这个就是ERC20 Short Address Attack。

怎么利用?

  1. 攻击者构建一个最后一个字节为0的地址A。
  2. 攻击者找到一个发行token的智能合约,在这个智能合约里面,向A存入500token。
  3. 攻击者从智能合约转出500token到地址A,但是将地址A最后一个字节的0去掉。
  4. 地址A最后1个字节会被补全,而转账的500token就变成了500<<8。

攻击防范

防范起来其实很简单,做好必要的参数校验即可。

下面的代码加了一个modifier onlyPayloadSize 。 在这个modifier里面,我们做了参数长度的校验。

pragma solidity ^0.4.11;contract MyToken {
mapping (address => uint) balances;event Transfer(address indexed _from, address indexed _to, uint256 _value);function MyToken() {
balances[tx.origin] = 10000;
}modifier onlyPayloadSize(uint size) {assert(msg.data.length == size + 4);_;}function sendCoin(address to, uint amount) onlyPayloadSize(2 * 32) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
return true;
}function getBalance(address addr) constant returns(uint) {
return balances[addr];
}
}

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多教程请参考flydean的博客

ERC20 Short Address Attack相关推荐

  1. ERC20接口下USDT代币的深入解析

    ERC20代币合约规则简介 ERC20 是各个代币的标准接口.ERC20 代币仅仅是以太坊代币的子集,为了充分兼容 ERC20,开发者需要将一组特定的函数(接口)集成到他们的智能合约中,以便在高层面能 ...

  2. 以太坊智能合约安全入门了解一下(下)

    作者:RickGray 作者博客:http://rickgray.me/2018/05/26/ethereum-smart-contracts-vulnerabilities-review-part2 ...

  3. 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新

    文章目录 简介 什么是区块链 区块链不是什么 区块链的基础:密码学 区块链的基础:分布式系统和共识机制 超级账本Hyperledger 以太坊 Libra 比特币 总结 简介 区块链是一种防篡改的共享 ...

  4. usdt智能合约代码

    以太链usdt智能合约代码 /***Submitted for verification at Etherscan.io on 2017-11-28 */pragma solidity ^0.4.17 ...

  5. 区块链100讲:智能合约审计指南

    智能合约代码的审计,目前还不是技术社区内经常会讨论的主题.今年3月6日,发表在博客网站[Schneier on Security]上的一篇博客(原文链接:[https://www.schneier.c ...

  6. How to Secure Your Smart Contracts: 6 Solidity Vulnerabilities and how to avoid them (Part 2)

    While Part 1 discussed some more high profile or obvious vulnerabilities, this post will be about vu ...

  7. 区块链相关安全名词及常见攻击手法

    钱包 Wallet 钱包(Wallet)是一个管理私钥的工具,数字货币钱包形式多样,但它通常包含一个软件客户端,允许使用者通过钱包检查.存储.交易其持有的数字货币.它是进入区块链世界的基础设施和重要入 ...

  8. 【智能合约系列009-如何做智能合约审计?】

    研究报告[Finding The Greedy, Prodigal, and Suicidal Contracts at Scale])指出,目前在以太坊中,有89%的智能合约代码都或多或少存在安全漏 ...

  9. 以太坊智能合约安全入门了解一下(上)

    作者:RickGray 作者博客:http://rickgray.me/2018/05/17/ethereum-smart-contracts-vulnerabilites-review/ (注:本文 ...

最新文章

  1. 分类家族:二分类、多分类、多标签分类、多输出分类
  2. context:annotation-config / 和context:component-
  3. php 验证微信token_php之微信公众号验证token获取access_token
  4. SpringBoot系列: 使用 flyway 管理数据库版本
  5. SQLServe错误整理
  6. Java番外篇2——jdk8新特性
  7. 扫地机器人什么牌子好?2021最新扫地机器人排行榜
  8. 2.4 shell 脚本基础
  9. zip命令通过yum安装和使用方法
  10. Linq级联删除 CascadingDeleteOnSubmit
  11. matlab%低通滤波器设计,用Matlab及C语言实现低通滤波器的设计
  12. Python—基于百度AI的人脸识别检索程序(转自本人博客)
  13. 重点分析!转型中的好莱坞发生了哪些变局?
  14. JumpServer登录提示连接WebSocket失败
  15. Chrome安装HttpWatch
  16. css svg做动图,用svg动态绘制图形
  17. ADC(一)—AD7683/AD7684/ADS8317
  18. 一台服务器支持多个域名和站点
  19. 【NOIP模拟】序列
  20. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘emp

热门文章

  1. linux源码安装必备条件,玩转Linux必备的金钥匙之源码安装mysql
  2. 在阿里云服务器上安装docker
  3. Timus1430(裴蜀定理应用)
  4. 关于丢番图方程x^2-dy^2=-1
  5. 二项式反演[bzoj3622]已经没有什么好害怕的了
  6. PTA 判断对称矩阵 (10分)
  7. Ollydbg中断方法浅探
  8. 互斥体CMutex的使用
  9. LiveVideoStack冬季招聘(高级策划编辑,市场BD主管)
  10. 云开发如何帮助业务扛过大流量活动洪峰丨深度好文