https://arxiv.org/pdf/2111.03013.pdf
Abstract
1-2:背景:fuzz有用,但是测试网络服务还难
3 本文: NYX-NET:基于snapshot的fuzzing方法
特点:可fuzz的对象非常多,包括服务端、游戏、客户端、IPC服务
效果:
- 在Mario上,提升10-30x速度
- 能在Lighttpd、MySQL、Firefox IPC上找到bug
- Mozilla上20000$的bug
1. Intro
P1: 介绍新进展;能够测试新的targets类型要比新的算法更加引人注目
P2: 测新的targets一般有两种方法
- generating function-style + persistent mode
- snapshot
挑战,尤其是信息传递非常频繁的: - 状态多
- 复杂
- 运行速度慢
- 消息格式更加复杂
P3: 以AFLNet为例 - 真的用网络连接是非常慢的
- 不知道何时服务能够接受testcase,因此需要等待相当长的时间
- 重用会带来一定噪声,比如background threads可能接收到testcase,这些进程可能随机影响到coverage和状态
为此,需要用户来写脚本确认文件系统之类的变化,让其在每个testcase之后回滚
P4: 本文:NYX-Net
方法:
- hypervisor-based snapshot fuzzing 基于管理程序的快照模糊测试,用于确保并加速noise free fuzzing(无噪音的模糊测试)
- selective emulation of network 网络选择性仿真,以避免实际网络流量的沉重成本。
P5:
Nyx-Net基于Nyx,拓展为:
- 能够定位网络连接,添加对网络对战的处理只吃(handle the network stack)
- 引入增量、完整的虚拟机快照,该快照与操作系统无关,兼容任何POSIX系统(虽然只测了busybox和ubuntu,并且只是在docker container里面跑的)。这些快照允许模拟很多API,并且几乎没有速度损耗。当hook检测到目标程序准备接受fuzzer提供的输入的第一个字节时,就会触发whole system snapshot。
P6:
认为Nyx Net实际上可以模糊任何负责、有状态、基于信息的目标程序,例如IPC接口。比如Firefox就已经使用了NyxNet。
P7:
效果:
- 与AFLnet比,在ProfuzzBench上,吞吐量提高了300%,覆盖率提高了70%
- 与Agamotto比,快照重新加载和创建速度为10倍。
- 在ProfuzzBench上能够找到AFLnet、Agamotto没发现的新bug
- 与AFL+LJON比,能够解决大多数超级马里奥关卡,而且比IJON小果果更好。
- 能找到Lighttpd、MySQL、Firefox IPC上的bug
P8:
贡献:
- Nyx-Net
- 增量快照
- 实验、发现了多个现实错误
2. Background
2.1 Network Service Fuzzing
P1: 网络服务的内存不安全问题;
This puts such software at significant risk: Most of the complexity is part of some very public (often Internet-wide) attack surface.
在不强制内存安全的语言中确保内存安全很困难
例子: AFLNet: 允许AFL发送包
改进:将socket-based I/O 操作改为 file-based I/O,这样就能直接将AFL++等软件应用在网络服务fuzz上。
P2:
挑战:
- AFL等假设目标程序快速,而且只spawn一个进程,这个进程会一直运行到处理完输入
(但实际上程序执行可能很慢、可能spawn多个进程、主进程可能在初始化之后就退出了) - AFL等假设两个执行基本独立(但对大多数网络服务来说,两个包并不独立)
- 对网络协议而言,很少考虑startup time, 链接持久化、重要状态
P3: AFLnet强制用户编写需要重置环境的清理脚本,大大降低了测试速度。
P4: custom mutator, 用户来写,非常有效,能够符合大多数结构化信息。
例如AFL: mutator based on multiple rudimentary packet boundary parsers用于支持格式
Nyx的仿射类型字节码
P1:
- 用户指定一组opcodes,这些opcodes可以被Nyx be chained
- 作者当时仅仅用该工具对Hypervisor进行测试,但这个方法具有用来测试许多交互式目标程序的潜力
- 用户仅仅需要实现一组opcodes
E.g:
- 通过给定的端口和网址来hook第一个建立的连接
- 通过agent将packet传给function calls,例如recv和read
- 当类似epoll或者select之类的函数希望获取更多数据时,agent提示准备完毕
人工需要做的事情只有找到建立连接和发送包的这类c代码
fuzzer会自动生成bytecode格式和自定义的VM,这个VM会调用对应handlers和自定义的mutator