【论文阅读】 智能合约安全漏洞检测技术研究综述

一、SC安全漏洞事件

2016 年 6 月,黑客利用 DAO(decentralized autonomous organization)合约的可重入漏洞, 窃取了价值约 6000 万美元的以太币(即以太坊数字货币);
2017 年 7 月, 由于 Parity 多签名钱包合约的 Delegatecall 漏洞(parity multi-sig wallet delegatecall), 价值近 3 亿美元的以太币被冻结; 2018 年 4 月, 恶意攻击者利用美链 BEC 合约的整数溢出漏洞无限复制代币, 导致 BEC 代币的价值蒸发归零;
2018 年 11 月, 攻击者向 EOS.WIN 发起连续随机数攻击, 获利超过 20000 枚 EOS(即 EOS 数字货币);
2019 年 5 月, Binance 交易所遭到黑客恶意攻击, 导致7000多枚比特币被盗; 2020 年以来, 智能合约游戏 FarmEOS, Playgames, LuckBet, EOSPlaystation 等都遭遇了不同程度的黑客攻击, 累计造成近百万美元的损失。

危害:经济损失+区块链信危机

二、智能合约容易受到影响的原因

  1. 智能合约编程语言和工具(如 Solidity)仍然是新颖且粗糙的, 而使用新的编程语言和运行环境编写的智能合约相对更难以测试,尤其因为智能合约运行时被允许与外部合约函数或接口交互, 这可能导致重复的外部调用, 从而引发安全漏洞;
  2. 智能合约开发人员一时间无法完全理解新颖的智能合约编程语言和工具的基本执行逻辑, 因此无法预见合约在将来遇到的所有可能状态和环境,导致了开发人员容易编写出存在漏洞或易受攻击的合约;
  3. 区别于传统程序,由于智能合约二进制码及其状态是存储在不可篡改且不可变的区块链网络上, 智能合约一旦部署便是不可逆的, 也无法进行更新或修改这就导致区块链网络上可能存在一些有潜在安全问题而无法修补的合约;
  4. 由于区块链平台上的数字货币(如比特币和以太币)被智能合约保管和操控, 使得智能合约成为极具诱惑力的被攻击目标,吸引了很多恶意攻击者, 他们尝试各种手段挖掘并利用智能合约中可能存在的漏洞, 以窃取资金或阻塞区块链网络。

三、智能合约常见的漏洞类型&典型案例

  • 以太坊是当前影响力最大的开源区块链平台, 也是目前为止智能合约数量最多、漏洞类型最多、漏洞造成的损失最大的区块链平台。
  • 根据以太坊智能合约漏洞发生的层次不同,可以将合约漏洞分为 3 个层面, 分别是 Solidity
    代码层、EVM执行层、区块链系统层

    【论文阅读】 智能合约安全漏洞检测技术研究综述_第1张图片
1、Solidity代码层

(1)可重入漏洞
智能合约执行具有原子性和顺序性。不同于一般情况,智能合约的回调机制可能导致恶意攻击者在程序执行结束前再次进入函数。智能合约涉及跨合约的转账等敏感操作,而这些外部调用容易被攻击者利用,导致危险操作。
可重入漏洞是由回调机制引起的,曾导致历史上最著名的智能合约安全漏洞事件(DAO攻击),损失价值近6000万美元的以太币,并引发了以太坊的硬分叉。

(2) 整数溢出漏洞
整数溢出漏洞具有普遍性, 很多程序中都可能存在整数溢出问题. 整数溢出一般分为上溢和下溢, 智能合约中的整数溢出类型包括 3 种: 乘法溢出、加法溢出和减法溢出。 以太坊智能合约中, 一般指定整数为固定大小且无符号整数类型, 即表示整型变量只能是一定范围内的数值, 超过这个范围则会产生整数溢出错误。

Solidity 语言的整型变量步长一般以 8 递增, 支持从 uint8 到 uint256. 以 uint8 类型为例, 其变量长度为 8 位,支持存储的数字范围是[0,255]. 若试图将大小超过这个范围的数据存储到 uint8 类型变量中, 以太坊虚拟机(Ethereum virtual machine, EVM)将会自动截断高位, 从而导致运算结果异常, 产生整数溢出错误.
不同于其他程序, 智能合约整数溢出漏洞造成的损失是巨大且不可弥补的。 例如美链 BEC 合约的整数溢出漏洞导致其代币价值瞬间归零. 目前, 为了防止智能合约的整数溢出, 一方面可以在算数逻辑前后进行验证; 另一方面, 开发人员能使用 SafeMath 安全库处理算术逻辑, 防止整数溢出。

(3)权限控制漏洞
智能合约权限控制漏洞产生的最根本原因是未能明确或未仔细检查合约中函数的访问权限, 从而允许恶意攻击者能进入本不该被其访问的函数或变量. 权限控制漏洞主要体现在两个层面:

合约代码层:Solidity 智能合约函数和变量的访问限制有 4 种, 即 public, private, external, internal.如果函数未使用这些标识符, 那么默认情况下, 智能合约函数的访问权限为 public, 亦即该函数允许被本合约或其他合约的任何函数调用, 这种情况可能导致该函数被攻击者恶意调用;

