【honggfuzz学习笔记】honggfuzz的基本特性

本文架构

1.动机

最近的学习需要使用honggfuzz,但苦于一直没有高度相关的、系统性总结的博客,官方文档写的也十分有限。于是收集各方资料形成此文。笔者还在初步学习阶段,若有错误还请大家不吝指出。
【Github】honggfuzz

首先提供几篇参考的博客,若看完本文还有不懂的地方希望能给大家解惑。
【安全客Blog】honggfuzz漏洞挖掘技术原理分析这篇文章讲的比较细致,我的大部分知识基本是这里看懂的。
【看雪Blog】honggfuzz漏洞挖掘技术深究系列分析的比较深入,且博主好几篇类似文章,值得参考。

2.honggfuzz的基本概念

官网描述

Description:A security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with interesting analysis options.

解读

从官网描述中我们可以提取到honggfuzz的几个特点:

面向安全(security oriented): 这点十分容易理解,fuzzing工具用以测试程序代码中可能存在的安全隐患(i.e. 漏洞)。
反馈驱动(feedback-driven): 通过监控样本触发的代码覆盖率,改进输入样本以提高代码覆盖率,增加发现漏洞的概率。本文将在第3章介绍。
持久型Fuzzing(Persistent Fuzzing): 所谓持久型fuzzing(Persistent Fuzzing),就是长生命周期进程重复调用被fuzz的API。
多种反馈驱动方式(Feedback-Driven):

* 支持基于软件和基于硬件(eg.分支计数(branch counting)、指令计数(instruction counting)等)

* Intel BTS(Branch Trace Store),

* Intel PT(Processor Tracing)
更接近底层的异常监视: 使用底层接口监视进程(linux和NetBSD下使用ptrace),与其它fuzzer相比更有可能从crash中发现并报告被劫持/忽略的信号(被fuzz的程序可能截获并隐藏)。

3. honggfuzz的反馈驱动(Feedback-Driven)

【官方文档】FeedbackDrivenFuzzing.md

Feedback-driven fuzzing :

Honggfuzz is capable of performing feedback-guided (code coverage driven) fuzzing. It can utilize the following sources of data:

* (Linux) Hardware-based counters (instructions, branches)

* (Linux) Intel BTS code coverage (kernel >= 4.2)

* (Linux) Intel PT code coverage (kernel >= 4.2)

* Sanitizer-coverage instrumentation (-fsanitize-coverage=bb)

* Compile-time instrumentation (-finstrument-functions or -fsanitize-coverage=trace-pc[-guard],indirect-calls,trace-cmp or both)

Developers may provide the initial file corpus which will be gradually improved upon, but it's not necessary with feedback-driven modes.

软件驱动反馈(software-based coverage-guided fuzzing)

Requirements for software-based coverage-guided fuzzing

  • -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp - Clang >= 5.0
  • -fsanitize-coverage=trace-pc - GCC >= 9.0
  • -fsanitize-coverage=bb - Clang >= 3.7
  • -finstrument-functions - GCC or Clang
  • [older, slower variant] -fsanitize-coverage=trace-pc,indirect-calls - Clang >= 3.9
    Note : The -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp set of flags will be automatically added to clang's command-line switches when using hfuzz-clang binary.

命令示例:

shell 复制代码
$ <honggfuzz_dir>/honggfuzz/hfuzz_cc/hfuzz-clang terminal-test.c -o terminal-test

代码覆盖率

代码覆盖率的计量单位

honggfuzz的代码覆盖计算有三种方式:

  • 函数级(Function-Level)
  • 基本块级(Basic Bolck-Level)
  • 边界级(Edge-Level)

函数级别(Function-Level) 最为粗糙,只记录函数的调用情况。如下代码,其仅会记录function1function2是否执行,而不关心内部if语句的执行情况,使用这种覆盖率统计方式可能会使我们的程序分析丢失一定的分析精度。

因此,常用的是基本块级(Basic Bolck-Level) ,能满足大部分程序分析的精度要求,基本块以跳转指令做为划分依据。如function1代码,此时,会分别记录Block ABlock B的是否执行。当用例a确小于b时仅能触发Block A,而Block B无法覆盖。通过用例变异后续可能产生能访问Block B的测试用例。

c 复制代码
void function1(int a,int b){
... 
	if(a<b){
	//Block A
	}
	else{
	//Block B
	}
...
}

边界级(Edge-Level) 是基本块级更为精细的一种情况。如下代码,if(a)及其上面的语句被划归为Block A,当a==0时才会执行Block A,否则执行Block C。前面基本块的方式就无法确切地知道是否曾从Block A执行到Block C,因为不论是A-B-C还是A直达C,基本块A和C都会被标记为已覆盖。

为了解决这一问题,edge方式会在A-C之间创建一个虚拟块D。以判断是否曾经执行过A直达C路径。

c 复制代码
void function2(int a){
...	//Block A
	if(a){
		a=0;//Block B
	}
	else{
	//Block C
	}
}

