ERC20数字货币ProxyOverflow存在漏洞
ERC20的ProxyOverflow漏洞造成影响广泛,本文将对其攻击方法进行分析,以便于智能合约发布者提高自身代码安全性以及其他研究人员进行测试。本文选择传播广泛、影响恶劣的SMT漏洞(CVE-2018–10376)作为样本进行分析,文中所涉及的代码截图均来自于SMT代码。由于目前各大交易平台已经将ERC20协议的数字货币交易叫停,本文的发布不会对这些货币带来直接影响。
1 ERC20货币及transferProxy函数
1.1 ERC20货币简介
基于ERC20协议的数字货币(以下简称为ERC20货币)实际上是以太坊上运行的智能合约,合约中对于每个账户拥有的货币数目是通过 账户地址→货币数 的映射关系进行的记录:
mapping (address => uint256) balances
ERC20货币的拥有者要想进行货币交易、余额查询等操作时,需要向智能合约对应的地址发送消息,声明调用的函数和相应参数。这一消息将会矿机接收,并执行智能合约中相应的函数代码。在这一过程中,消息发送者需要向挖矿成功的矿机支付相应的报酬。这笔报酬在以太坊中被称作gas,其支付货币为以太币。也就是说,ERC20的货币拥有者要想发送货币交易消息,就需要拥有一定数量的以太币。
然而,ERC20货币拥有者并不一定拥有以太币。为了满足他们发起货币交易的需求,ERC20 协议提供了transferProxy函数。利用该函数,ERC20货币拥有者可以签署一个交易消息,并交由拥有以太币的第三方节点将其发送到以太坊上。消息的发送者会从拥有者那里获取一定数量的ERC20货币作为其发送消息的代理费用。
1.2 transferProxy函数代码分析
SMT的transferProxy函数代码如下图所示:

该函数的各个参数解释如下,该函数代码逻辑较为简单,此处不做赘述。
- address _from:ERC20 货币的拥有者和交易的发起者;
- address _to:货币交易中的接收者;
- uint256 _value:货币交易的数额;
- uint256 _feeSmt:交易信息发送者(即函数中msg.sender)收取的代理费用;
- uint _v,bytes32 _r,bytes32 _s:交易发起者(即_from)生成的签名数据。
需注意的是,代码215行中的transferAllowed(_from)是transferProxy()运行前必会运行的验证函数。该函数代码如下:
代码117行中的exclude为映射结构,仅合约的创建者将为设置为True,其他地址默认均为False。
代码118行判定transferEnabled标志符是否为true,该标志只能通过enableTransfer函数设定,且该函数只能被合约创建者调用,该函数的作用是使得ERC20合约的交易过程可控,这也是SMT等货币出现问题时能够在后续中止交易的原因:


代码119-121行对于交易发送者(即_from)帐号是否被锁定进行了检查,lockFlag和locked都只能被合约创建者所控制:


