honggfuzz学习

honggfuzz的实现原理的学习笔记。

honggfuzz - 一个易于使用的fuzzer,支持基于代码覆盖的feedback-driven fuzzing。同时支持GNU/Linux,FreeBSD,Windows, Mac OSX和Android等系统。

学习1

(1)honggfuzz

(2)模糊实战之honggfuzz

关键:

  1. honggfuzz 也是 google 开发的一款 fuzz . 其设计思路 和 libfuzzer 和 afl 类似 ,感觉就是 libfuzzer + afl 的 增强版。

  2. 对于fuzz过程中的常用命令的解释——

(1)honggfuzz -f input_dir -W out -z -s – /usr/bin/djpeg _ FILE _

-f : 指定初始样本集目录

-W : 指定输出目录

-z : 使用编译时的指令插桩信息来 为 样本变异做回馈, 默认选项

-s : 表示目标程序从 stdin 获取输入,即样本数据通过 stdin 喂给程序

_ FILE _ : 类似于 afl 的 @@ , 表示程序通过文件获取输入,fuzz 过程会被替换为相应的样本文件名

(2)honggfuzz -f input_dir -P – /usr/bin/djpeg_persistent_mode

-P : 表示使用 persistent 模式

(3)更多使用说明

  1. 具体的实战,利用该框架对应用程序进行模糊测试。

学习2

honggfuzz漏洞挖掘技术深究系列

关键:

  1. 反馈驱动(Feedback-Driven)——通过监控样本触发的代码覆盖率,进而改进输入样本以提高代码覆盖率,增加发现漏洞的概率。与libfuzzer和honggfuzz类似,该工具也是基于代码覆盖率的Fuzzer。

关于代码覆盖率——

(1)代码覆盖率的计量单位

函数(较粗糙)

基本块 (较普遍,以指令跳转为作划分界限)

边界(涵盖了基本块部分,唯一的差别是edge多记录了一些执行边界的信息)

(2)统计代码覆盖率

有源码:直接使用SanitizerCoverage即可,在编译选项中添加相应的覆盖率统计方式,比如基本块统计方式可以添加:CFLAG=“-fsanitize=address -fsanitize-coverage=bb”

无源码:使用Pin、DynamoRIO等二进制插桩工具去hook统计,或者pediy改指令的方式去监控也是可以的

  1. Persistent Fuzzing——即fuzzing API。

  2. Fuzz策略——honggfuzz中fuzz策略的实现主要集中在mangle.c中,在循环的fuzzloop函数中,会根据用户的选择的fuzz方式来调用动态fuzz或者静态fuzz的方法,但最后都是调用mangle_mangleContent来变异文件数据。(把这些函数过一遍就是honggfuzz中所有的文件变异规则(如下表)了,如果想实现自己的fuzzer,这些规则来扣出来用Python实现一遍,顺便把afl的规则也扣过来就更完美了。)

源码中的函数 具体的变异操作
mangle_Resize 用空格填充随机位置
mangle_Byte 向随机位置写随机的uint8类型的数据
mangle_Bit 取随机位置的数值做位翻转
mangle_Bytes 在随机位置覆盖写2~4字节数据
mangle_Magic 取各种边界值进行覆写,这些边界值部分跟AFL还不一样
mangle_IncByte 取随机位置的数据加1
mangle_DecByte 取随机位置的数据减1
mangle_NegByte 取随机位置的数据取反
mangle_AddSub 取随机位置的1、2、4或8字节的数据长度作加减操作,操作数取 rand(0~8192)-4096
mangle_Dictionary 变异目录名,也是随机取文件夹名称进行变异,如果有多个目录,那被变异的目录数也是随机的
mangle_DictionaryInsert 在目录的随机位置中插入随机数据
mangle_MemMove 取随机位置的数据拷贝随机长度的数据,里面就是调用memmove函数实现的
mangle_MemSet 取随机位置、随机大小,用UINT8_MAX数值填充
mangle_Random 取随机位置、随机大小的缓冲区,用随机数填充
mangle_CloneByte 取两处随机位置的作数据交换
mangle_Expand 文件末尾扩展随机长度的空间,用空格填充,然后在随机位置,取前面的随机长度作数据拷贝
mangle_Shrink 删除随机长度的文件内容
mangle_InsertRnd 在文件的随机位置插入随机长度的数据
mangle_ASCIIVal 在随机位置覆盖32字节的随机数

注意1:在Fuzzing过程中,很多变异规则是共用的,可以参考一些主源的开源软件,比如afl\peach\honggfuzz\libfuzzer,提取规则作整合,然后写个自己的fuzzing框架,在后面作针对的fuzzer时,可以直接套用。

注意2:从上面的fuzz策略可以总结出常规的变异规则——

随机数据替换

数据值增减

已知边界值替换

插入随机数据

删减文件内容

目录变异

数据拷贝覆盖

……

  1. Intel Processor Trace

对于闭源程序的反馈驱动Fuzzing,通常有3种方式——

二进制插桩:使用Pin或DynamoRIO动态插桩监控代码覆盖率,比如winafl

虚拟化技术:使用Qemu或Boch等虚拟化技术实现应用层和内核层的代码覆盖率监控,比如afl

硬件级技术:使用Intel Processor Trace(PT)技术,比如honggfuzz

补充说明

作为一款通用型Fuzzer,honggfuzz是支持Android平台的,可以研究一下怎样在Android平台上使用该Fuzzer,以及能否使用该框架对Android应用程序进行模糊测试。

参考资料:官方说明文档

其余的开源Fuzzer列表

(1)有哪些好的fuzzing工具推荐?

(2)Open Source Fuzzers list (and other fuzzing tools)