模糊器如何处理无效输入?

How does a fuzzer deal with invalid inputs?

假设我有一个以指针作为输入的程序。在没有关于指针结构的先验知识的情况下,模糊器如何创建可以实际命中程序内部的有效输入?为了使这个更具体,想象一个人工 C 程序

int myprogram (unknow_pointer* input){
  printf("%s", input->name);
}

在某些情况下,被测程序首先检查输入格式。如果输入格式不好,它会引发异常。在这种情况下,模糊器如何能够到达超出该异常引发语句的程序点?

模糊器在攻击面抛出各种随机输入组合。目的是寻找任何机会让 "golden BB" 通过输入检查并获得可以进一步探索的响应。

大多数 模糊器对程序的内部结构一无所知。不同的模糊器以不同的方式处理这个问题:

  1. 根本不处理。只需随机输入并希望产生能够通过 some/all 检查的输入。 (例如 - radamasa
  2. 改变有效输入 - 获取已知的有效输入,并改变它(翻转位、删除部分、添加部分等),在许多情况下,它的有效性足以通过部分或全部检查。例如——如果你想对 VLC 进行模糊测试,你将把一个有效的电影文件作为模糊器的输入,它将向 VLC 提供它的突变。这些通常被称为 基于突变的 模糊器。 (例如 - zzuf
  3. 如果您事先了解输入的结构,请构建输入模型,然后改变其中的特定字段。这种方法的一大优势是能够处理非常特定类型的字段——校验和、哈希、大小等。这些通常被称为 generation based fuzzer。 (例如 - 秒杀,sulley and their successors, peach

然而,近年来出现了一种新型的模糊器 - 基于反馈的模糊器 - 这些模糊器对有效(或无效)输入执行突变,并根据他们从模糊程序收到的反馈来决定如何以及做什么接下来变异。通过在编译时进行注入跟踪、通过在运行时修补程序或使用硬件跟踪机制来注入跟踪代码,通过检测程序执行来接收反馈。其中首先是 AFL(您可以阅读更多相关信息 here)。