综上所述,只有整个合约在允许交易且攻击者帐号未被锁定的情况下,攻击者才能真正调用transferProxy函数。在参数处理过程中发生漏洞的原因可参见我们之前的分析文章:https://weibo.com/ttarticle/p/show?id=2309404232782242012923。
2 攻击重现
为了重现攻击,我们选择了基于go语言编写的以太坊客户端geth进行以太坊私有网络的部署。为了便于实现可编程的自动化交互,我们选择了Web3.py作为与以太坊节点交互的中间件。
2.1 漏洞验证环境的搭建
S1. 从链接页面下载SMT智能合约源码;
S2. 创建两台Linux虚拟机;
S3. 准备Python运行环境,在两台虚拟机上安装python3,并利用pip安装web3、py-solc、hexbytes、attrdict;
S4. 准备合约编译环境,在两台虚拟机上安装智能合约代码编译器solc,参考链接;
S5. 在两台虚拟机上搭建以太坊私有网络,可参考链接,其中:
— 1) 节点1用于发布SMT合约代码,为其创建以太坊账户并分配一定数量以太币,启动挖矿;
— 2) 节点2用于部署攻击代码,创建两个以太坊账户,分别作为transferProxy中的from账户(转账消息签署者,记为Signer)和transferProxy调用者(即转账消息的发送者,记为Sender),为Sender分配一定数量以太币,并启动挖矿。
2.2 SMT智能合约发布
在节点1上,利用deploy_SMT.py脚本中的代码实现SMT智能合约的一键部署。
关于执行前的配置的介绍:
1) sol_path,代表合约代码路径;
2) account,代表用于发布合约的账户,如1.2所示,只有该账户才能调用部署好的智能合约函数,进行控制交易开启和关闭,维护被锁账户列表等操作;
3) pin,用于解锁account的密码。
关于执行过程与结果的分析:
1) tx_receipt,该变量用于获取部署智能合约(23行)和发送启动交易消息(35行)的结果,当这两行代码被调用后,以太坊网络中会发布相应的消息,只有在下一个区块被挖掘出来后,tx_receipt才能获取非空的结果;
2) contract_address,代表该合约被顺利部署到以太坊网络后的合约地址,其他节点要想调用合约代码,需要获知该地址以便发送函数调用消息。
合约代码部署结果的截图如下:

