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存在漏洞的更多相关文章

  1. 一步步教你创建自己的数字货币(代币)进行ICO

    本文从技术角度详细介绍如何基于以太坊ERC20创建代币的流程. 写在前面 本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 ...

  2. 央行辟谣未发行“DC/EP”和“DCEP” 法定数字货币仍在测试阶段

    http://www.sohu.com/a/354709423_100157595 近期,中国央行再度就法定数字货币发布公告,指出目前系统仍处于研究测试过程中,市场上交易“DC/EP”或“DCEP”均 ...

  3. BotVS数字货币现货交易类库

    以下是BotVS数字货币现货交易类库模板,使用Python2语言实现 import types # 导入类型模块 import time # 导入时间模块 import platform # 版本信息 ...

  4. 世界各国货币,C#数字货币计算

    货币 CCY(Currency)本质上是一种所有者与市场关于交换权的契约,根本上是所有者相互之间的约定.吾以吾之所有予市场,换吾之所需,货币就是这一过程的约定,它反映的是个体与社会的经济协作关系.货币 ...

  5. 全球数字货币交易所TOP20安全性评级报告

      链塔智库2018-05-03 10:28 分析师:常昊.王婧雯    来源: 链塔智库 全球加密数字货币市值超2.5万亿元,单日交易额超2000亿元,全球超过3000万人已投入加密数字货币领域. ...

  6. G20峰会将会给数字货币带来哪些影响?

    G20峰会对于全球经济有着举足轻重的影响,其成员人口占全球的2/3,国土面积占全球的60%,国内生产总值占全球的90%,贸易额占全球的75%……作为国际经济合作的主要平台,G20在引领和推动国际经济合 ...

  7. 【课程笔记】比特币和数字货币技术[Bitcoin and Cryptocurrency Technologies] week1

    源地址(可能要FQ):https://www.coursera.org/learn/cryptocurrency/home/welcome 1.1 Cryptographic Hash Functio ...

  8. PAY8 数字货币支付结算系统,全球付!实时结算!秒到账!

    数字货币支付是历史发展的必然 如今已经有越来越多的地方接受加密数字货币作为支付消费了,比如泰国电影院连锁店 Cineplex Group 可用加密货币买爆米花和电影票,西班牙一精品酒店接受数字货币支付 ...

  9. [币严区块链]数字货币交易所之瑞波(XRP)钱包对接

    对接Ripple(XRP),不需要本地部署钱包,直接访问Ripple API,本文包括访问Ripple API及如何免费获取测试的XRP. 对接流程 安装Ripple API Ripple API 接 ...

随机推荐

  1. JVM内存模型和面试题解析

    一.JVM运行时区域 其中, 线程私有的:程序计数器,虚拟机栈,本地方法栈 线程共享的:堆,方法区,直接内存 1 程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示 ...

  2. js常用身份校验规则

    js常用身份校验规则 var Validator = { extractBirth: function(id) { // 身份证提取出生年月 var re = null, split, year, m ...

  3. 关于Ajax异步请求(实时刷新)

    1.需求:想要做成动态实时刷新获取数据库的值 2.例子 3.代码逻辑: <script type="text/javascript"> var Seconds=1000 ...

  4. MATLA总结三

    1.将分数表示转换为小数表示: vpa( ******(表达式或者变量), n(小数点后几位)) 2.将一个式子中的变量带入具体的值: subs(  y, x, [2,3,4] ) 3.用工具箱确定阶 ...

  5. .net WCF简单练习

    之前一直没接触过WCF这个东西,由于是初学WCF没有深入研究其原理,只是写了一个demo WCF服务用于两个不同项目中的调用,在这里我举例项目A调用WCF服务实现查询数据功能. 第一步:创建数据库,有 ...

  6. c3p0数据源的第一次尝试

    开始补习 以前学习过的基础 正在尝试从c3p0 获取到connection 好的,首先上代码吧 public static DataSource ds = null; static { ComboPo ...

  7. SQLServer “无法对数据库'XXX' 执行删除,因为它正用于复制”的解决方法

    “无法对数据库'XXX'执行删除,因为它正用于复制” 解决办法: 执行  sp_removedbreplication 'XXX'  这个语句的解释是:从数据库中删除所有复制对象,但不更新分发服务器上 ...

  8. 盒子模型(Box Model)

    盒子模型(Box Model) ■ 盒子模型——概念 在网页设计中常用的属性名:内容(content),填充(padding),边框(border),边界(margin),CSS 盒子模式都具备这些属 ...

  9. LogXGEController: Error: XGE version 8.01 (build 1867) or higher is required for XGE shader

    找到Engine/Config/ConsoleVariables.ini 禁用XGEShaderCompile就可以了

  10. visual studio vode 汉化

    在vs code 的商店中搜索Chinese,找到如下模块,安装. 安装后,按下ctrl+shift+p,找到configure display language ,点击进入,修改 改成如图字母就可以 ...