区块链安全 - DAO攻击事件解析
作者:隐形人真忙
作者博客: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 < paidOut[_account]) throw; uint reward = (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account]; if (!rewardAccount.payOut(_account, reward)) //vulnerable throw; paidOut[_account] += reward; return true;
}
这里调用了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。可见,区块链领域的安全不容忽视,因为其修复难度和所造成的影响都很高,毕竟是和钱打交道。
区块链安全 - DAO攻击事件解析相关推荐
- 区块链51%双花攻击
复习一下 区块链是啥? 区块链是分布式数据存储,点对点传输,共识机制,加密算法的计算机技术的新型应用模式,区块链本质上是一个去中心化的数据库. 简单一点来讲,家里有个账本,由你来记账,爸爸妈妈把工资交 ...
- 【金融科技前沿】区块链和数字经济(区块链的缘起,现状和发展、区块链技术架构和原理解析 、区块链应用和案例综述)
1.缘由 前段时间微众银行的区块链首席架构师张开翔老师给我们上了一堂近三小时的课,与其说是在上课,不如说是一场思想的享受.开翔老师跟我们学院联系挺密切的,之前比赛也见过他,我印象中他一直是一位顶级的技 ...
- 独家 | Fomo 3D 沦陷?为何又是 DDoS攻击?来听听区块链安全大牛的深度解析
自7月8日,一款运行在以太坊上的带有明显博弈性质的区块链游戏火了,这是继EOS-RAM之后,又一个用惊人收益刷新着我们认知的"新物种",它就是Fomo 3D. 然而就在昨天,网 ...
- 区块链数据存在哪里?解析区块链数据存储和安全性
区块链是一个去中心化的分布式账本系统,是一种新型的数字资产管理方式.区块链的本质是由一系列区块组成的链式结构,每个区块中都包含了一些数据.那么,区块链数据存在哪里呢?下面将对区块链数据的存储和安全性进 ...
- 研究人员探索了对以太坊区块链的日食攻击
eclipse攻击是对区块链的网络级攻击,攻击者基本上控制了对等网络,模糊了节点对区块链的视图. 波士顿大学副教授Sharon Goldberg在一篇题为"低资源Eclipse攻击以太的点对 ...
- td不允许自己扩展_V神原文详解:通过及时性检测器(TD)解决区块链的51%攻击问题...
注:原文作者是以太坊联合创始人Vitalik Buterin,在这篇文章中,他提出了一种称为及时性检测器(TD)的构造,以试图解决区块链51%攻击的问题. (图:Vitalik Buterin) 以下 ...
- 浅谈最近流行的三起区块链51%算力攻击
很多人可能早就听说过 51% 算力攻击,但更多的可能源于各种媒体渠道中"比特币的缺陷"文章之流.实际上,这个说法并不准确,根据比特币百科上所描述,这种攻击被称为多数人的攻击(Maj ...
- 【年终盘点之二】2020 区块链创新项目里程碑事件
1990 年代,计算机科学家 Nick Szabo 首次提出智能合约概念.简单说,智能合约指的是将各方所做出的承诺,以数字形式写入程序,让参与者在遵循这些承诺的前提下,进行互动.在区块链出现之前,最接 ...
- 「万向区块链专家观点」深度解析“区块链+物联网”与新基建
本文从属于万向区块链"融合创新"系列行业研究报告,作者为万向区块链首席经济学家邹传伟博士. 2020年10月27日至28日,万向区块链实验室将主办主题为"融合创新&quo ...
最新文章
- matlab 变参数 方程组,解带参数方程组 运行结果竟然自己带了新参数z
- Python 入门篇-最新版python3.7.2的安装。
- 一文让你明白Redis持久化 1
- Mysql之删除表中数据_DELETE FROM
- 网上商城首页实现总结(一)
- ELK学习总结(1-1)ELK是什么
- msf:Known bug in WMI query, try migrating to another process
- 三星Galaxy S21 FE即将量产:8月登场 小屏满血旗舰!
- VB 更换设置桌面背景图片函数
- matlab绘制二元函数,matlab绘制二元函数z=x∧2+y∧2,y=0,y=x∧2,z=0的图像
- 143_iOS干货50_认识几个概念:跨域问题和内网穿透
- Java聊天室——一对一模式
- 虾皮物流好不好SLS 异常件怎么处理?
- Java使用openOffice转PDF以及PDF文件预览乱码问题
- jmap命令(Java Memory Map)
- 《实践论》、《矛盾论》
- 张果老能是鸿蒙时期一蝙蝠,历史书中张果老的故事,一只蝙蝠的传奇
- 一道对10年间中国行政区划个数进行对比的Python考试题
- linux博通bcm4313无线网卡,Debian中配置broadcom bcm43XX无线网卡
- python等值面追踪_等值线的追踪算法(1)
热门文章
- Mac怎么终端配置mysql_mysql mac怎么在终端安装
- 电脑摄像头未能创建连接服务器,Win7摄像头提示"未能创建视频预览"的原因及解决方法...
- C语言各种排序算法(冒泡排序、快速排序、插入排序、希尔排序、快速排序、 归并排序)
- android 动态单选,添加单选按钮动态︰android
- c语言int超出范围溢出处理_整数溢出是怎么回事?Python和Numpy的整数为何不一样?...
- html5 上海,【上海校区】HTML5新特性
- JNI调用两层C++动态库
- Joseph_Circle(约瑟夫环)
- 利用HUtool读取Excel内容
- EF+MVC+Bootstrap 项目实践 Day11