论文精读01

xFuzz: Machine Learning Guided Cross-Contract Fuzzing

代码链接:xfuzz_tools
首先所以说一下本篇文章的大致思想,xfuzz是应用与Cross-contracts 也就是交叉合约,交叉合约的定义为多个智能合约之间相互调用而导致的漏洞,可能只有一个合约的时候这个漏洞不会显示出来,而由于多次调用,以往无法被调用的合约也可以被调用了。
abstract:由于现在的合约检测器大部分是检测单个智能合约的漏洞,也就导致CC(cross-contracts)漏洞事件比较多。然而现存的工具对于检测分析一个合约又十分的受限,由于在CC中对于合约路径的搜索空间是远远大于单个合约的。为了解决这个问题,这篇文章提出了xfuzz一个基于机器学习的智能合约漏洞检测框架。这个机器学习的框架是由一个比较“新”的特征来训练的比如说(word vectors 以及instructions)并且这些方式来过滤良性路径(搜索路径),比较以往的检测工具该方式通过实验证明是比较好的。
贡献,
1,构建并且成功检测出来了三种漏洞,reentrancy,delegatecall,and txorigin
2,提出新的ML模型能够很大程度上减少可利用的搜索路径,同时也发现该训练模型能够兼容其他检测工具的报告
3,对于这三种漏洞的检测精准度比较高
4,xfuzz可以发现18种漏洞

介绍这几种漏洞以及会面临的挑战

我们都知道EVM会把代码编译成为opcode,而且我们对漏洞的定义是是否存在这么一个调用路径使得attacker能够获得一定的benefits。具体来说,当存在一个依赖从具体的关键指令比如说(TXORIGIN 以及 DELEGATECALL)到一个具体的指令集合比如说,ADD SUB 和 SSTORE,此时就有可能有漏洞的发生。因此为了形式化前面提到的这个概念采用了漏洞的定义形式。
Definition(Control Dependency),一个操作码opj被认为是控制依赖于opi的前提是,如果是存在一个执行流程从opi到opj,同时opj这个操作码后决定所有的opk在这一条路径从opi到opj(不包括opi),但是不是后决定于opi。情况二,若是一个操作码opj被认为是后决定一个操作码opi的前提是要满足所有的调用路径从opi开始都要经过opj
Definition(Data Dependency),一个opj被认为是数据依赖于opi的前提是存在着一条路径执行从opi到opj,比如说W (opi) ∩ R(opj) != ∅,这里R(opj)代表着一个集合被指令opj所读取数据的定位以及W(opi)就代表着被opi指令所写入数据的位置集合
总结,一个操作码opj依赖于opi,如果说opj控制或者数据依赖于opi,同时如果opj也依赖于opk,那么opk也依赖于opi
如果要进行漏洞的判断,首先我们定义C代表一个关键操作码的集合(CALL,CALLCODE,DELEGATECALL)等,明显这些操作码都涉及外部调用external call,而这些外部调用就是漏洞出现的原因,因为这些代码都收到外部attaker的控制。
Definition(Reentrancy Vulnerability).用操作码层次来说,如果说存在有一个调用路径中的opcode opc属于C并且紧跟着执行了ops在同一个函数当中比如说ops是SSTORE,并且opc依赖于ops一个会遭受重入攻击的合约
Definition(Dangerous Delegatecall Vulnerability)
Definition(Tx-origin misuse Vulnerability)
Definition(Cross-contract Vulnerability),只要一组的合约遭受了CCV存在着一个漏洞路径,是由于操作码来自于两个及以上的两个合约。
一个CCV的图片解释
CCV造成的前提是,至少需要三个智能合约参与。

总述

利用作者定义的ML去引导模糊测试受怀疑的交易(可能有漏洞),这里存在三点难点;
C1 如何训练ML模型并且达到令人满意的precision和recall
C2 如何把训练好的ML与fuzzer相结合以减少合约的搜索空间
C3 如何赋予受引导的fuzzer去支持高效的CCV检测
xfuzzer的整体框架

ML Model training phase

这里利用ML而不是其他的静态分析工具去训练模型,去寻找可能有漏洞的合约是由于,ML能够有效的减少人为定义的漏洞检测规则;
在这个阶段,我们搜集训练数据,engineer features,以及评估模型。首先利用slither securify solhint去检测漏洞,在我们的数据集上,之后把这三者检测报告收集后给合约打上标签。标签规则:如果一个合约获得了至少两票就被打上漏洞标签。之后利用,文章定义的engineer features,把输入的contract变成bytecode,然后把他们向量化,通过word2vec。同时为了解决C1问题,我们人工定义一些新的特征比如说,can_send_eth,has_call,callee_external.这些静态特征从合约的CFGS或者ASTs中抽取。最终这些特征就是被用来训练ML模型的。尤其是,从三种模型中去选择更好的。

