Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

Osiris Hunting for Integer Bugs in Ethereum Smart Contracts

0
0

发表会议:ACSAC’18

作者:Christof Ferreira Torres, Julian Schütte, Radu State

单位:SnT University of Luxembourg, Fraunhofer AISEC

论文链接: https://orbilu.uni.lu/bitstream/10993/36757/1/osiris.pdf

摘要

以去中心化的方式执行所谓的智能合约是当今区块链世界中一项令人激动的技术。智能合约通常是实现去中心化应用程序(DApp)业务逻辑的一段代码,管理着价值数千万美元的加密货币。然而,智能合约一旦被部署至区块链便无法被修改,如何有效的确定智能合约代码的正确性和安全性便成为了如今区块链安全研究的一个重要方向。

本文的研究重点是与整数错误(integer bugs)相关的安全漏洞,这类漏洞是由以太坊虚拟机与Solidity编程语言的一些特性而导致的,所以难以避免。文章针对这类漏洞提出了OSIRIS工具,该工具是一个将符号执行与污点分析相结合的漏洞检测框架,旨在精确地寻找以太坊智能合约中整数错误导致的安全漏洞。

1 介绍

开发者通常使用Solidity等高级语言编写智能合约,并将合约代码编译为EVM字节码部署执行。虽然Solidity与javascript、C等高级语言的语法相似,但是从根本上来说,智能合约的执行方式和安全属性都是与传统程序完全不同的。此外,由于缺少严格的静态检查和有限的开发工具支持,开发者编写的智能合约中极有可能存在致命的安全漏洞。

文章研究了智能合约中与整数错误相关的安全漏洞,并做出了如下贡献:

文章提出了OSIRIS工具,该工具针对EVM字节码自动化检测与整数错误相关的安全漏洞,目前覆盖了三种不同种类的整数错误:算术错误(arithmetic bugs),截断错误(truncation bugs)与符号错误(signedness bugs); 文章使用OSIRIS工具对截至2018年1月所有已经部署在以太坊区块链中的智能合约进行了自动化检测,发现其中有42,108个智能合约至少存在有一种上述与整数错误相关的安全漏洞; 文章将OSIRIS工具与ZEUS工具进行了比较,发现OSIRIS工具能够检测出更多的漏洞,并且具有低得多的误报率; 文章分析了495个以太坊代币智能合约并且在一些合约中发现了未知的安全漏洞; 文章针对与整数错误相关的安全漏洞提出了对EVM与Solidity编译器的修改防护方案。 2 背景 2.1 以太坊虚拟机

矿工使用以太坊虚拟机(EVM)执行智能合约,EVM是用于执行EVM字节码的基于栈的虚拟机。

2.2 Solidity编程语言

Solidity的语法虽然与C和JavaScript相似,但是Solidity存在一系列专门针对智能合约开发的独有概念。Solidity是静态类型语言,整数分为有符号整数与无符号整数,宽度最低为8bit,最高为256bit。然而在EVM中,所有的整数均以256bit大端补码的形式存放。也就是说,Solidity中的整数类型系统与EVM中的整数类型系统存在不一致,这极有可能导致严重的编码错误。

2.3 以太坊智能合约中的整数错误

文章描述了三种类型的整数错误,这些整数错误有可能导致恶意用户窃取以太币或者更改智能合约的执行路径。

算术错误

算术错误包括整数上溢、整数下溢、除数为零和模数为零这四种错误。值得注意的是,EVM与Solidity针对越界行为的处理方式是不完全相同的,而且在EVM和Solidity旧版本(0.4.0之前)除数为零和模数为零只会导致运算结果为0,并不会触发异常。


Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
截断错误

将一个整数类型数据转换为宽度更短的整数类型数据,可能会导致精度的丢

符号错误

将一个有符号整数类型数据转换为相同宽度的无符号整数类型数据,可能会导致一个负数变为一个很大的整数(反之亦然)。

3 方法论 3.1 类型推断

整数的类型信息,例如宽度和符号,通常只能从智能合约的源代码中直接获得,而不能从字节码中获得。尽管如此,通过分析Solidity编译器在编译过程中引入的代码优化规则,人们依旧能够根据特定代码优化规则从智能合约字节码中间接地推测整数的类型信息。

