FIRM-AFL 通过增强进程仿真实现物联网固件的高吞吐量灰盒模糊测试
我们的解决方案:通过增强进程仿真进行灰盒模糊测试
- 方案的优势在于透明度和效率
- 透明度,即不需要对固件中要进行模糊测试的程序进行修改。
- 效率,即整个系统模糊测试的吞吐量接近于用户模式仿真。
- 方案的主要思想
- 用全系统仿真来增强进程仿真(或用户模式仿真)
- 要模糊测试的程序主要运行在用户模式仿真,以实现高效率。只有在必要时切换到全系统仿真,以确保程序的正确执行,从而实现通用性。
- 用户模式仿真具有高效率的特点
- 全系统仿真具有通用性的特点
- FIRM-AFL基于AFL和Firmadyne实现,其中AFL负责对物联网固件中用户指定的程序进行覆盖引导模糊测试,就像使用AFL对普通用户级程序进行模糊测试一样,Firmadyne负责用户模式仿真和全系统仿真之间的切换,以确保给定的程序能够被正确地仿真。
背景和动机
Fuzzing
- 最流行的灰盒模糊器是覆盖引导模糊器。
- 这些模糊器对目标程序进行插桩,以收集代码覆盖率信息。
- 收集的信息用于引导输入的生成。探索了新的路径的输入将被作为种子去生成新的路径,而没有产生新的覆盖的输入将被丢弃。
- AFL
- 当源代码可用时,首选静态插桩。
- 当源代码不可用时,AFL使用二进制翻译器即(QEMU提供的用户模式仿真)来执行插桩。
- 对于大多数物联网设备,由于源代码和设计文件是厂商专有的,我们可能只有固件的镜像可用,因此动态插桩是唯一可行的选择。
测试物联网固件以发现漏洞
- 测试物联网程序面临两个挑战
- 兼容性:许多物联网程序依赖于设备的特殊硬件组件,因此在没有合适支持的情况下无法进行测试。
- 代码覆盖率:黑盒模糊器代码覆盖率较低,而白盒模糊器无法扩展到稍大的代码库。
- 同类型的工具对比
- Avatar(一种结合硬件和软件仿真的混合解决方案)
- 构建QEMU和真实硬件组成的混合执行环境,Avatar充当模拟器与真实硬件之间的软件代理,这允许其利用模拟器来执行和分析指令,同时将I/O操作引导到物理硬件。
- 吞吐量低
- IoTFuzzer(直接模糊物联网固件)
- Firmadyne(全系统仿真)
- 在系统模式QEMU中添加了对物联网固件的硬件支持,为ARM和MIPS架构提供支持。通过修改内核和驱动程序来完全模拟系统,以处理由于缺乏实际硬件而导致的物联网异常。
- 吞吐量低
- AFL
- 可以通过用户模式QEMU支持纯二进制模糊测试
- 由于缺乏特殊的硬件支持,用户模式QEMU无法成功模拟大多数物联网程序。
- 总结
- 现有的物联网固件模糊测试工具不能提供令人满意的代码覆盖率。(前面一直提吞吐量,最后总结的时候提代码覆盖率???)
- 最先进的模糊器(如,AFL)无法轻松应用于物联网程序模糊测试。
动机
- 我们决定基于仿真来构建模糊器
- 由于大多数IOT固件只有二进制程序,因此最好是基于仿真进行插桩。
- 仿真比直接在IOT设备上fuzz吞吐量更高。
- 导致全系统仿真吞吐量低的原因
- 内存地址转换
- 在系统模式仿真中,QEMU使用软件MMU为每次内存访问执行地址转换。
- 动态代码翻译
- 在系统模式仿真中,块链接限制于同一物理页面的基本块,那意味着翻译器的调用频率高于用户模式仿真。
- 系统调用仿真
- 在系统模式仿真中,系统调用交给仿真的操作系统和硬件,速度较慢。并不是所有的系统调用都需要仿真的操作系统和硬件来支持。
增强进程仿真
概述
问题陈述
- 增强进程仿真的目标是在满足以下要求的情况下,在用户模式仿真中正确执行物联网固件的程序:
- 固件可以在系统仿真器(如系统模式QEMU)中被正确仿真。
- 固件运行POSIX兼容的操作系统。
- 通过增强进程仿真,实现以下设计目标:
- 透明度(解决挑战一:兼容性)在增强进程仿真中运行的用户级程序应该表现地像在系统模式仿真中运行一样。
- 高效率(解决挑战二:性能)理想情况下,它应该近似与纯用户模式仿真的性能。
解决方案概述

