首页
社区
课程
招聘
[翻译]Firm-AFL:高效的IOT固件灰盒fuzz
发表于: 2021-2-15 19:59 36901

[翻译]Firm-AFL:高效的IOT固件灰盒fuzz

2021-2-15 19:59
36901

IoT 设备的网络攻击是一个严重威胁。这些攻击利用 IoT 固件中的软件漏洞。fuzz是一种有效的软件测试技术,用于漏洞挖掘。在IOT漏洞挖掘工作中,我们介绍Firm-AFL,用于 IoT 固件的第一个高通量灰盒模糊器。Firm-AFL解决了物联网模糊中的两个基本问题:

1、    它通过启用模糊处理来解决兼容性问题。可在系统中模拟的 POSIX 兼容固件仿真。

2、    它解决了性能瓶颈系统模式仿真技术采用新型技术引起称为增强过程仿真。通过组合系统模式仿真和用户模式仿真以新颖的方式,增强过程仿真提供高兼容性,如系统模式仿真和高吞吐量作为用户模式仿真。

我们的评估结果显示,(1 Firm-AFL功能齐全,能够挖掘到现实世界中的IOT设备漏洞;2 FIRM-AFL 的平均吞吐量比基于系统模式仿真的fuzz8.2;3Firm-AFL 能够找到1day漏洞比基于系统模式仿真的fuzz速度快得多,并且能够找到0day漏洞。

 

物联网设备对我们的隐私安全的影响非常大。据不完全统计直至2017年为止,全球物联网设备超过了82亿,人们的生活都离不开IOT设备,IOT设备的不安全问题已迫在眉睫。目前黑客对IOT设备的主要恶意行为是创建大型的僵尸网络(例如:MiraiVPNFilterProwli)。恶意程序会通过IOT设备的1day0day直接拿到root权限。因此,防御者必须要在攻击发生之前找到漏洞并修补。

Fuzz是一种软件测试技术,通过给目标程序发送变异的样本可以高效的进行漏洞挖掘;其中AFLAmerican Fuzzy Lop,一种以代码覆盖率作为变异策略的fuzz)的知名度最高,在DARPA Cyber Grand Challenge的决赛中,大部分选手都会使用AFL做漏洞挖掘。

IOT设备fuzz所存在的问题:

尽管fuzz在通用平台上能对程序进行有效的测试,但是因为fuzz对硬件配置有较高的要求,所以一般情况下不能直接在IOT设备上进行fuzz,比如:提取一个固件并找到一个应用程序,然后使用AFL对此程序进行fuzz,正常情况下fuzz会失败。

为此,最近的研究者提出了一系列的解决方案,从直接对IOT设备进行fuzz(例如:IOTFuzzer_Full);一种结合结合了硬件和软件的混合fuzz(例如:AVATAR);到完全使用软件进行系统模拟(例如:Firmadyne)。最近由Muench et al的研究报告指出:使用软件进行系统模拟的效率要比使用IOT设备的效率高得多,因为大多数IOT设备的硬件配置本身并不高。

吞吐量是影响fuzz效率的关键因素;然而即使是使用软件进行系统仿真,其性能也并不理想,根据我们的测试结果来看,system-mode大约比user-mode慢十倍(在使用AFL的情况下);慢十倍也就意味着同样是发现一个漏洞,system-mode要多花十倍的系统资源。根据我们的分析来看,system-mode主要开销有两个,一个是将虚拟内存转换为物理机内存,即内存管理单元(例如:SoftMMU);另一个主要开销是模拟系统调用的开销。

我们的解决方案:通过增强过程仿真进行灰盒模糊处理

在研究中我们发现,这是据我们所知第一个能同时完成以下两项设计目标的IOT固件fuzzer1、透明性:在进行fuzz之前不需要对固件的代码进行修改;2、效率:整个system-mode的吞吐量接近于user-mode的吞吐量。我们找到了能实现这两个目标的关键技术,也就是同时兼容了system-mode的通用性和user-mode的效率。

更准确的说,我们提出了一种名为“增强过程模拟”的新技术。顾名思义,这项技术的主要思想就是通过完整的系统模拟来增强进程模拟(或user-mode)。被fuzz的程序大部分时间会在user-mode中运行以提升效率,只有某些特殊时刻程序才会在system-mode中运行,以保证程序能正确执行。