对于无符号整数,编译器会使用AND操作符屏蔽不在整数宽度范围内的bit,例如编译器会将uint32数据与位掩码0Xffffffff进行AND操作。

对于有符号整数,编译器会使用SIGNEXTEND操作符对数据进行符号扩展,数据的宽度可以根据SIGNEXTEND操作符的第一个参数i的值计算获得,即8 * (i + 1)。

3.2 寻找整数错误 算术错误

对于每一条可能导致整数上溢或者整数下溢错误的算术指令,作者检查在当前的路径条件下指令是否有可能违反Table 1中所列举的各条边界检查要求,如果指令可能违反任意一条边界检查要求,则该指令存在算数错误。

截断错误

Solidity分别使用AND和SIGNEXTEND指令截断有符号整数和无符号整数。作者检查每一条AND指令和SIGNEXTEND指令的输入是否大于指令的输出,以判断指令是否存在截断错误。

此外,为了检测并忽略Solidity编译器有意引入的截断,例如address类型数据的转换以及storage中变量的压缩存储,作者还对于检测得到存在截断错误的指令进行了进一步的筛选。

符号错误

作者根据特定指令的符号限制对所有整数类型数据的符号信息进行推断。所有数据的初始标记为”Top“;如果一个数据被当做有符号整数使用过,则将该数据标记为”Signed“;如果一个数据被当做无符号整数使用过,则将该数据标记为”Unsigned“;如果一个数据既被当做有符号整数使用过,又被当做无符号整数使用过,则将该数据标记为”Bottome“,表示该整数类型数据存在符号错误。

3.3 污点分析

作者使用污点分析筛选掉不能被实际利用攻击的整数错误,以降低误报率:

Sources:CALLDATALOAD,CALLDATACOPY; Sinks:SSTORE,JUMPI,CALL,RETURN。
Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
3.4 识别良性整数错误

作者使用了一些启发式规则以识别良性的整数错误。例如,当发现整数错误是分支条件的一部分时,作者通过检查分支条件谓词的左右两边是否都使用了相同的变量,且其后的某一基本块是否是以JUMPI、REVERT或ASSERTFAIL指令结尾,以判断该分支条件谓词是否是设计用于检查该整数错误的。

4 OSIRIS
Osiris Hunting for Integer Bugs in Ethereum Smart Contracts

OSIRIS是在OYENTE符号执行引擎的基础上实现的,包括三个主要的组成部分:symbolic analysis、taint analysis与integer error detection。

symbolic analysisi组件构建控制流图(CFG),符号执行智能合约的不同路径,并将每一条指令执行的结果传递给其他两个组件;taint analysis组件引入、传播并检查stack、memory和storage中的污点;integer error detection组件检查在执行的指令中是否存在整数错误。

5 评估 5.1 经验分析 定性分析

作者将OSIRIS工具与ZEUS工具进行了比较,发现ZEUS工具无法达到其自称的零漏报率的可靠性,相比较而言OSIRIS工具能够检测出更多的漏洞,并且具有低得多的误报率。


Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
定量分析

作者对于以太坊区块链前5,000,000个区块中的1,207,335个智能合约使用OSIRIS工具进行了大规模自动化分析。


Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
5.2 检测现实世界的漏洞

作者使用OSIRIS检测了排名前495的以太坊代币智能合约,重新检测出了已知的5个整数溢出错误导致的安全漏洞,并检测出其中例如RMC与UET等以太坊代币智能合约存在与整数错误相关的安全漏洞。


Osiris Hunting for Integer Bugs in Ethereum Smart Contracts
6 讨论 6.1 整数错误的原因 Solidity与EVM的弱点:Solidity中的整数类型系统与EVM中的整数类型系统存在不一致,EVM并不将整数上溢错误视为异常; 标准的不安全实现:ERC-20等代币标准仅仅提供接口定义,其具体实现完全由代币的开发者决定; 安全库的不正确使用:开发者并不会对于智能合约中的每一个算术操作都使用SafeMath等安全库。 6.2 安全整数处理的方法 在应用层面处理整数错误:SafeMath等安全库,额外的EVM指令会增加gas消耗; 在编译器层面处理整数错误:编译器在编译过程中生成整数错误检查代码,减轻了开发者的负担,但依旧会造成额外的开销以及性能影响。

Viewing all articles
Browse latest Browse all 12749