"Unchecked-Send"漏洞分析
author:sf197
tl;dr
国内并没有一个文档有讲述该漏洞的,正好闲着没事。就写下这篇文章。在网上也搜寻了一些资料,通过自己的翻译才有今天的这篇文章。该漏洞在DASP TOP
10中可以查看到。至于查看的资料,将会在文章末尾贴上。转载请注明作者及文章来源。
什么是“未检查发送”漏洞?
简洁来说,就是一个或多个Ether发送到其他地址时,其他合约拒绝,或发生错误时,会返回一个布尔值false,并且代码将会继续。
倘若未给这些返回值做检测,可能会造成意想不到的结果。
漏洞函数: call()、
callcode()、 delegatecall()、
send();
这里我们用send()函数做一次测试。
测试代码如下:
- pragma solidity ^0.4.19;
- contract test
- {
- bool etherLeft;
- mapping (address => uint256) balances;
- function Deposit(address addrs,uint256 _value)
- public
- payable
- {
- balances[addrs]+=_value;
- }
- function withdraw(address addr,uint256 _amount) public returns(bool
etherLeft) - {
- require(balances[addr] >= _amount);
- balances[addr] -= _amount;
- if(addr.send(_amount)){
- etherLeft = true;
- }else{
- etherLeft = false;
- }
- return etherLeft;
- }
- function balanceOf(address _owner) constant returns (uint256 balance) {
- return balances[_owner];
- }
- }
首先我们利用Deposit函数给自己合约地址充值,再利用send()向合约地址转账。
可以看到这里转账的结果是false
这里其实有个坑,官方给出send函数关联fallback函数是必须的!
- Contracts that receive Ether directly (without a function call, i.e. using
send or transfer) but do not define a fallback function throw an exception,
sending back the Ether (this was different before Solidity v0.4.0). So if you
want your contract to receive Ether, you have to implement a fallback
function.
换句话说,通过send,transfer这些函数转移代币的时候,若被接收方是合约的话,则该合约必须存在fallback函数
我们就正好利用这个情况,复现我们的未检测发送漏洞。
代码如下:
- pragma solidity ^0.4.19;
- contract test
- {
- mapping (address => uint256) balances;
- function Deposit(address addrs,uint256 _value)
- public
- payable
- {
- balances[addrs]+=_value;
- }
- function withdraw(address addr,uint256 _amount) public
- {
- require(balances[addr] >= _amount);
- addr.send(_amount);
- balances[addr] -= _amount;
- }
- function balanceOf(address _owner) constant returns (uint256 balance) {
- return balances[_owner];
- }
- }
上述代码进过修改后,写合约的人逻辑是,先转账_amount金额,再扣除自身这么多的金额。
然而并未在此做返回检查,致使下一行的balances[addr]
-=
_amount;代码继续执行。最终得到金额未转账成功,但余额中又被扣除的现象
先给合约地址充值10代币
再给自身合约转账5代币,由于没有fallback函数,转账会失败。
再去查询余额,竟然变成5代币
漏洞防御:
最主要的防御是尽量避免使用send函数,因为sand函数并不是一个相对安全的函数。如若要使用,可以参考以下几种方案:
(1)
- function withdraw(address addr,uint256 _amount) public returns(bool
etherLeft) - {
- require(balances[addr] >= _amount);
- if(addr.send(_amount)){
- balances[addr] -= _amount;
- etherLeft = true;
- }else{
- etherLeft = false;
- }
- return etherLeft;
- }
就是在发送的时候做个判断,这是对当前示例的适当修复,但有时它不是正确的解决方案。
(2)
我们可以定义一个宏,CaltSkasiSunType()
- function withdraw(address addr,uint256 _amount) public returns(bool
etherLeft) - {
- require(balances[addr] >= _amount);
- if(callStackIsEmpty()){
- addr.send(_amount)
- balances[addr] -= _amount;
- }else throw;
- return etherLeft;
- }
这种解决方案的唯一好处就是,通过CaltSkasiSunType()生成一个测试消息,来调用堆栈且当调用为堆栈为空的时,返回false。
详细文档请看:
http://hackingdistributed.com/2016/06/16/scanning-live-ethereum-contracts-for-bugs/#Listing4
http://www.dasp.co/#item-4
原文地址:http://www.rlsec.org/thread-22-1-1.html
"Unchecked-Send"漏洞分析的更多相关文章
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...
- 【漏洞分析】dedecms有前提前台任意用户密码修改
0x00 前言 早上浏览sec-news,发现锦行信息安全发布了一篇文章<[漏洞分析] 织梦前台任意用户密码修改>,看完之后就想着自己复现一下. 该漏洞的精髓是php的弱类型比较,'0. ...
- Apache Shiro Java反序列化漏洞分析
1. 前言 最近工作上刚好碰到了这个漏洞,当时的漏洞环境是: shiro-core 1.2.4 commons-beanutils 1.9.1 最终利用ysoserial的CommonsBeanuti ...
- thinkphp5.0.22远程代码执行漏洞分析及复现
虽然网上已经有几篇公开的漏洞分析文章,但都是针对5.1版本的,而且看起来都比较抽象:我没有深入分析5.1版本,但看了下网上分析5.1版本漏洞的文章,发现虽然POC都是一样的,但它们的漏洞触发原因是不同 ...
- SEIG Modbus 3.4 CVE-2013-0662 漏洞分析与利用
前言 Schneider Electric Modbus Serial Driver 会监听 27700 端口,程序在处理客户端发送的数据时会导致栈溢出. 测试环境: windows xp sp3 相 ...
- CVE-2018-18820 icecast 栈缓冲区越界写漏洞分析
前言 icecast 是一款开源的流媒体服务器 , 当服务器配置了 url 认证时,服务器在处理 HTTP 头部字段时错误的使用了 snprintf 导致栈缓冲区的越界写漏洞( CVE-2018-18 ...
- exim CVE-2017-16943 uaf漏洞分析
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这是最近爆出来的 exim 的一个 uaf 漏洞,可以进行远程代码 ...
- 一步一步 Pwn RouterOS之调试环境搭建&&漏洞分析&&poc
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 本文分析 Vault 7 中泄露的 RouterOs 漏洞.漏洞影 ...
- 抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析
PDF 版本下载:抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析 Author:知道创宇404实验室 Date:2017/03/19 一.漏洞背景 GoAhead作为世界上最 ...
- weblogic漏洞分析之CVE-2017-3248 & CVE-2018-2628
CVE-2017-3248 & CVE-2018-2628 后面的漏洞就是2017-3248的绕过而已,所以poc都一样,只是使用的payload不同 本机开启JRMP服务端 ->利用T ...
随机推荐
- html5 canvas 水平渐变描边
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 【整理】HTML5游戏开发学习笔记(4)- 记忆力游戏
1.预备知识(1)Canvas绘制多边形(2)Canvas绘制文字 2.实现思路涉及的对象 (1)场景Scene 场景代表了画布上的一块区域,场景里的每个物体都是场景里的一个元素,其绘制统一由场景 ...
- ARC 之内存转换
CHENYILONG Blog ARC 之内存转换 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilo ...
- Zookeeper笔记之命令行操作
$ZOOKEEPER_HOME/bin下的zkCli.sh进入命令行界面,使用help可查看支持的所有命令: 一.节点相关操作 create [-s] [-e] path data acl creat ...
- bash脚本:集群资源争夺战crazy-killer
背景 公司的集群很多人一起用,有时候就难免资源紧张,某次需要用的时候没资源等了半天还是没资源,再等半天还是没资源,于是就写了个脚本泄愤,建议看到的人拷走放在自己公司集群上长期运行 :) 实现 此脚本运 ...
- 转载 你不知道的super
http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...
- C++单链表反转
单链表反转笔记: #include<iostream> #include<string.h> using namespace std; struct ListNode { in ...
- @PostContruct注解
@PostContruct是spring框架的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法.
- spring-web.xml 模板
ssm模板 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:/ ...
- Codeforces 671A Recycling Bottles(贪心+思维)
题目链接:http://codeforces.com/problemset/problem/671/A 题目大意:给你两个人的位置和一个箱子的位置,然后给出n个瓶子的位置,要求让至少一个人去捡瓶子放到 ...