【论文分享】One Fuzz Doesn’t Fit All: Optimizing Directed Fuzzing via Target-tailored Program State...

论文基本信息

发表会议或期刊(简称,CCF级别):ACSAC 2022
论文标题(论文简称):One Fuzz Doesn’t Fit All: Optimizing Directed Fuzzing via Target-tailored Program State Restriction
论文作者所在团队:Hexhive
论文一句话概述:论文提出XX方法,解决了XX问题。
论文实验情况:实验工具(是否开源),实验测试集(是否开源),实验环境,实验规模,简要过程

开源于:https://github.com/HexHive/SieveFuzz

论文概述

众所周知,fuzzing是发现软件漏洞的一种实用技术。然而,有时候,我们只需要关注特定的代码区域有没有漏洞,比如漏洞复现,补丁或者回归测试。这种需求催生了定向模糊测试。给定一些目标位置(行号),定向模糊测试通过距离最小化策略来让fuzzing往这些地方探索。距离最小化策略是找到离目标近的测试样例,然后随机地变异这些测试样例。然而,这个策略被应用到所有的测试样例,不管样例是否到达了目标,这就会导致浪费很多时间计算没有到达目标的测试样例的距离。要加速定向模糊测试就需要对目标可达的路径进行优先级排序。

因此,本文提出了tripwiring(绊绳,一种陷阱,可以让路过的东西摔倒),一种轻量级的技术过滤不会到达目标的路径。通过限制模糊测试探索只会到达目标的路径,可以减小模糊测试的噪声,从而减小了插桩和距离最小化策略的开销,能够提升定向模糊测试器高达99x的测试样例的吞吐量。

实验评估方面,与AFLGo,Beacon和AFL++进行了对比,在9个benchmark上触发的漏洞要比这些工具多47%,也快117%。

研究背景

现有的定向模糊测试使用距离最小化策略来让fuzzing探索预定义的目标位置。为了实现定向性,距离最小化策略计算每个生成的测试样例到目标位置的距离。然而距离测量是在运行时,并且是对所有种子实施的。而大多数的种子并不会到达目标,就会引入过多的开销。

而且,距离最小化策略并不适合那些很容易到达的目标。对于这些容易到达的目标,距离最小化的开销很大。没必要对无法到达目标的路径进行分析。

相关工作

文章主要介绍了两类工作,一个是定向模糊测试,另一个是提高fuzzing性能的。

定向模糊测试这块提到了AFLGO,Hawkeye,ParmeSan,UAFuzz,UAFL,BEACON。

提高fuzzing性能的提到了AFL-Dyninst,AFL-QEMU,RetroWrite,ZAFL。

原理

image-20230108173457057

宏观层次上,用传统的控制流和路径检测方法识别出到达目标位置的路径,然后修改覆盖率导向的模糊测试让其只探索这些区域,从而实现定向性。

文章的核心思想是认为定向模糊测试浪费过多的时间在目标不可到达的路径上,所以可以先发制人地终止模糊测试探索目标不可达的区域。这么做有两点好处:

  • fuzzer里超过90%的运行时间就不会花在计算代码覆盖率和目标距离上。
  • 过滤掉这些路径,fuzzer就不会浪费资源在处理这些测试样例上。

识别不可达区域

识别不可达区域的算法如下,首先用目标位置的入口结点来初始化worklist,同时allow list也初始化为空集。然后,对于worklist中的每个元素,做如下操作:

  • 在过程间控制流图上,找到每个节点的来边
  • 对于每条边,检查它的源和对应于过程间控制流图上的节点
  • 使用调用图检查从源能否到目标,如果可以,就把源加在allow list里,对应节点加在worklist里。

所有在allow list外的节点就会被判定为不必要的。由于过程间控制流图对上下文不敏感,我们的分析可能会多包含一些目标相关的代码区域。为了缓解这个问题,整合了函数可达性分析的结果。

image-20230108185845593

同时,由于使用静态分析来生成ICFG和CG,另一个挑战是处理间接跳转。求解间接跳转的静态方法有指向分析和值集分析,但是这种静态的方法会over-approximate候选的目标。从而不能保证fuzzing的定向性。

为了缓解这个问题,文章用每个新覆盖的间接分支来更新调用图。有了新信息后,再重新用上面的分析方法来更新可达的区域。虽然这种重分析技术会增加运行时开销,但是带来的好处是覆盖率的指数下降,所以不会有很明显的性能下降。

虽然是动态解决间接调用问题的,目标位置在一开始的可达性分析里可能会被忽略。然而,作者观察到用其他模糊测试器生成种子的trace来进行分析就够了。

实现

基于AFL++实现。为了实现按需的可达性分析,实现了fuzzer和分析模块的client-server的通信机制。静态分析基于SVF框架。

总体框架可以用一个状态机来表示。

INIT:一开始,确定target是否在初始的ICFG和CG上可达。如果是不可达,有可能静态没有识别到一些间接跳转的。因此转到EXP状态去探索。利用EXP过程跑的动态信息来更新ICFG和CG。不过要尽可能避免EXP过程,所以一开始会利用初始种子来更新这些间接跳转。

EXP:如果目标是不可达的,就使用非定向,non-tripwired的模糊测试来多样化可选的种子。一旦发现有一条路径可以到达目标,就退出这个阶段,跳到FUZZ阶段。

FUZZ:一旦确定target是可达的,tripwired-directed fuzzing就开始了。

image-20230108195707674

为了随时更新间接跳转,作者实现了按需的可达性分析。也就是引入了通信机制,一旦发现新的间接边,就暂停fuzzer,等待静态分析模块反馈结果。不过这个切换实际运行时并不多。

提前终止部分的实现是:分配给每个代码区域一个唯一的数字ID,然后用ID去hook每个区域调用运行库的开始。然后把这个库链接到被插桩的程序,利用它来强制终止执行。

同时也会维护一个动态的bitmap,每个bit和每个ID映射。如果bit是unset,和这个bit相对应的函数就不会被执行。间接跳转追踪的部分,对所有间接跳转分支进行插桩,去获取这些边的目的地。

实验结果及分析

主要回答这三个问题:

  • RQ1:Is tripwiring effective and fast at restricting fuzzing-reachable search space?,
  • RQ2:Do the benefits of tripwiring improve directed fuzzing effectiveness and speed?
  • RQ3:Are there properties that make a target location well suited to tripwiring?

对于RQ1,平均消除了29%的空间。这让我有点意外,比我想象中的少很多。表格中也给出了初始分析的时间和重分析的时间,开销是比较小的。

image-20230109195140486

对于RQ2,触发漏洞的时间比AFLGO快3.49x,比AFL++快8.36x,比Beacon快2.82x

image-20230109195933269

image-20230109200808145

对于RQ3,作者得出两个结论:

  • 可以用“不能到达目标位置的代码数量”来识别目标是否disjoint。也就是脱节。
  • 对于这类脱节的目标,用文章的方法要比距离最小化的方法好。

自己的感受

这篇文章的思路和Beacon有些相似,但是,是通过动态的方法解决的。

而且实现上有几个点挺有意思的。比如,动态方法解决间接调用追踪的问题,通过链接库来让程序提前终止等等。

并且发现开源的仓库给的脚本特别详细,所有的数据应该是都开源了。有机会看一看他的仓库。

最后就是这篇文章写作上用词用得比较巧,有很多表达是值得收藏的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

破落之实

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值