2.3 ProxyOverflow漏洞攻击
在节点2上,利用test_SMT.py脚本中的代码可实现针对SMT合约的一键攻击。
关于执行前的配置的介绍:
1) contract_address,来自2.2中SMT部署完成后的输出值;
2) sol_path,代表合约代码路径;
3) signer,交易信息的签署者,也将作为调用transferProxy时的_from和_to的实参;
4) sender,交易信息的发送者,需要拥有一定数量以太坊以支付gas费用;
5) signer_pin,signer的密钥解锁口令,以便对交易信息进行签名;
6) sender_pin,sender的密钥解锁口令,以便解锁sender账户,支付gas费用;
7) value,代表发生交易的金额;
8) fee,代表支付给sender的代理费用;
9) signer_key_path,代表signer的密钥文件路径。
关于执行过程与结果的分析:
1) 30-35行,基于目标智能合约地址和代码,创建智能合约对象;
2) 37-38行,获取并打印sender和signer在攻击前的SMT币数目;
3) 40-43行,获取signer现有的nonce的值,并将其扩充为64字符的字符串;
4) 46-62行,构建要进行签名的数据的Hash值,获取signer的私有密钥,并对Hash值进行签名,获得签名数据s,r,v;
5) 63-77行,构造transferProxy函数调用参数,进行函数调用,并获取交易回执;
6) 79-80行,获取并打印sender和signer在攻击后的SMT币数目。
攻击结果的截图如下:
ERC20数字货币ProxyOverflow存在漏洞的更多相关文章
- 一步步教你创建自己的数字货币(代币)进行ICO
本文从技术角度详细介绍如何基于以太坊ERC20创建代币的流程. 写在前面 本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 ...
- 央行辟谣未发行“DC/EP”和“DCEP” 法定数字货币仍在测试阶段
http://www.sohu.com/a/354709423_100157595 近期,中国央行再度就法定数字货币发布公告,指出目前系统仍处于研究测试过程中,市场上交易“DC/EP”或“DCEP”均 ...
- BotVS数字货币现货交易类库
以下是BotVS数字货币现货交易类库模板,使用Python2语言实现 import types # 导入类型模块 import time # 导入时间模块 import platform # 版本信息 ...
- 世界各国货币,C#数字货币计算
货币 CCY(Currency)本质上是一种所有者与市场关于交换权的契约,根本上是所有者相互之间的约定.吾以吾之所有予市场,换吾之所需,货币就是这一过程的约定,它反映的是个体与社会的经济协作关系.货币 ...
- 全球数字货币交易所TOP20安全性评级报告
链塔智库2018-05-03 10:28 分析师:常昊.王婧雯 来源: 链塔智库 全球加密数字货币市值超2.5万亿元,单日交易额超2000亿元,全球超过3000万人已投入加密数字货币领域. ...
- G20峰会将会给数字货币带来哪些影响?
G20峰会对于全球经济有着举足轻重的影响,其成员人口占全球的2/3,国土面积占全球的60%,国内生产总值占全球的90%,贸易额占全球的75%……作为国际经济合作的主要平台,G20在引领和推动国际经济合 ...
- 【课程笔记】比特币和数字货币技术[Bitcoin and Cryptocurrency Technologies] week1
源地址(可能要FQ):https://www.coursera.org/learn/cryptocurrency/home/welcome 1.1 Cryptographic Hash Functio ...
- PAY8 数字货币支付结算系统,全球付!实时结算!秒到账!
数字货币支付是历史发展的必然 如今已经有越来越多的地方接受加密数字货币作为支付消费了,比如泰国电影院连锁店 Cineplex Group 可用加密货币买爆米花和电影票,西班牙一精品酒店接受数字货币支付 ...
- [币严区块链]数字货币交易所之瑞波(XRP)钱包对接
对接Ripple(XRP),不需要本地部署钱包,直接访问Ripple API,本文包括访问Ripple API及如何免费获取测试的XRP. 对接流程 安装Ripple API Ripple API 接 ...
随机推荐
- web跨域问题(No 'Access-Control-Allow-Origin'..)
1. 问题 angular开发中连接java服务时出现跨域问题(No 'Access-Control-Allow-Origin'..). 如下图 解决方法 2,原因分析 这个与安全机制有关,默认情况下 ...
- 记一次monolog的RotatingFileHandler使用
需求如下: 1.需要一种日记格式,能把同一次请求的日记归在一起,请求间的日记以空行隔开,即使并发操作也不会像laravel默认的日记一样很"被动"的记录(不同请求的日记可能被交替记 ...
- 算法之Python实现 - 003 : 换钱的方法数
[题目]给定数组arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的方法数. [代码1]递归 impor ...
- phxpaxos遇到反复拉取checkpoint但是反复失败的问题,给其它节点造成压力
原因: 接收checkpoint时与接收普通message共用IOLoop中的队列,当遇到队列满或者超内存时,会造成checkpoint的包随机丢失的问题 解决办法: 遇到checkpoint时不丢弃 ...
- Docker Got permission denied while trying to connect to the Docker daemon socket at unix://
这是没有权限的原因,先将自己加入docker组,然后在重新启动就可以了, 下面参考来源:https://blog.csdn.net/weixin_40896352/article/details/80 ...
- 微信小程序:request合法域名检验出错,https://apis.map.qq.com 不在以下 request 合法域名列表中
设置域名 登录微信小程序后台, 设置→开发设置→服务器设置 必须设置域名,微信小程序才能进行网络通讯,不然会报错 如果没有设置合法域名,在开发阶段是可以不设置合法域名的 详情 -项目设置 好了,完美解 ...
- C语言典型编程2
关于C的一些小而精的编程,适合希望提升编程能力的初学者学习:关键编程也就几句,但思维可以迁移到其他编程语言.同一问题,算法多种. //任意整数的任意次方取后3位(算数取位)#include<st ...
- 阿里云单机快速部署K8S
网上有很多关于K8S部署测试环境的文章,但是有些部署比较繁琐.这里推荐使用 https://github.com/gjmzj/kubeasz地址文章.文章介绍很详细,记录一下方便自己日后学习使用. # ...
- Java框架spring 学习笔记(二):Bean的作用域
Spring 框架Bean支持以下五个作用域: 下面介绍两种作用域,singleton和protoype singleton作用域 singleton作用域为默认作用域,在同一个ioc容器内getBe ...
- 解题(Solution -4Sum)
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...