为了评估这项技术的可行性,我们结合了AFLFirmadyne,实现了一个名为FirmAFLfuzz原型。从用户的角度来看,当用户使用Firm-AFL时,一方面可以像普通AFLfuzz那样对固件进行基于代码覆盖率的fuzz,另一方面Firm-AFL偶尔也会切换到Firmadyne进入system-mode,以确保程序能够正常执行。

我们已经用一组真实的IOT固件来对Firm-AFL进行基本评估,结果表明:

(1)、就想使用system-mode运行固件一样,Firm-AFL可以正确的运行固件;

(2)Firm-AFL的平均吞吐量相比于TriforceAFL(此fuzzer启用了轻量级的快照)这样的基于完整system-modefuzzer快了8.2倍;

(3)、在单个机器上Firm-AFL找到1day漏洞的速度比使用system-modefuzzfuzzer快了313倍,并且在8小时内找到了两个0day漏洞。

 

综上所述,我们在本论文中作出了如下贡献:

1、  我们认为,全系统仿真的运行开销很大,当批量进行固件fuzz时,效率并不理想;我们将进一步研究开销大的根本原因;

2、  摘要针对全系统仿真(高通用性、低效率)和用户模式仿真(低通用性、高效率)的矛盾特点,我们提出了一种“增强过程仿真”的新技术;

3、  我们为IOT固件设计并实现了第一个基于代码覆盖率的灰盒fuzzerFirm-AFL

4、  我们对我们的系统进行了全面的评估,并打印出系统的各个部分的运行开销;我们的改进使得fuzz的平均速度提高了8.2倍,并且能够在8小时内挖掘到两个0day

5、  目前最新版本的Firm-AFL支持三种CPU架构:mipselmipsebarmel,这涵盖了Firmadyne数据库中90.2%的固件。Firm-AFL源码已经上传至GitHubhttps://github.com/zyw-200/FirmAFL

 

Fuzzing是一种软件测试技术,旨在通过执行带有随机输入的目标程序并寻找有趣的程序行为(例如:crash)来发现bug。根据执行时收集和使用的信息的多少,fuzzer可以被分为黑盒、白盒和灰盒。黑盒fuzzer将程序视为黑盒,不利用任何执行反馈来做随机输入的变异,这种方法最初被用于Linux的程序测试;相反的,白盒fuzzer是根据对目标程序有着深入的了解下,对随机输入进行变异,这类程序分析技术通常代价较大,例如动态污点分析和符号执行;最后则是灰盒fuzzer,此类测试会根据有限的信息(例如代码覆盖率)来对随机输入进行变异。

目前最流行的灰盒fuzzer变异策略是根据代码覆盖率进行变异。这些fuzzer检测目标程序以收集代码覆盖率信息,之后收集到的信息会被用来指导样本的变异——能触发新代码的样本会被遗传算法选中,而不能触发新代码的样本会被丢弃。这种简单的策略在实际应用中效率很高。事实上,在实际应用中,因为灰盒fuzzer的速度很快甚至可以胜过白盒fuzzer,灰盒fuzzer的轻量级使得灰盒fuzzer的执行速度比白盒fuzzer快百倍甚至千倍,换言之,吞吐量对灰盒fuzzer至关重要。

AFL是著名的灰盒fuzzer。它可以静态或动态的分析程序。当有源代码时,AFL就会静态插桩;当没有源代码时,例如:fuzz商业程序(COTS)时,AFL会使用二进制转换器(例如:qemuuser-mode)来执行检测。因为大多数物联网设备的源代码和设计文档是专有的,所以只能进行动态检测。事实上就算是固件提取也要费一番功夫。

QEMU是一个基于动态二进制转换快速处理器的模拟器。与传统的逐条执行目标程序的模拟器不同,qemu一次性翻译多个基本块,并使用块链将它们连接在一起。这种块链设计使得qemu大部分时间都会在代码缓存(cache)内执行,从而使得转换开销最小化。动态检测可以在转换过程中执行以引入新功能,例如:分支监视和污点传播。