合约逻辑层面:通常使用函数修饰器对函数或变量进行约束. 例如, 某些关键函数需要使用修饰器onlyOwner 或 onlyAdmin 来约束. 若未给这些函数添加修饰器, 任何人都有权利访问并操纵这些关键函数, 则很有可能导致关键函数被恶意攻击者操纵, 从而进一步地破坏智能合约逻辑.

(4)异常处理漏洞
以太坊智能合约中, 有 3 种情况会抛出异常:
① 执行过程中的 Gas(即部署或执行智能合约的费用)消耗殆尽;
② 调用栈溢出;
③ 执行语句中有 throw 命令。
一般来说, 如果被调用的合约抛出异常时, 合约将会通过回滚的方式处理异常行为, 即终止当前合约执行并恢复到上一步状态, 同时返回一个错误标识符(即 false).然而, 当一个合约以不同的方式调用另一个合约时, 以太坊智能合约却没有统一的方法处理异常, 发起调用的合约可能无法获取被调用合约中的异常信息. 例如, 智能合约中的子调用发生异常时, 通常会自动向上级传播, 但是一些底层调用函数(如 send, call, delegatecall)发生异常时只返回 False, 而不抛出异常 . 因此,仅仅根据有无异常抛出就判断合约执行是否成功是不安全的, 在调用底层函数时必须严格检查返回值, 并且对异常采用一致性的处理方式。

(5)拒绝服务漏洞
攻击者通过破坏合约中原有的逻辑, 消耗以太坊网络中的资源(如以太币和 Gas), 从而使合约在一段时间内无法正常执行或提供正常服务。

(6)类型混乱漏洞
编代码时人工类型错误。

(7)未知函数调用漏洞
当一个智能合约调用另一个合约中的函数时, 若函数和参数类型无法匹配到被调用合约中的函数, 此时将会默认调用该合约中的Fallback函数. 攻击者可以Fallback函数中隐藏恶意操作。

(8)以太冻结漏洞
转账操作是智能合约最重要且最独特的功能之一。 一些合约自身不实现转账函数, 是通过 delegatecall 调用外部合约中的转账函数来实现。 若外部合约带有 Self-destruct 或 Suicide 等操作时, 通过delegatecall 调用转账函数的合约很可能会发生因为被调用合约的自毁操作而导致自身以太币被冻结的情况。

2、EVM 执行层

(1) 短地址漏洞
利用了以太坊虚拟机自动补0的特性. 在智能合约ABI规范中, 输入的合约地址长度必须为20字节, 当地址长度小于20字节时, 以太坊虚拟机会通过在末尾自动补0来满足地址长度的要求. 然而, 正是因为这个特性使得恶意攻击者有机可趁. 例如, 攻击者故意把账户地址少输一个字节, 以太坊虚拟机解析时就会从下一个参数(即以太币数量)取缺少的编码位数对地址进行补全, 然后在整串二进制码的末位补0至正常的编码位数, 这就意味着以太币数量这个参数被左移了一个字节, 此时若是执行的是转账操作, 则可能使合约转出超出实际应该转发的以太币数量给攻击者。(真坏啊)

(2) 以太丢失漏洞
智能合约转账以太币时必须指定接收方的合约地址, 并且地址必须是规范的. 若是接收方的合约地址是完全独立的空地址, 即它们与任何其他用户或合约都没有关联, 如果将以太币转账给这样的合约地址, 将会导致以太币永远丢失。

(3) 调用栈溢出漏洞
智能合约每调用一次外部合约或者自身调用, 都会增加一次合约的调用栈深度. 在以太坊虚拟机中, 调用栈的限制为1 024, 若攻击者设计一系列的嵌套调用, 最终可能会成功引发调用栈的溢出, 从而进一步使智能合约处于不安全的状态。

(4) Tx.Origin 漏洞
全局变量tx.origin, 它能够回溯整个调用栈返回最初发起调用的合约地址. 若是合约使用这个变量做用户验证或授权操作时, 攻击者便可以利用tx.origin的特性创建相应的攻击合约盗取以太币.

3、区块链系统层

(1) 时间戳依赖漏洞
智能合约通常使用区块时间戳(block.timestamp),由矿工在区块链网络中确认。合约可以检索区块的时间戳,而且一个区块中的所有交易共享同一个时间戳,以确保合约执行后状态的一致性。然而,矿工在创建区块时可以在一定程度上选择有利于他们的时间戳,以谋取利益。

(2) 区块参数依赖漏洞
在以太坊智能合约中,无法直接创建真正的随机数。为了产生随机数,合约开发者通常会编写随机函数,并使用区块号(block.number)、区块时间戳(block.timestamp)或者区块哈希(block.blockhash)等相关的区块参数或信息作为种子来生成随机数。然而,类似于时间戳依赖漏洞,由于这些区块参数可以被矿工提前获取,导致生成的随机数是可预测的。因此,恶意攻击者可能会利用这一漏洞,产生对他们有利的随机数。