Guided testing phase

这个阶段还是在ML,合约被输入以预训练模型为了获得预测结果,之后被预测后的合约会被分析然后被指出或者是标记,为了解决C2问题,一个函数被认为可能有漏洞的。我们使用call-graph 分析以及cfg分析,去构造call path之后,我们收集可达路径,我们利用path优先级算法(后面会提到),把这些路径排序,这个优先级就变成了fuzzer的指标,这个方法可以有效的减少检测路径,因为,良性函数的检测执行一定会等到漏洞函数检测完。fuzzer就可以集中注意力到有漏洞的函数。
为了解决C3问题,我们提取出static信息比如说,函数的参数,conditions path。然后把之前预测以及当前的静态信息进行融合以得到 path priority score,基于此,最有可能有漏洞的函数会被先检测,这样search space 会被进一步减少。

ML Guidance preparation

Datacollection 从https://etherscan.io 提取
features engineer提取特征,首先漏洞函数与良性函数都会被slither提取出来runtime code,之后word2vec把bytecode转变成20维度的vector,我们前面提到过为了解决C2问题需要添加新特征以减少search space所以这里只要20dimension是不够的,我们要丰富它,为了解决这个问题,文章提出了加7个维度,从CFGs中提取出来,
这七个特征
这样丰富后,就变成了27个dimension的维度。比如说这个特征has_modifier 被用来设计辨别是否存在项目guards(保护),就是自己禁止函数的任意访问。而有这个特征的函数一般很少可能有漏洞,因此我们把modifier变为counter-features防止假阳性;has_call has_balance用来检测是否有外部调用以及余额检测操作这两个指令对转账操作十分的敏感。可以利用它,更好的定位是否有转账操作以减少search space;callee_exernal检测是否有外部调用,用来补抓是否有risky call。can_send_eth,用来检测是否有转账操作;剩下的两个特征txorigin 以及delegatecall是对应于两个具体的漏洞的,着七个特征可以任意组合以应对新出的漏洞。

Model selection

模型测试

,最后选择了EEC模型,选择ecc的原因是因为这里选择是为了分出带漏洞和良性漏洞的,不是为了检测而recall就是为了甄别真假。

GUIDED CROSS-CONTRACT FUZZING

利用上面ML去引导fuzzer
去做两个事情。一,定位可能有漏洞的函数,二,利用静态信息以路径优先化。然而即使有ML过滤了,这个search space任然相当的大,因此想去优先化路径
引导过程
路径优先级算法
下面介绍一下怎么计算优先级分数;
优先级score分两个一个是functions score 以及 caller priority ,function score是为了评估函数的复杂性,而caller score为了衡量调用路径的代价。
Function priority。我们收集静态特征去计算函数的优先级分数越少代表着更高的优先级。fs代表函数的分数比如说可能有漏洞的函数令fs=0.5,而没有漏洞的函数令为fs=1;之后,我们计算被调智能合约的维度。维度就是一个函数的被调用的次数。比如说优先级例子
上面的这个智能合约withdraw被调用了两次,所以这个函数的维度就是2;
而这个参数的维度Sp就是被衡量去设置看这个函数的参数的复杂度。参数的复杂度越高同理优先级就越低,array bytes address 以及integer复杂度都是不一样。
Definition(function priority score)

这个就是计算函数优先级分数的表达式。

caller priority,这个函数用来描述谁是首先进行测试的路径。它也有两个部分组成。1,分支语句的个数 if for while 等,以及require assert被用来衡量COMp条件复杂度用来描述去经过条件语句的复杂度。更多条件对应更低优先级。比如说an example of prioritizin path中第6行有一个所以这个函数的得分为1其他为0;
下一步计算条件距离,这个距离本质上是从这个函数入口到这个函数内第一个条件所经过的statements语句。
Definition(caller priority score)
在这里插入图片描述
具体的检测过程。1,合约会被编译成bytecode,fuzzer会把所有的合约放在私链上。2,对于漏洞非相关的path只会执行一次,用来初始化变量。3,存储函数选择器。4,fuzzer会检测是否有漏洞。5,fuzzer寻找local 变量找到函数选择器以寻找漏洞函数,然后触发这个目标函数的调用路径。6,把执行结果与ML阶段的report相比较。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值