代码覆盖率的统计方式

有源码时:

SanitizerCoverage:SanitizerCoverage内置在LLVM中,可以在函数、基本块和边界这些级别上插入对用户定义函数的回调,实现了简单的覆盖率报告和可视化。

  • 添加编译选项(基本块统计方式) CFLAG="-fsanitize=address -fsanitize-coverage=bb"

无源码时:

使用Pin、DynamoRIO等二进制插桩工具去hook统计,或者pediy改指令的方式去监控。

硬件驱动反馈( hardware-based coverage-feedback fuzzing)

【区分为LINUX系和Intel(x86)系】

Linux系:

Requirements for hardware-based counter-based fuzzing

  • GNU/Linux OS
  • A relatively modern Linux kernel (4.2 should be ok)
  • CPU which is supported by the perf subsystem for hardware-assisted instruction and branch counting

Intel系

Requirements for hardware-based coverage-feedback fuzzing (Intel)

  • CPU supporting BTS (Branch Trace Store) for hardware assisted unique pc and edges (branch pairs) counting. Currently it's available only in some newer Intel CPUs (unfortunately no AMD support for now)
  • CPU supporting Intel PT (Processor Tracing) for hardware assisted unique edge (branch pairs) counting. Currently it's available only in some newer Intel CPUs (since Broadwell architecture)
  • GNU/Linux OS with a supported CPU; Intel Core 2 for BTS, Intel Broadwell for Intel PT
  • Intel's ibipt library for Intel PT
  • Linux kernel >= v4.2 for perf AUXTRACE

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

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

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

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

bash 复制代码
apt install linux-tools-common
# 安装好后输入
perf -v
#然后会弹出提示你安装哪些包,根据提示安装对应的包即可。


perf 按照固定的频率去"采样",然后再统计函数的调用次数,算出百分比。只要采样的频率足够大,把这些"瞬时截面"组合在一起,就可以得到进程运行时的可信数据,比较全面地描述出 CPU 使用情况。

输入 top 查看进程的 PID 号

bash 复制代码
$ sudo perf top -K -p 3213 (PID)

4.持久型Fuzzing(Persistent Fuzzing)

如前所述,持久型Fuzzing就是具有长生命周期进程,可重复调用被用以fuzz的API

  • trace-pc: 追踪执行过的基本块BB,在每个edge中插入__saitizer_cov_trace_pc函数,可定义该函数作为相应的回调处理。

  • indirect-calls:在每个间接调用中添加PC追踪,与前面的trace-pctrace-pc-guard联合使用,回调函数:__sanitizer_cov_trace_pc_indir

  • trace-cmp:追踪每个比较指令和swith语句

5. 日志信息

测试时会输出日志信息。

下面是日志信息的源码。

c 复制代码
LOG_I("Size:%zu (i,b,hw,edge,ip,cmp): %" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64
              "/%" PRIu64 "/%" PRIu64 ", Tot:%" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64
              "/%" PRIu64 "/%" PRIu64,
            run->dynamicFileSz, 
            run->linux.hwCnts.cpuInstrCnt, 
            run->linux.hwCnts.cpuBranchCnt,
            run->linux.hwCnts.newBBCnt, 
            softCntEdge, softCntPc, softCntCmp,
            run->global->linux.hwCnts.cpuInstrCnt, 
            run->global->linux.hwCnts.cpuBranchCnt,
            run->global->linux.hwCnts.bbCnt, 
            run->global->linux.hwCnts.softCntEdge,
            run->global->linux.hwCnts.softCntPc, 
            run->global->linux.hwCnts.softCntCmp);

可以看到,输出的信息分别代表单次测试设计的指令数量(cpuInstrCnt)、分支计数(cpuBranchCnt)、新基本块数量newBBCnt)、软件边(softCntEdge)、软件路径(softCntPc)、软件比较次数(softCntCmp)。以Tot:开头的则是整个程序分析的次数。

先写到这,后期继续更。任重道远啊...哎~

相关推荐
cuisidong199716 分钟前
5G学习笔记三之物理层、数据链路层、RRC层协议
笔记·学习·5g
乌恩大侠17 分钟前
5G周边知识笔记
笔记·5g
南宫理的日知录23 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
数据与后端架构提升之路1 小时前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
一行11 小时前
电脑蓝屏debug学习
学习·电脑
咔叽布吉2 小时前
【论文阅读笔记】CamoFormer: Masked Separable Attention for Camouflaged Object Detection
论文阅读·笔记·目标检测
johnny2332 小时前
《大模型应用开发极简入门》笔记
笔记·chatgpt
亦枫Leonlew2 小时前
微积分复习笔记 Calculus Volume 1 - 4.7 Applied Optimization Problems
笔记·数学·微积分·1024程序员节
小肥象不是小飞象2 小时前
(六千字心得笔记)零基础C语言入门第八课——函数(上)
c语言·开发语言·笔记·1024程序员节
星LZX2 小时前
WireShark入门学习笔记
笔记·学习·wireshark