欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

以太坊 “后偷渡时代” 盗币之 “拾荒攻击”

来源:本站整理 作者:佚名 时间:2018-08-20 TAG: 我要投稿

2018年08月01日,知道创宇404区块链安全研究团队发布《金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘》,针对 偷渡漏洞 和 后偷渡时代的盗币方式 进行了介绍,披露了 后偷渡时代 的三种盗币方式:离线攻击、重放攻击和爆破攻击。
在进一步的研究中,我们又发现了针对这些攻击方式的补充:拾荒攻击。攻击者或求助于矿工,或本身拥有一定算力以获得将交易打包进区块的权利。在偷渡漏洞中,攻击者在被攻击节点构造gasPrice 为 0 的交易,等待用户解锁账户签名广播。攻击者同时设置一个恶意节点,用于接收这笔交易。攻击者将符合条件的交易打包,就可以实现 0 手续费完成转账。通过这种攻击,攻击者可以获取到余额不足以支付转账手续费或勉强足够支付手续费节点上的所有以太币,并在一定程度上可以防止其他攻击者的竞争,可谓是 薅羊毛 的典范。
除此之外,在薅够以太币残羹之后,攻击者又盯上了这些以太币已被盗光,但账户中残留的代币。直到现在,针对许多智能合约发行的代币,一些被攻击账户中的token,仍在小额地被攻击者以拾荒攻击盗走。
本文将从一笔零手续费交易谈起,模拟复现盗币的实际流程,对拾荒攻击成功的关键点进行分析。
 
0x01 从一笔零手续费交易谈起
在区块链系统中,每一笔交易都应该附带一部分gas以及相应的gasPrice作为手续费,当该交易被打包进区块,这笔手续费将用来奖励完成打包的矿工。
在《金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘》中,我们提到了一个利用以太坊JSON-RPC接口的攻击者账号0x957cD4Ff9b3894FC78b5134A8DC72b032fFbC464。该攻击者在公网中扫描开放的RPC端口,构造高手续费的交易请求,一旦用户解锁账户,便会将用户余额转至攻击者的账户或攻击者创建的合约账户。
在分析该账户交易信息的时候,我们发现了一笔不符合常识的交易,先从这笔交易开始谈起。
交易地址:0xb1050b324f02e9a0112e0ec052b57013c16156301fa7c894ebf2f80ac351ac22
Function: transfer(address _to, uint256 _value)MethodID: 0xa9059cbb[0]:  000000000000000000000000957cd4ff9b3894fc78b5134a8dc72b032ffbc464[1]:  000000000000000000000000000000000000000000000000000000000abe7d00
从0x00a329c0648769a73afac7f9381e08fb43dbea72向合约MinereumToken(攻击者的合约)的交易,虽然用户余额很少,但这笔交易使用了该账户所有余额作为value与合约交互,这笔交易使用了正常数量的gas,但它的gasPrice被设定为0。
前文提到,攻击者会使用较高的手续费来保证自己的交易成功,矿工会按照本节点的txpool中各交易的gasPrice倒序排列,优先将高gasPrice交易打包进之后的区块。在这个世界上每时每刻都在发生着无数笔交易,在最近七日,成交一笔交易的最低gasPrice是3Gwei。这笔零手续费交易究竟是如何发生,又是如何打包进区块的呢。
 
0x02 思路分析
在区块链系统中,任何人都可以加入区块链网络,成为其中一个节点,参与记账、挖矿等操作。保证区块链的可信性和去中心化的核心便是共识机制。
共识机制
在以太坊中,矿工将上一区块的哈希值、txpool中手续费较高的交易、时间戳等数据打包,不断计算nonce来挖矿,最先得出符合条件的nonce值的矿工将拥有记账权,得到手续费和挖矿奖励。矿工将广播得到的区块,其他节点会校验这一区块,若无错误,则认为新的区块产生,区块链高度增加。这就是各节点生成新区块保持共识的过程。
将0 gasPrice交易完成需要确认两个问题
下面我们来对0 gasPrice交易相关的操作进行测试。了解零手续费的交易如何产生,如何被txpool接受,打包了零手续费交易的区块能否被认可,确认上述问题的答案。
 
0x03 零手续费交易测试
a. 单节点测试
首先,我们来确认此交易是否可以进入节点的txpool中,启用一个测试链。默认rpc端口是8545,使用python的web3包发起一笔0 gasPrice转账。
geth --networkid 233 --nodiscover --verbosity 6 --ipcdisable --datadir data0 --rpc --rpcaddr 0.0.0.0 console
节点一发起转账的脚本,转帐前要解锁账户
from web3 import Web3, HTTPProviderweb3 = Web3(HTTPProvider("http://localhost:8545/"))print(web3.eth.accounts)# 转帐前要解锁账户web3.eth.sendTransaction({
    "from":web3.eth.accounts[0],
    "to":web3.eth.accounts[1],
    "value": 10,
    "gas":21000,
    "gasPrice":0,
    })
交互结果
> txpool.content
{
  pending: {},
  queued: {}
}
> eth.getBalance(eth.accounts[0])
800000000
> personal.unlockAccount(eth.accounts[0],'sissel')
true
> INFO [08-14|11:20:14.972] Submitted transaction                    fullhash=0x72e81751d2517807cabad24102d3cc2f0f4f2e8b92f1f106f1ee0bf6be734fe4 recipient=0x92636b228148e2824cB8d472Ef2F4e76f2F5059C
> txpool.content
{
  pending: {
    0x092fda221a114FA702e2f59C217C92cfEB63f5AC: {
      3: {
        blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        blockNumber: null,
        from: "0x092fda221a114fa702e2f59c217c92cfeb63f5ac",
        gas: "0x5208",
        gasPrice: "0x0",

[1] [2] [3] [4] [5]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载