(3) 交易顺序依赖漏洞
在区块链网络中,交易的执行顺序由矿工决定。某些合约对交易执行顺序有严格要求,错误的顺序可能对合约造成负面影响。在图2所示的交易顺序依赖案例中,用户1和用户2在t时刻同时提交了交易T1和T2。然而,T1和T2的执行顺序由区块中的矿工决定。如果T1先执行,合约状态将由S变为S1;反之,将变为S2。因此,最终的合约状态取决于矿工选择的交易执行顺序。如果恶意的矿工监听到区块中对应的合约交易,便可以通过提交恶意的交易改变当前合约状态,从而有机会提前部署攻击。

4、典型案例
  • The DAO案例
    【论文阅读】 智能合约安全漏洞检测技术研究综述_第2张图片
  • KoET案例

【论文阅读】 智能合约安全漏洞检测技术研究综述_第3张图片
【论文阅读】 智能合约安全漏洞检测技术研究综述_第4张图片

  • Parity Multi-Sig Wallet案例
    【论文阅读】 智能合约安全漏洞检测技术研究综述_第5张图片
  • 美链BEC合约整数溢出案例
  • 庞氏骗局合约Rubixi案例(好离谱啊)
    【论文阅读】 智能合约安全漏洞检测技术研究综述_第6张图片

四、智能合约安全分析方法

https://www.mubu.com/doc/B8-6SK8MQV

五、智能合约漏洞检测工具的性能评估

(1) 准确率
漏洞检测其实是一个二分类问题,即检测工具判断合约是否存在某类漏洞,而对于二分类问题,通常将真实情况和检测结果的匹配结果作为重要评估指标,其中:

  • TP:True Positive,分类器预测结果为正样本,实际也为正样本,即正样本被正确识别的数量。
  • FP:False Positive,分类器预测结果为正样本,实际为负样本,即误报的负样本数量。
  • TN:True Negative,分类器预测结果为负样本,实际也为负样本,即负样本被正确识别的数量。
  • FN:False Negative,分类器预测结果为负样本,实际为正样本,即漏报的正样本数量。

● 真阳性(true positive, TP): 对于某一合约, 检测工具的检测结果是有漏洞且真实情况也是有漏洞, 即检测结果是正确的;
● 假阳性(false positive, FP): 对于某一合约, 检测工具的检测结果是有漏洞而真实情况却是无漏洞, 即检测结果存在误判;
● 假阴性(false negative, FN): 对于某一合约, 检测工具的检测结果是无漏洞而真实情况却是有漏洞, 即检测结果存在漏判;
● 真阴性(true negative, TN): 对于某一合约, 检测工具的检测结果是无漏洞且真实情况也是无漏洞, 即检测结果是正确的。
其中,TP+FP+FN+TN的结果是所有智能合约的测试样本, 智能合约真实值和检测值的混淆矩阵(confusion matrix)如图 , 其中, 准确率的计算方法如公式(1)所示:
在这里插入图片描述
【论文阅读】 智能合约安全漏洞检测技术研究综述_第7张图片
(2) F1-Score
F1-Score是分类问题中重要的衡量指标, 它是精确率(precision)和召回率(recall)调和平均数, 常被用作一些分类问题的最终评估标准。
【论文阅读】 智能合约安全漏洞检测技术研究综述_第8张图片

(3) 平均检测时间

一些相关概念

 - 图灵完备:图灵完备性 (Turing Completeness) 是针对一套数据操作规则而言的概念。数据操作规则可以是门编程语言,也可以是计算机里具体实现了的指令集。当这套规则可以实现图灵机模型里的全部功能时,就称它具有图灵完备性。直白一点,图灵完备性就是给一个工具箱内容:包括无限内存、if/else 控制流、while 循环......从而实现所有可计算的问题。
 - DAO:DAO的全称为Decentralized Autonomous Organization,直译为分布式的自治组织,是一种将组织的管理和运营规则以“智能合约”的形式编码在区块链上,从而在没有集中控制或第三方干预的情况下自主运行的组织形式。
 - 分叉:随着比特币越来越为人所知,比特币的交易越来越大,比特币网络原本的区块容量变得不够用。分叉就是复制了比特币原有的代码特性基础上,修改了部分的代码,并产生了一套新的代码。分叉主要是为了解决拥堵和扩容问题。不同的团队针对这些问题在比特币现有网络的基础上提出了新的解决方案,这就是分叉。在分叉的过程中,又有新的币产生,这些币就叫分叉币。
 - 软分叉:区块链网络系统版本或协议升级后,旧的节点并不会意识到比特币代码发生改变,并继续接受由新节点创造的区块,新老节点始终还是在同一条链上工作。
 - 硬分叉:指比特币区块格式或交易格式(共识机制)发生改变时,未升级的节点拒绝验证已经升级的节点产生的区块,然后大家各自延续自己认为正确的链,所以分成两条链。
 - EVM 字节码:是以太坊虚拟机的指令集,用于执行以太坊智能合约。EVM字节码是一种低级的、面向栈的编程语言,由一系列操作码(opcodes)组成。

你可能感兴趣的:(论文阅读,智能合约,区块链)