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 接 ...
随机推荐
- SpringBoot 配置Redis
application.properties 文件内容 #Redis数据库索引(默认为0) spring.redis.database=0 #Redis服务器地址 spring.redis.host= ...
- 每日一练之排序算法(P1097 统计数字)
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5×10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. ...
- 二.第一个自动化demo,打开APP-如何获取包名和activity。(真机)
环境配置成功后,我们就可以进行第一个自动化测试了.用真机则不需要安装安卓模拟器.以一个简单的打开APP为例. 一.获取包名和activtity 启动一个app,我们需要知道它的平台.版本号. ...
- mac下新建txt文本快捷方式.md
转:127.0.0.1:47873/help/0-436/ms.help?method=page&id=A38C5670-BA28-44F3-BD5B-FCB46880E904&pro ...
- mysql学习一 常用语句
操作系统为windows 1 启动关闭mysql服务 //windows mysqld --console //开启mysql服务 mysqladmin -uroot shutdown //关闭my ...
- jQuery之animate中的queue
queue.dequeue clearQueue 清空 用队列完成之前动画的操作:
- python+Django+test 测试数据库生成报错
前提: 使用Django自带的test进行单元测试. 问题描述: 运行:python manage.py test,报错,出现数据库乱码的现象,报错如下: Creating test database ...
- Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.4.1:clean (default-clean) on project
在maven项目中 启动了2个tomcat,只能启动一个.
- netty(七) Handler的执行顺序
Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码.拦截指定的报文.统一对日志错误进行处理.统一对 ...
- Python·——进程1
1.进程背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序(的一个抽象). 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统 ...