通过静态分析自动化模糊目标发现的框架
对软件进行安全评估的脆弱性研究人员通常会通过AFL ++和LibFuzzer(例如AFL ++和Libfuzzer)来利用覆盖范围引导的模糊功能。这很重要,因为它可以自动化漏洞的过程,并揭示目标的可剥削条件。但是,当遇到大型且复杂的代码库或封闭源二进制文件时,研究人员必须精心努力地手动审核和反向工程,以确定基于模糊的探索可以有用的功能。
Fuzzable是一个与C/C ++源代码和二进制文件集成在一起的框架,以帮助脆弱性研究人员识别可行的模糊功能目标。这是通过应用几种基于静态分析的启发式方法来指出软件中的风险行为以及执行它们的功能来完成的。然后,研究人员可以利用该框架生成基本的线束模板,然后可以用来寻找漏洞,或者作为连续模糊管道的一部分集成,例如Google的OSS-Fuzz Project。
除了作为独立工具运行外,Fuzzable还集成了二进制忍者拆卸器的插件,并支持开发其他拆卸后端。
在此处查看详细介绍该工具的原始博客文章,该文章重点介绍了静态分析启发式方法的技术规格以及该工具的产生方式。该工具还在美国2022年的Black Hat Arsenal美国介绍。
某些二进制目标可能需要进行一些消毒(即签名匹配或从内部识别识别功能),因此可能主要使用二进制忍者作为拆卸后端,因为它具有有效解决这些问题的能力。因此,它可以用作独立工具和插件。
由于二进制忍者并非所有人都可以访问,并且可能需要用于安全评估并可能在云中扩大规模,因此也支持ANGR后备后端。我预计还将将其他拆卸器纳入道路(优先:Ghidra)。
如果您有二进制忍者广告,请确保安装API以进行独立的无头使用:
$ python3 /Applications/Binary Ninja.app/Contents/Resources/scripts/install_api.py
使用pip安装:
$ pip install fuzzable
我们将诗歌用于依赖性管理和建设。要进行手动构建,请使用第三方模块克隆存储库:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
手动安装:
$ cd fuzzable/
# without poetry
$ pip install .
# with poetry
$ poetry install
# with poetry for a development virtualenv
$ poetry shell
现在,您可以使用该工具分析二进制文件和/或源代码!
# analyzing a single shared object library binary
$ fuzzable analyze examples/binaries/libbasic.so
# analyzing a single C source file
$ fuzzable analyze examples/source/libbasic.c
# analyzing a workspace with multiple C/C++ files and headers
$ fuzzable analyze examples/source/source_bundle/
可以通过Binary Ninja > Manage Plugins和搜索它,可以轻松地通过二进制忍者插件市场安装模糊。这是可模糊插件运行的示例,准确性识别用于模糊的目标和进一步的脆弱性评估:

可模仿的可带来各种选择,以帮助更好地调整分析。将来的计划和任何功能请求都将支持更多。
为了确定模糊性,可模仿的方法利用几种启发式方法来确定哪些目标是最可行的动态分析目标。这些启发式方法都使用Scikit-Criteria库对这些启发式方法的加权都不同,该库利用多标准决策分析来确定最佳候选者。这些指标和重量可以在这里看到:
| 启发式 | 描述 | 重量 |
|---|---|---|
| 模糊友好的名字 | 符号名称意味着行为摄入文件/缓冲区输入 | 0.3 |
| 冒险的下沉 | 流向风险的电话的争论(即memcpy) | 0.3 |
| 天然循环 | 用主导边界检测到的循环数量 | 0.05 |
| 循环复杂性 | 基于边缘 +节点的功能目标的复杂性 | 0.05 |
| 覆盖深度 | 目标遍历的量数 | 0.3 |
如前所述,请查看技术博客文章,以了解为什么以及如何使用这些指标。
Vincenzo Iozzo在0-知识模糊中的原始作品的启发,许多指标的启发。
您要分析的每个目标都是多种多样的,而Fuzzable将无法考虑程序目标中的每个边缘案例行为。因此,在分析过程中,适当调整这些权重以查看不同结果是否对您的用例更有意义,这可能很重要。为了调整CLI中的这些权重,只需指定--score-weights参数:
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
默认情况下, Fuzzable将根据以下标准滤除功能目标:
static且不会通过标头暴露的功能。要查看被Fuzzable过滤的呼叫,请设置--list_ignored标志:
$ fuzzable analyze --list-ignored <TARGET>
在Binary Ninja中,您可以在Settings > Fuzzable > List Ignored Calls中转动此设置。
如果可模糊地错误地滤除了应分析的重要呼叫,建议在运行期间使用--include-*参数将其包括在内:
# include ALL non top-level calls that were filtered out
$ fuzzable analyze --include-nontop <TARGET>
# include specific symbols that were filtered out
$ fuzzable analyze --include-sym <SYM> <TARGET>
在Binary Ninja中,通过Settings > Fuzzable > Include non-top level calls和Symbols to Exclude 。
既然您已经找到了理想的候选人来模糊,那么Fuzzable也将帮助您生成(几乎)准备好仪器并与基于文件的Fuzzer(即AFL ++,Honggfuzz)或内存模糊(Libfuzzer)一起使用的模糊安全带。在CLI中这样做:
# generate harness from a candidate
$ fuzzable create-harness target --symbol-name=some_unsafe_call
# make minimal and necessary modifications to the harness
$ vim target_some_unsafe_call_harness.cpp
# example compilation for AFL-QEMU, which is specified in the comments of the generated harness
$ clang target_some_unsafe_call_harness.cpp -no-pie -o target_some_unsafe_call_harness -ldl
# create your base seeds, ideally should be more well-formed for input
$ mkdir in/
$ echo "seed" >> in/seed
# start black box fuzzing
$ afl-fuzz -Q -m none -i in/ -o out/ -- ./target_some_unsafe_call_harness
如果此目标是源代码库,则将使用通用源模板。
如果目标是二进制的,则将使用通用的黑框模板,理想情况下可以与AFL-QEMU这样的模糊仿真模式使用。如果未直接导出该符号以使用lief直接dlopen该符号,则二进制的副本也将作为共享对象创建。
目前,此功能是相当基本的,因为它只会创建一个带有适当参数的独立C ++线束,并且不会自动产生任何运行时行为所需的代码(即实例化和释放结构)。但是,为模糊创建的模板应该使您快速运行。这是我想实现的一些雄心勃勃的功能:
可模糊的支持以各种格式生成报告。当前支持的是JSON,CSV和MARKDOWN。如果您将其用作自动化的一部分,这将很有用,您希望以可序列化格式摄入输出。
在CLI中,只需通过以适当扩展名的文件名传递--export参数:
$ fuzzable analyze --export=report.json <TARGET>
在Binary Ninja中,转到Plugins > Fuzzable > Export Fuzzability Report > ...并选择要导出到的格式以及要将其写入的路径。
该工具将不断开发,并感谢外部壁炉架的任何帮助!
可模糊的可根据麻省理工学院许可获得许可。