热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

区块链安全DAO攻击事件解析

作者:隐形人真忙作者博客:http:blog.csdn.netu011721501articledetails794501220x00前言最近关注了

作者:隐形人真忙
作者博客:http://blog.csdn.net/u011721501/article/details/79450122


0x00 前言

最近关注了一下区块链方面的安全,因此翻出来之前的DAO攻击事件研究了一番,形成此文。

之后可能还会发一些其他的安全分析文章。


0x00 基础知识


1.跨合约调用

智能合约之间的调用本质上是外部调用,可以使用message call或者创建智能合约对象的形式进行调用。

(1)使用message call

比如合约1调用合约2的某个方法:

bytes4 methodId = bytes4(keccak256("increaseAge(string,uint256)"));
return addr.call(methodId,"jack", 1);

(2)还原智能合约对象 如果已知合约的地址,可以通过如下方式获取到合约对象:

Contract1 c = Contract1(AddressOfContract1) ;
c.foo() ; //跨合约调用

2.智能合约发送ETH

我们可以在智能合约中用代码向某个地址(这个地址可以是人,也可以是智能合约)发送以太币,比较常见的两个方式是:

(1)调用send函数

比如:msg.sender.send(100)

(2)使用message call

msg.sender.call.value(100)()

这两个方式不同的是发送的gas数量,gas就是执行opcode需要花费的一种币,称作为gas也特别形象。当调用send方法时,只会发送一部分gas,准确地来讲,是2300gas,一旦gas耗尽就可能抛出异常。

而使用message call的时候,则是发送全部的gas,执行完之后剩余的gas会退还给发起调用的合约。


3.fallback函数

智能合约中可以有唯一的一个未命名函数,称为fallback函数。该函数不能有实参,不能返回任何值。如果其他函数都不能匹配给定的函数标识符,则执行fallback函数。

当合约接收到以太币但是不调用任何函数的时候,就会执行fallback函数。如果一个合约接收了以太币但是内部没有fallback函数,那么就会抛出异常,然后将以太币退还给发送方。

下面就是一个fallback函数的代码示例:

contract Sample{ function () payable{ // your code here }
}

一般单纯使用message call或者send函数发送以太币给合约的时候,没有指明调用合约的某个方法,这种情况下就会调用合约的fallback函数。


0x01 攻击事件还原

我们先用简单的模拟代码来了解下整个攻击过程。

首先是存在漏洞的智能合约代码,Bank:

用户可以通过addToBalance方法存入一定量的以太币到这个智能合约,通过withdrawBalance方法可以提现以太坊,通过getUserBalance可以获取到账户余额。

注意到这里是通过message call的方式来发送以太币,所以在调用sender的fallback函数的时候我们就会有充足的gas来进行循环调用。如果是send的方式,gas只有2300,稍微一操作就会耗尽gas抛出异常,是不够用来进行嵌套调用的。以下是不同操作所需要的gas数量:

出问题的是withdrawBalance方法,特别是在修改保存在区块链的balances的代码是放在了发送以太币之后。 攻击代码如下:

这里的deposit函数是往Bank合约中发送10wei。withdraw是通过调用Bank合约的withdrawBalance函数把以太币提取出来。注意看这里的fallback函数,这里循环调用了两次Bank合约的withdrawBalance方法。

攻击的过程如下:

(1)假设Bank合约中有100wei,攻击者Attack合约中有10wei
(2)Attack合约先调用deposit方法向Bank合约发送10wei
(3)之后Attack合约调用withdraw方法,从而调用了Bank的withdrawBalance方法。
(4)Bank的withdrawBalance方法发送给了Attack合约10wei
(5)Attack收到10wei之后,又会触发调用fallback函数
(6)这时,fallback函数又调用了两次Bank合约的withdrawBalance,从而转走了20wei
(7)之后Bank合约才修改Attack合约的balance,将其置为0

通过上面的步骤,攻击者实际上从Bank合约转走了30wei,Bank则损失了20wei,如果攻击者多嵌套调用几次withdrawBalance,完全可以将Bank合约中的以太币全部转走。


0x02 复现过程

给Bank合约100wei,给Attack合约10wei。

(1)部署Bank,分配100wei

(2)部署Attack

分配给Attack 10wei。

(3)调用Attack合约的deposit方法

(4)调用Attack合约的withdraw方法

(5)查看Attack合约的余额,变成了30wei,即窃取了20wei


0x03 DAO攻击事件代码分析

在DAO源码中,有withdrawRewardFor函数:

function withdrawRewardFor(address _account) noEther internal returns (bool _success) { if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply }

这里调用了payOut函数进行付款。

function payOut(address _recipient, uint _amount) returns (bool) { if (msg.sender != owner || msg.value > 0 || (payOwnerOnly && _recipient != owner)) throw; if (_recipient.call.value(_amount)()) { //vulnerable PayOut(_recipient, _amount); return true; } else { return false;
}

而payOut中直接使用的是message call的方式发送以太币,从而导致了嵌套漏洞。


0x04 总结

在编写智能合约进行以太币发送的时候,要使用send或者transfer,不要使用message call的方式,而send其实还是有些小问题,以后有时间再分析。DAO事件直接导致了以太坊硬分叉,分为ETH和ETC。可见,区块链领域的安全不容忽视,因为其修复难度和所造成的影响都很高,毕竟是和钱打交道。





推荐阅读
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 2018年在北航听陈博士讲解时,对重入漏洞有了初步了解。最近重温了慢雾科技的相关文章,发现他们对重入漏洞的解释非常清晰明了。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 2016-2017学年《网络安全实战》第三次作业
    2016-2017学年《网络安全实战》第三次作业总结了教材中关于网络信息收集技术的内容。本章主要探讨了网络踩点、网络扫描和网络查点三个关键步骤。其中,网络踩点旨在通过公开渠道收集目标信息,为后续的安全测试奠定基础,而不涉及实际的入侵行为。 ... [详细]
  • 如果程序使用Go语言编写并涉及单向或双向TLS认证,可能会遭受CPU拒绝服务攻击(DoS)。本文深入分析了CVE-2018-16875漏洞,探讨其成因、影响及防范措施,为开发者提供全面的安全指导。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 投融资周报 | Circle 达成 4 亿美元融资协议,唯一艺术平台 A 轮融资超千万美元 ... [详细]
author-avatar
谢超4444
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有