根据Unicorn和LibFuzzer的模拟执行fuzzing

黑客信息网

以前,星空试验室对根据unicorn的模拟执行fuzzing技术性开展了科学研究。在之前科学研究的基本上,大家进一步融合解决了一部分难题,基本完成了根据Unicorn和LibFuzzer的模拟执行fuzzing专用工具:uniFuzzer。

有关此项科学研究的有关情况,可回望试验室以前的本文根据 unicorn 的单独涵数模拟执行和 fuzzer 完成,这儿就不会再缀述了。从总体上,大家要想完成的是:

在x86网络服务器上模拟运作MIPS/ARM架构的ELF(关键来源于IoT机器设备)

能够对随意涵数或是代码精彩片段开展fuzzing

高效率的键入基因变异

在其中前2点,在以前的科学研究中早已明确用Unicorn处理;键入的基因变异,大家调查后决策选用LibFuzzer,并运用其代码覆盖率反馈,提高fuzzing高效率。

在本文中,大家先简略详细介绍下Unicorn和LibFuzzer,接着对模拟执行fuzzing专用工具的原理开展详尽的剖析,最终根据一个demo来详细介绍专用工具的大概应用方法。

情况详细介绍

1.1 Unicorn

提及Unicorn,就迫不得已谈起QEMU。QEMU是一款开源系统的vm虚拟机,能够模拟运作多种多样CPU架构的程序流程或系统软件。而Unicorn恰好是根据QEMU,它获取了QEMU中与CPU模拟有关的关键代码,并在表层开展了包裝,出示了多语种的API插口。

因而,Unicorn的优势很显著。对比QEMU而言,客户能够根据丰富多彩的插口,灵便地启用CPU模拟作用,对随意代码精彩片段开展模拟执行。但是,我们在应用全过程中,也发觉Unicorn存有了一些不够,最关键的便是Unicorn实际上还并不是很平稳、健全,存有了很多的坑(能看Github上的issue),并且好像创作者都没有短时间要填好这种坑的准备。另一方面,因为也有较多的坑,造成 Unicorn最底层QEMU代码的升级好像都没有纳入计划:Unicorn全新的release是2017年的1.0.1版本号,它是根据QEMU 2的,殊不知2020年QEMU早已公布到QEMU 4了。

但是,尽管存有着坑比较多、QEMU版本号较为旧的难题,对大家的模拟执行fuzzing而言实际上还行。前面一种能够在应用全过程选用一些临时性方式先填入(后边会举一个事例)。后面一种的危害主要是不兼容一些新的架构和命令,这针对很多IoT机器设备而言难题并不算太大;而旧版QEMU存有的网络安全问题,关键也是和驱动器有关,而Unicorn并沒有包括QEMU的驱动器,因此基础不会受到这种系统漏洞的危害。

1.2 QEMU

有关QEMU的CPU模拟原理,阅读者能够在网络上搜到一些专业的详细介绍,比如这篇。大概而言,QEMU是根据引进一层正中间語言,TCG,来完成在服务器上模拟执行不一样架构的代码。比如,假如在x86网络服务器上模拟MIPS的代码,QEMU会先以基本块(Basic Block)为企业,将MIPS命令经过TCG这一层译成x86代码,获得TB(Translation Block),最后在服务器上执行。

而为了更好地提升 模拟运作的高效率,QEMU还添加了TB缓存文件和连接体制。根据缓存文件翻译完成的TB,降低了下一次执行时的汉语翻译花销,这即便是Unicorn常说的JIT。而TB连接体制,则是把初始代码基本块中间的自动跳转关联,投射到TB中间,进而尽量地降低了搜索缓存文件的频次和有关的前后文转换。

值得一提的是,Unicorn所出示的hook作用,便是在总体目标代码译成TCG时,插进有关的TCG命令,进而在最后汉语翻译获得的TB中,于特定部位处回调函数hook涵数。而因为TCG命令和架构不相干,因而加上的TCG命令能够立即适用不一样架构。

1.3 LibFuzzer

LibFuzzer应当很多人 也不生疏,它是LLVM新项目中内嵌的一款fuzzing专用工具,对比大家以前详细介绍过的AFL,LibFuzzer具备下列优势:

灵便:根据完成插口的方法应用,能够对随意涵数开展fuzzing

高效率:在同一过程中开展fuzzing,不用很多fork()过程

方便快捷:出示了API插口,容易订制化和集成化

并且,和AFL一样,LibFuzzer也是根据代码覆盖率来正确引导基因变异键入的,因而fuzzing的高效率很高。但是,这两者都必须根据编译程序时插桩的方法,来完成代码覆盖率的追踪,因此务必要有总体目标的源代码。下面,在uniFuzzer的原理中,大家会详细介绍怎样融合Unicorn和LibFuzzer的作用,对闭源代码开展代码覆盖率的追踪意见反馈。

uniFuzzer原理

uniFuzzer的总体工作内容大概以下:

总体目标载入:在Unicorn中载入总体目标ELF和依靠库,并分析标记

设定hook:根据Unicorn的基本块hook,意见反馈给LibFuzzer代码覆盖率

提前准备自然环境:设定栈、存储器等信息内容

fuzzing:将Unicorn的模拟执行做为目标函数,逐渐LibFuzzer的fuzzing

下边对各阶段开展实际的详细介绍。

2.1 总体目标载入

碰到的很多IoT机器设备,运作的是32位系统MIPS/ARM架构的Linux,因此大家基本设置的总体目标便是这类架构上的ELF文档。

如试验室以前对模拟执行科学研究的那一篇文章中常讲,大家必须做的便是分析ELF文件格式,并将LOAD段投射到Unicorn的运行内存中。而在接着的科学研究中,大家发觉总体目标代码通常会启用别的依靠库文件的涵数,最普遍的便是libc中的各种C规范函数库。根据Unicorn的hook体制,倒是能够将一部分规范函数库根据非模拟执行的方法运作。可是这类方法局限性很大:倘若启用的外界涵数并不是标准库中的,那麼调用完成起來便会十分不便。因此,大家還是挑选将总体目标ELF的所有依靠库也一并载入到Unicorn中,而且也根据模拟执行的方法,运作这种依靠库文件的代码。

那麼,之上所做的,实际上也就是Linux中的动态链接器ld.so的工作中。Unicorn自身并不包含这种作用,因此一种方法是由Unicorn去模拟执行适合的ld.so,另一种方法是完成有关的分析代码,再启用Unicorn的插口进行投射。因为后一种更可控性,因此大家挑选了这类方法。但是好在ld.so是开源系统的,大家只必须把有关的代码改动兼容一下就可以。最后大家挑选了uClibc这一常见于内嵌式机器设备的轻巧库,将其ld.so的代码开展了简易的改动,集成化到uniFuzzer中。

因为大家集成化的是ld.so的一部分作用,导进涵数的地址解析没法在运作时开展。因而,大家采用相近LD_BIND_NOW的方法,在总体目标ELF和依靠库所有被载入到Unicorn以后,解析xml标记详细地址,并升级GOT表内容。那样,在接着的模拟执行时,就不用再开展导进涵数的地址解析工作中了。

集成化ld.so还产生了一个益处,便是能够运用LD_PRELOAD的体制,完成对函数库的遮盖,这有利于对fuzzing总体目标开展一部分订制化的改动。

标签:

发表评论 (已有条评论)

  • 评论列表