- 固件在系统模式仿真器中启动,用户级程序(包括要模糊测试的程序)在仿真器中正确启动。
- 当要模糊测试的程序达到预定点(如主函数入口点),进程执行将迁移到用户模式仿真,以获得较高执行速度。只有在极少情况下,才会将执行迁移回系统模式执行,以确保执行的正确性。
- 为最小化迁移成本,两种仿真模式通过RAM文件实现内存共享。系统模式仿真将RAM文件视为物理内存,而用户模式仿真通过虚拟地址访问共享内存。
- 当在用户模式仿真中没有建立页面映射时,需要将进程执行迁移到系统模式仿真以建立该映射。
- 通过正确的内存映射,进程应该能在用户模式仿真中正确执行,直到到达系统调用(直接在主机OS执行系统调用通常不起作用,因为主机OS 与IOT OS不同,底层硬件层也不同),借助RAM文件将进程执行迁移到系统模式仿真以处理此系统调用,当系统调用返回时,将进程执行迁移回用户模式仿真。
内存映射
引导
- 在系统模式仿真中启动IOT固件,并进一步启动指定的物联网固件程序,通过DECAF提供的虚拟机自检VMI监控指定的物联网程序的执行,并在执行到达预定分叉点时得到通知,遍历指定进程的页表,收集虚拟到物理的页映射信息,并将其发送到用户模式仿真端,然后,对于虚拟地址到物理地址的每次映射,用户模式仿真端通过调用mmap来建立内存映射:
mmap(va,4096,prot,MAP_FILE,ram_fd,pa)
- 本质上讲,我们将RAM文件的一页以物理地址作为偏移量映射到指定的虚拟地址。
- 从这一点开始,系统模式仿真中的执行暂停,CPU状态被发送到用户模式仿真,并在那里恢复执行。
- 理解:这里是指在程序刚启动的时候如何将系统模式仿真和用户模式仿真进行内存共享------就是先在系统模式仿真运行,然后将页表发送给用户模式仿真,用户模式仿真构建虚拟内存与物理内存的映射,实现两个模式下内存映射的统一,即初始化(也就是引导)
页面错误处理
- 在用户模式仿真的进程执行过程中,如果访问的内存地址已经映射到此虚拟地址空间,则执行应该会成功进行。否则,主机CPU将引发页面故障,将进程迁移到系统模式仿真以建立映射。
- 在用户模式仿真中为页面错误注册了信号处理程序,主机OS将页面错误事件传递给用户模拟仿真,在接收到该信号时,用户模拟仿真记录故障指令处的CPU状态,暂停执行,将CPU状态传递给系统模式仿真端,期望在系统模式仿真中处理页面错误,并为故障虚拟地址建立新的映射。
- 在系统模式仿真接收到CPU状态并恢复执行时,由于页面不存在,仿真处理器将引发页面错误,物联网固件OS中的页面故障处理程序将对此页面故障作出响应,并尝试建议映射。
- 一个关键问题是确定页面映射何时建立以及错误何时发生
- 映射何时建立
- 如果当前执行在指定的进程内,则意味着执行已经从内核返回到用户空间,可以在TLB中找到新建立的映射,将其与CPU状态一块发送给用户模式仿真,它通过调用mmap创建这个新的映射并恢复执行。
- 错误何时发生
- 如果由于某种原因,发生了错误,进程被中止,可以依赖虚拟机自检VMI来获得通知,然后双方的整个执行都会终止。
- 理解:物联网固件程序会一直在用户模式仿真下运行,当发生页面错误时,将错误抛给系统模式仿真,由他解决问题建立新映射,映射建立后切换到用户模式仿真。
预加载页面映射
- 现代操作系统以惰性方式加载内存页。尽管当一个新进程启动时,所有代码页都被分配到其地址空间中,但直到第一次内存访问导致页面错误,才真正建立从每个虚拟页面到其物理页面的映射。
- 对于每个模糊迭代,子进程都会从父进程中重复分叉,因此总是有一系列由未映射的代码页引起的页面错误,开销巨大拖慢模糊速度。
- 在物理内存中预加载给定进程的代码页,并执行两种模式之间的映射,可以避免每次模糊迭代时重复加载代码页,从而加快模糊吞吐量。
- 在引导过程中,在系统模式仿真中模拟对每个程序代码页的访问,以迫使操作系统将每个页面映射到进程的地址空间,从而减少由预加载页面引起的页面错误数目。
系统调用重定向
- 如果系统调用引起的异常没有得到正确处理,物联网程序的用户模式仿真可能会失败。
- 为了确保执行的正确性,我们必须将系统调用从用户模式仿真重定向到系统模式仿真。
- 优化与文件系统相关的系统调用
- 作者发现许多系统调用都与文件系统有关。
- 物联网固件程序要么试图访问固件中已经存在的文件或目录,要么是新创建的临时使用的文件或目录。