模糊测试

基本介绍

覆盖率指引的模糊测试方法获得覆盖率的四种追踪方式[1]

  1. 使用编译器向基本块边缘插桩,可以准确地插桩并易于优化,但需要源码已知。
  2. 静态二进制重写,不需要源码,仍在研究,因为静态代码插桩准确性难以保证,并且优化能力有限。这些限制条件会影响代码率信息的质量与准确性,以及二进制重写的表现。
  3. 动态二进制插桩,不需要源码,可以容易、准确插入代码,但是动态翻译二进制的开销可能大到不能接受。
  4. 硬件辅助追踪,不需要源码,利用内置的硬件追踪扩展,在运行时直接获取控制执行流信息。

针对网络协议的模糊测试

网络协议的特点是一般有明确的状态信息,相同的input在不同的状态可能得到不同的output。针对网络协议的模糊测试一般具有stateful的特点。这类模糊测试有几个难点:

  1. 生成格式正确的信息,满足对特定状态的fuzz
  2. 扩展到不同的协议中
  3. 测试样例有效性,需要通过格式校验比如长度、协议认证、校验和等

AFLNET

首次提出针对有状态协议的灰盒模糊测试。AFLNET从响应信息中提取响应码来表示状态信息,并用响应码序列来推断协议实现的状态模型,并进一步使用这一模型来指导fuzz。

一些不足:

  1. 状态表示能力:AFLNET要求响应信息中包含状态码,这并不是协议必须实现的。而且状态码表示能力有限,且可能产生冗余状态。
  2. 测试效率:没有明确的信号反映待测程序是否处理完消息,因此设置固定的计时器来控制消息发送,时间窗口可能过小或过大。

STATEAFL

使用程序内存状态来表示服务状态,通过对被测程序插桩来收集状态信息并推测状态模型。在每一轮网络交互中,STATEAFL将程序变量值转储给分析队列,并进行post-execution的分析,来更新状态模型。

一些不足:

  1. 面对和AFLNET相同的测试效率问题,而且因为后执行分析,产生额外的开销,会降低测试吞吐量。

NSFuzz

使用基于变量的状态表示方法推断状态模型来指导模糊测试,使用基于网络事件循环的同步机制来提高吞吐量。

启发式的变量判断方法:静态分析中只在事件循环代码中分辨状态变量,且关注被读与写、被赋予枚举类型的数据或是数据结构体里的整型成员。

表示状态的方法:使用两条语句维护shared_state数组,当状态变量值被更新时同步更新shared_state;当fuzzer在通信管道收到消息处理结果时,对这个数组进行hash,作为当前程序所处的state。

1
2
shared_state[hash(var_id) ^ cur_store_val] = 1;
shared_state[hash(var_id) ^ pre_store_val] = 0;

IoTHunter

提出多阶段信息生成方法来对IoT固件汇总的有状态网络协议进行fuzz。