除了指令翻译外,还有一个重要的任务是地址空间翻译。在不同的执行模式下翻译的方式会有很大的不同。在系统模式下,qemu实现了一个软件内存管理单元(MMU)来处理内存访问。软件MMU将虚拟机的虚拟基址(GVAs)映射到物理机的虚拟地址(HVA)。这个映射过程对客户操作系统(OS)是透明的,这意味着qemu允许客户操作系统通过页表的接口设置GVA到客户物理地址(GPA)通过页面表的界面映射处理页面错误。在底层,qemu为每个内存访问插入一个从GVAGPA的转换逻辑。为了加快翻译速度,qemu使用转译后备缓冲区(TLB)来缓存转译的结果。此外,为了避免在地址转换发生时使代码缓存和块链失效,所有已转换的块都是用GPA进行索引,并且只有在两个基本块位于同一物理页面内时才执行块链。GPAHVA的映射使用线性映射(即 HVA=GPA + offset)。

system-mode不同,在user-mode中主机虚拟地址(HVA)的计算方式为:客户虚拟地址(GVA+ 常量偏移量。因此,这种转换比system-mode中的转换快得多。

随着IOT设备成为热门的攻击目标,IOT固件的漏洞挖掘也变得越来越重要。在测试程序时有两个挑战,第一个挑战是兼容性:许多IOT程序依赖于设备的特殊硬件组件,因此如果没有硬件支持将无法继续测试;第二个挑战是代码覆盖率:众所周知,黑盒fuzzer的代码覆盖率很低,而白盒fuzzer在代码量很大的情况下容易跑崩。表1对各种fuzzer的性能进行了对比。

AVATAR旨在通过提供更好的硬件组件支持,进行嵌入式固件的动态分析。它通过构架一个有处理器模拟器(qemu)和真实硬件组成的混合执行环境来进行固件分析,其中AVATAR充当的是qemu和真实硬件之间的软件代理。这使得AVATAR可以利用模拟器来执行和分析指令并将I/O操作传输到物理硬件上。作者使用S2E(白盒fuzzer)来挖掘Redwire Econotag Zigbee传感器的漏洞。因为是白盒fuzzer并且物理硬件的配置也不高,预计AVATAR的吞吐量会极低。

IOTFuzzer直接在真实设备上执行黑盒fuzz。与传统的基于黑盒的fuzz相比,他的主要优势就是通过目标设备的配套固件来执行fuzz。通过自动分析配套固件程序中的数据流,可以更好的理解通讯协议,从而生成更好的测试样本,提高触发bug的几率。也就是说,根据我们的评估,IOTFuzzer从来没有超过‘1样本/秒’的吞吐量,这是很慢的。

Firmadyne并不执行fuzz,它只是增加了qemu-system-mode对固件支持的数量。它提供了对ARMMIPS架构的支持,这些架构在商业中很流行。在硬件模拟方面,Firmadyne通过修改内核和驱动程序来完全模拟系统,以处理由于硬件的缺乏而导致的大量异常。与前两种解决方案相比,该方案能很快的适应新的IOT固件。全系统模拟的吞吐量通常比IOT设备要好。

Muench等人比较了不同配置下的黑盒fuzzer的吞吐量,包括:IOT设备执行(直接将输入发送到物理设备)、部分模拟(只发送硬件请求)和完全模拟。他们的仿真基于PANDA提供的图像重播功能。他们得出的结论是完全模拟(FE)具有最高的吞吐量,主要是因为IOT处理器要比桌面级处理器慢很多。然而即使是桌面级处理器,吞吐量也不会超过‘15样本/秒’。

AFL是一个非常著名的灰盒fuzzer,它可以通过qemu-user-mode进行二进制fuzz。只可惜,因为缺乏必要的硬件支持,qemu-user-mode并不能模拟IOT固件程序。例如:使用支持qemu-user-modeAFL对固件进行模拟时全都失败了(表三)。此外,因为吞吐量第的问题,直接采用Firmadyne进行完整的系统模拟并不可行。

总而言之,现有的固件fuzzer并不能做到代码覆盖率的最大化,而最先进的fuzzer(例如:AFL)却因为硬件的原因,无法直接用于固件fuzz。目前为止还没有高效的IOT灰盒fuzzer

AVATAR

IOTFuzzer

Firmadyne

Muench   et al.

AFL

种类

白盒fuzzing

黑盒fuzzing

PoC

黑盒fuzzing

灰盒fuzzing

兼容性

硬件支持

混合

全硬件

全模拟

混合

不支持

代码覆盖率

N/A

吞吐量

极低

中偏低

0day检测

1:固件测试工具的比较

鉴于目前IOT固件fuzzer的不尽人意的现状,我们的目标是为IOT固件设计一个高吞吐量的灰盒fuzzer。为此,我们决定在模拟的基础上设计一个fuzzer。这么做是出于两点考虑:首先,灰盒fuzzer需要收集代码覆盖信息来作为样本变异的依据,正如$2.1中所说,代码覆盖率检测并不是很难,由于大多数IOT固件只有二进制程序,因此工具最好是基于模拟器的;其次是性能,根据Muench等人的研究表明,虽然可以直接在IOT设备上执行fuzz,但是因为硬件配置的原因,使用完全模拟会更快,因为桌面级CPU的处理速度更快。

Firmadyne最大的问题是吞吐量不够,因此即是在system-mode下进行fuzz,速度也不会超过‘15样本/秒’。为了找到限制吞吐量的原因,我们使用了两种工具(basenameuptime)分别测试在system-modeuser-mode下的执行时间,结果如表2所示。根据测试结果可得出:如果在fuzz时使用user-mode将明显的提高吞吐量。导致时间差异的原因如下:

B1内存地址转换。在system-mode中,qemu使用软件模拟MMU对所有内存访问进行地址转换;相比之下,user-mode的地址转换要简单的多。因此,即使只考虑user-mode本身执行所花费的时间,也要比system-mode少得多。

B2动态代码翻译。User-mode下做代码翻译比system-mode要快;在system-mode下,块链接仅限于同一物理页中的基本块,这意味着在user-mode中调用转换程序的频率更高。

B3系统调用模拟。在user-mode中系统调用是由主机操作系统和硬件直接处理的,因此它比system-mode要快得多,因为在system-mode中操作系统和硬件设备都得被模拟;因为需要让程序正确的执行,就需要硬件模拟,但并不是所有的系统调用都需要依赖硬件模拟,换言之,并不是所有的系统调用都需要模拟。

在本次工作中,我们解决了上述的三个问题,并大幅提高了fuzz的吞吐量。

 

System-mode(ms)

User-mode(ms)

程序

总用时

系统执行

系统代码翻译

用户执行

用户代码翻译

总用时

系统执行

用户执行

用户代码翻译

Basename

4.08

1.79

0.53

1.41

0.35

0.34

0.02

0.11

0.22

Uptime

7.48

2.39

0.76

2.79

1.55

0.89

0.04

0.31

0.54

2system-modeuser-mode的运行时性能

这项工作的目标是设计一个IOT固件的高吞吐专有灰盒fuzzer,在$2中提到,想要实现这个目标就需要解决两个问题:兼容性和性能;system-mode可以解决兼容性的问题,但是性能较差;user-mode可以解决性能问题,但是兼容性较差。我们提出了一种名为“增强进程模拟”的新技术,它同时拥有了system-modeuser-mode的优点。

一般来说增强进程模拟的目标是在user-mode中正确执行大量固件程序,并满足以下要求:

(1)    可以在系统模拟器(例如qemu-system-mode)中正确的执行IOT固件,所幸,大部分IOT固件都能在Firmadyne下运行;

(2)    固件为POSIX兼容的操作系统。所幸许多固件镜像都是用Linux作为操作系统。

通过增强进程模拟,我们将实现如下目标:

1、  透明度。在增强进程模拟中运行的用户级程序的行为应该与在system-mode用运行的程序一样。

2、   效率。由于吞吐量是样本变异的主要因素,增强进程模拟需要尽可能高效。理想情况下,它应该接近于纯user-mode的性能。

为了实现上述设计目标,我们采用了一种新颖的方式对system-modeuser-mode进行混合。图1简单解释了我们的方法。

                            图1:增强进程模拟的概述



首先,IoT 固件在系统模式下启动,模拟器和用户级程序(包括fuzzer)在模拟器内正确启动。当被fuzz的程序达到预定的点(如main函数的入口点,或接收到第一个网络数据包)后,进程的执行被迁移到user-mode,以获得较高的执行速度。只有在极少数情况下,程序会回到system-mode执行,以保证程序能正确执行。

为了降低迁移成本,将会在这两种模式之前共享内存。更具体地说,system-mode的物理内存被分配为一个内存映射文件(称为RAM文件)。这个RAM文件也映射到user-mode的地址空间。但不同的是system-modeuser-mode会以不同的方式访问这个RAM文件;system-modeRAM文件视为物理内存,因此通过物理地址访问它;而user-mode通过虚拟地址访问共享内存。因此,RAM文件中的物理页面需要按照页面粒度通过它的虚拟地址映射到user-mode的地址空间。因此,当user-mode未建立页面映射时,需要将进程迁移到system-mode以建立此映射。我们将在$3.2中详细介绍内存映射的细节。

在到达系统调用之前,只要有适当的内存映射,进程就能在user-mode中正确执行。而在到达系统调用时,如果直接在物理机系统中执行固件的系统调用一般不会成功,因为物理机和固件不仅是软件不同,硬件也不同。为了确保透明性,我们需要将执行迁移到system-mode中来处理系统调用,当系统调用结束时,我们将执行迁移回user-mode;我们会在$3.3中详细讲解技术细节。

AFL对程序做fuzz时,当程序执行到预定点,AFLfork服务器会在这个点上重复fork一个新的程序实例(这个点称为fork point),并提供随机样本输入。同样的,在固件fuzz中,我们将在system-mode中启动固件,并启动指定程序。使用DECAF(基于system-mode的动态分析平台)提供的虚拟机自省(VMI),我们能够监控指定程序的执行,并在执行到预定点时得到通知。

此时,我们将遍历指定进程的页表,收集虚拟到物理页映射信息,并将其发送到user-mode。然后对每次虚拟地址到物理地址的映射都通过user-mode建立映射,建立映射所需要用到的mmap函数如下:

上述代码顾名思义。本质上,我们将RAM文件的一个物理地址作为偏移量映射到指定的虚拟地址。参数prot由对应的页表项的保护位决定。

从此开始,system-mode暂停运行,CPU状态被发送到user-mode,然后在user-mode继续运行。

user-mode的进程执行期间,如果访问内存地址已经映射在此地址空间,那么程序执行不会出错。否则,物理机CPU将引发页面错误。我们在user-mode中为页面错误注册了一个信号处理程序,如果出现页面错误时物理机系统会把页面错误事件传递给user-mode,当收到这个信号时,user-mode会记录故障处指令的CPU状态,然后暂停执行,并将CPU状态传递给system-mode,期望system-mode能处理页面故障并建立故障虚拟地址的新映射。

system-mode接收到CPU状态并恢复执行时,模拟的CPU会因为页面不存在而引发一个页面错误。页面错误处理程序将在物联网固件的操作系统中响应此页面故障,并尝试建立映射。大多数情况下,操作系统会建立一个类似映射(取决于内核线程和中断处理程序的调度),而导致页面错误的指令也将被重新执行;极少数情况下,如果操作系统因为某些原因无法建立映射,那么进程将被杀死。

这里的一个关键问题是确定何时建立了页面映射或何时发生错误,这样我们就可以在不同模式之间快速切换,以最大限度的提高执行速度。事实上这个问题的答案是很重要的,因为操作系统会同时处理多个任务,可能会同时发生大量的页面切换。

我们会用工具测量每个基本块的结束时间,以确认映射建立的时间。如果当前执行在指定的进程(或线程)内,就说明程序已从内核返回到用户空间以恢复错误指令。该映射必须在TLB中存在,以便我们可以直接找到这个映射。此时,我们将映射信息和CPU状态传递回user-mode,而user-mode将通过调用mmap函数创建新的映射并继续执行。

如果因为某些原因出现了错误,进程被杀死了,我们可以通过DECAF提供的虚拟机自省(VMI)功能收到消息,然后终止两边的执行。

当前的操作系统会在进程启动时以一种惰性的方式加载内存,所有的代码页都被分配到它的地址空间,直到第一次内存访问导致页面错误之前,都不会建立虚拟页到物理页的映射。

这种惰性设计对fuzzer的性能有不利的影响。正如我们在$4.1中讨论的,每个fuzz迭代的子进程都重复的从父进程派生出来。因此,总有一堆由未映射代码页引起的页面错误。这对我们的系统伤害极大,因为处理页面错误的开销远比在物理机系统上做本地处理大得多。

为了解决此问题,我们决定在物理内存中预加载给定的进程代码页,并在两种模式之间执行映射。这有助于我们避免在每次fuzz迭代时重复加载代码页,从而提高fuzz吞吐量。为此,我们在引导过程中模拟system-mode对每个程序代码页的访问,以强制操作系统将每个页映射到进程的地址空间,从而减少有这些预加载页面引起的页面错误的数量。

程序中的系统调用会因为底层硬件、固件和需求的不同而不同。因此,如果没有正确的处理由系统调用引起的异常,user-mode下的IOT固件可能会崩溃;例如:大多数IOT设备都有网络接口,而本地模拟器上没有此接口;当user-mode中的IOT程序执行需要与IOT系统中特定的网络接口交互时,就会引发故障;另一种情况时访问桌面计算机未定义的NVRAM的系统调用。

因此,为了确保固件能正确执行,我们必须将系统调用从user-mode重定向到system-mode。更具体的说,当user-mode遇到系统调用时,他会暂停执行,保存当前的CPU状态,并将其发送给system-modesystem-mode接受到CPU状态并继续执行,这将导致客户系统直接切换到内核模式以处理相应的系统调用。同样,由于客户系统的内核是多任务的,在系统调用返回之前可能会发生环境变化;因此,我们会用处理页面错误的方式来处理此问题,在每个基本块的末尾安装工具。如果当前的基本块在内核空间(r0),但下一个程序计数器在用户空间(r3),并且当前执行环境是针对执行系统调用的线程的,那么我们就会检测系统调用何时返回;此时system-mode暂停执行,保存CPU状态,并将其传递回user-mode,然后继续执行。

在检查IOT程序发出的系统调用时,我们发现许多系统调用都与文件系统有关。IOT固件程序要么访问已有的文件或目录,要么就临时创建文件或目录。我们决定对这组系统调用做一些优化。我们从固件中映射文件系统,并将其作为物理机操作系统中的一个目录挂载,这样user-mode就可以直接访问它了;同样地,user-mode就可以直接将文件系统相关的系统调用传递到物理机操作系统,而不是重定向到system-mode

正如$5.3所示,与文件系统相关的系统调用会大幅消耗系统资源,因此这种优化对整体性能影响很大。

利用$3中介绍的技术,我们设计了基于AFLIOT固件fuzzer——Firm-AFL。在$4.1中,我们将会介绍AFL的工作流程,然后在$4.2中,我们会介绍如何将增强进程仿真集成到AFL中。

AFL是一个根据代码覆盖率进行变异的灰盒fuzzer。它维护了一个样本集,该集合储存了所有的样本,包括用户选择的初始样本,以及从现有样本中变异而来的新样本,这些样本会使程序的代码覆盖率最大化。

启动AFL的主程序在afl-fuzz中。它从样本集中挑选一个原始样本执行一次随机变异,生成一个新的随机样本,并将这个样本喂给目标程序(假设目标程序是一个二进制可执行程序)。

AFL会使用qemu-user-mode启动程序,并从fuzz过程中收集目标程序的代码覆盖率信息,以检测分支转换。目标程序的代码覆盖率信息被编码并储存在位图中。

由于在fuzz过程中需要反复执行目标程序,AFL利用“fork”这种机制来提高效率。它首先运行目标程序到特定位置(例如:main函数入口),使程序的代码和数据正确初始化,然后重复的从它派生出子进程;通过这种方式可以快速跳过新进程的初始化设置。因此,父进程被成为fork-server;然后将样本喂给派生出的子进程中,覆盖率信息被收集并储存在位图中;而位图在三个进程(afl-fuzzfork-server,子进程)之间共享。Afl-fuzz将比较子级中的位图实例和过去所有执行结果积累的位图,已确定是否应该将这个变异的样本保留并存储在样本集中。

我们希望在不改变原有AFL的情况下,加入对IOT固件fuzz的功能。为此,我们将qemu-user-mode替换为增强进程模拟,其余组件保持不变。新的工作流程如图2所示。


                                   图2:Firm-AFL概述


为了fuzz IOT固件中的程序,我们需要启动固件镜像,并在系统启动后启动程序。这是在fork-server中的system-mode中完成的。

我们利用Firmadyne来模拟固件。我们还在Firmadyne中加入了DECAF中的虚拟机自省(VMI)功能。这样我们就能够知道目标程序何时启动或终止,还可以知道目标程序何时执行到指定位置。

AFL选择的默认分支点是main函数的入口点。在我们的案例中,我们希望通过网络接口触发IOT程序中的漏洞;因此我们会hook网络相关的系统调用,当这些系统函数被第一次调用时就会创建分支点。

AFL的工作流程中,我们可以简单地利用系统调用的分支点来派生一个子进程并启动一个新的fuzz实例。而在我们的例子中,我们不仅需要为user-mode派生一个子进程,而且还需要为system-mode派生一个虚拟机实例,因为两个模式必须同步。

事实上,创建一个虚拟机需要的系统资源太多,所以我们会创建一个虚拟机的快照;当fuzz完成时我们可以恢复快照。qemu-system-mode提供了保存快照的功能,将所有CPU寄存器和内存空间保存到特定的文件;然后读写这些文件的速度依然缓慢。

在我们的系统中,我们基于写时复制原理实现了一个轻量级的快照机制。更具体地说,我们首先将映射到qemu-system-modeRAM文件标记为只读;那么,内存写操作将导致页面错误,我们复制这个页面,然后把这个页面标记为可写。因此我们记录在一次fuzz期间修改的所有内存页;当恢复快照时,我们只需要将这些记录下来的页写回即可。

输入是通过检测系统调用提供的。对于从网络接口接收输入的IOT程序,我们直接在user-mode中检测与网络相关的系统调用;因此我们不需要将这些系统调用重定向到system-mode

收集代码覆盖率信息。由于大部分执行都发生在user-mode中,而system-mode仅用于处理页面错误和部分系统调用,所以我们可以像原始的AFL那样在qemu-user-mode中插入分支转换来计算覆盖位图。

在本节中,我们会评估我们的Firm-AFL fuzzer。本节的目的是测试我们的方法是否已经解决了性能瓶颈并实现了两个目标;简而言之,我们会回答以下几个问题:

透明度。Firm-AFL在对固件进行fuzz时是否可以像system-mode那样正确的执行IOT程序?

效率。Firm-AFL的吞吐量(样本/秒)相比于完全基于user-modefuzzer的吞吐量如何?

优化的有效性。我们的优化技术成功的解决了已知的性能瓶颈吗?

漏洞挖掘的效率。IOT固件漏洞挖掘方面,Firm-AFL到底是否有用?

我们在测试时使用了三套程序。第一组程序时两个标准:nbenchlmbench。它们用于测试模拟的正确性和系统资源开销。第二组程序由来自四个不同的供应商的七个IOT程序组成(表3)。我们选择这些程序是因为它们是处理网络请求的关键程序,因此是远程攻击的理想目标。它们用于测试灰盒fuzzer的性能。第三个数据集时Firmadyne数据集,其中包括了其HTTPuPnP服务与151day攻击的相关固件(表6.我们收集这些数据是为了评估Firm-AFL漏洞挖掘的透明度和效率。

实验(除了$5.4外)是在一台8IntelRCoreTMi7-3940XM 3.00GHz CPU23.5GB RAM 1TB硬盘上进行的。操作系统为Ubuntu 16.04.5 LTSqemuAFL的版本分别为2.10.12.06b。我们在每十次迭代后获得所有测量值。我们最终报告的数字是20次测量的平均值。默认情况下,我们将分支点设置在接收到网络数据后的位置,并由AFL引擎提供随机输入。

为了评估增强进程模拟的透明度,我们首先使用nbench测试软件进行测试。在生成输出之后,基准测试将把实际输出和预期输出进行比较。如果生成的输出是错误的,则意味着模拟出错了。结果表明,该系统能够在无误差的情况下完成所有的基准测试。

我们还利用Frimadyne的数据库对Firm-AFL的透明度进行了评估。我们收集了120个带有HTTP服务和独特设备模型的固件镜像。我们从固件镜像中提取并使用chroot挂载文件系统;但是因为系统环境的原因,这些程序刚启动就崩溃了;然后我们在尝试system-mode和增强进程模拟下使用正常样本输入(初始样本)并运行;结果是在这两种模式下所有的程序都能正常运行。对于固件程序,我们需要进一步比较system-mode和增强进程模拟下生成的系统调用序列,确认系统调用的序列是相同的。

最后我们对每个表6中的漏洞我们都使用全system-mode和增强进程模拟进行复现和利用并进行了执行跟踪。我们已经确定两种模式的执行轨迹是相同的。

综上所述,本次测评表明Firm-AFL可以像全system-mode那样提供完全透明的模拟。

程序

文件大小(KB)

描述

厂商

硬件类型

硬件名称

版本

CPU架构

Cgibin

129.4

CGI   binary program

DLINK

Router

DIR-815

1.01

MIPSEL

Httpd

90.2

Embedded   HTTP server

Dnsmasq

162.3

Embedded   DNS server

Dropbear

307.3

Embedded   SSH server

TPLINK

TL-WR940N

V4_160617

MIPSEB

Httpd

169.2

Embedded   HTTP server

Jjhttpd

103.3

Embedded   HTTP server

Trendnet

TEW-813DRU

V1(1.00B23)

lighttpd

327.3

Embedded   HTTP server

netgear

WNAP320

3.0.5.0

3:测评中使用的IOT程序

我们从两个角度测试进行效率测试。首先我们使用bench跑分对增强进程模拟的性能开销进行评估。

nbench的结果如表4所示。nbench是一个测试CPU的测试组件。这个测试的增强模式并没有施加太多开销,主要是因为这些测试并没有很多内存同步操作和重定向系统调用,所以相对简单;为了测试重定向系统调用产生的开销,我们使用了lmbench。结果如表5所示,可以看到对于普通的系统调用(例如文件相关的系统调用),开销几乎可以忽略不计;但是对于需要重定向的系统调用(例如TCP相关的),开销就要大得多。

跑分项

增强模式

用户模式

速度下降比例

Numeric   sort

679.12

686.56

1.08%

String   sort

78.36

79.54

1.48%

Bitfield

3.47E+08

3.45E+08

0%

FP   emulation

163.85

161.72

0%

Fourier

1383.6

1384

0%

Assignment

20.45


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-2-23 09:38 被pureGavin编辑 ,原因:
上传的附件:
收藏
免费 13
支持
分享
打赏 + 50.00雪花
打赏次数 1 雪花 + 50.00
 
赞赏  yjmwxwx   +50.00 2021/02/21
最新回复 (10)
雪    币: 377
活跃值: (5996)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2021-2-18 11:55
0
雪    币: 6
活跃值: (1141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢
2021-2-18 13:48
0
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
4
感谢分享!
2021-2-18 16:59
0
雪    币: 420
活跃值: (690)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
非常感谢 之前看了这篇文章 非常好
2021-2-18 20:32
0
雪    币: 76
活跃值: (206)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
6
感谢分享!
2021-2-20 15:57
0
雪    币: 809
活跃值: (1301)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享!
2021-3-2 10:17
0
雪    币: 8
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
感谢分享!
2021-7-14 14:45
0
雪    币: 228
活跃值: (582)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9

<这个评论最初提了一个很傻的问题,现在已经解决了。删除>

最后于 2022-1-19 14:55 被KSr01dO编辑 ,原因:
2022-1-19 14:52
0
雪    币: 228
活跃值: (582)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
“但是因为fuzz对硬件配置有较高的要求” 这段对照了一下原文上下文,建议修改为 
“但是由于对MIPS平台的Fuzz有较高的硬件依赖,直接在模拟器中进行user-mode级,单纯针对于软件本身的Fuzz可能会无功而返” 或修改为类似内容,请译者核查,感谢
2022-1-19 14:58
0
雪    币: 14517
活跃值: (17538)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
11
KSr01dO “但是因为fuzz对硬件配置有较高的要求” 这段对照了一下原文上下文,建议修改为 “但是由于对MIPS平台的Fuzz有较高的硬件依赖,直接在模拟器中进行user-mode级,单纯针对于软件本身的F ...
感谢提醒
2022-1-19 15:09
1
游客
登录 | 注册 方可回帖
返回
//