对honggfuzz的实现原理的学习笔记。
honggfuzz - 一个易于使用的fuzzer,支持基于代码覆盖的feedback-driven fuzzing。同时支持GNU/Linux,FreeBSD,Windows, Mac OSX和Android等系统。
学习1
(1)honggfuzz
关键:
honggfuzz 也是 google 开发的一款 fuzz . 其设计思路 和 libfuzzer 和 afl 类似 ,感觉就是 libfuzzer + afl 的 增强版。
对于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)更多使用说明
- 具体的实战,利用该框架对应用程序进行模糊测试。
学习2
关键:
- 反馈驱动(Feedback-Driven)——通过监控样本触发的代码覆盖率,进而改进输入样本以提高代码覆盖率,增加发现漏洞的概率。与libfuzzer和honggfuzz类似,该工具也是基于代码覆盖率的Fuzzer。
关于代码覆盖率——
(1)代码覆盖率的计量单位
函数(较粗糙)
基本块 (较普遍,以指令跳转为作划分界限)
边界(涵盖了基本块部分,唯一的差别是edge多记录了一些执行边界的信息)
(2)统计代码覆盖率
有源码:直接使用SanitizerCoverage即可,在编译选项中添加相应的覆盖率统计方式,比如基本块统计方式可以添加:
CFLAG=“-fsanitize=address -fsanitize-coverage=bb”
无源码:使用Pin、DynamoRIO等二进制插桩工具去hook统计,或者pediy改指令的方式去监控也是可以的
Persistent Fuzzing——即fuzzing API。
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策略可以总结出常规的变异规则——
随机数据替换
数据值增减
已知边界值替换
插入随机数据
删减文件内容
目录变异
数据拷贝覆盖
……
- Intel Processor Trace
对于闭源程序的反馈驱动Fuzzing,通常有3种方式——
二进制插桩:使用Pin或DynamoRIO动态插桩监控代码覆盖率,比如winafl
虚拟化技术:使用Qemu或Boch等虚拟化技术实现应用层和内核层的代码覆盖率监控,比如afl
硬件级技术:使用Intel Processor Trace(PT)技术,比如honggfuzz
补充说明
作为一款通用型Fuzzer,honggfuzz是支持Android平台的,可以研究一下怎样在Android平台上使用该Fuzzer,以及能否使用该框架对Android应用程序进行模糊测试。
参考资料:官方说明文档