GDBFUZZ-使用硬件断点的模糊嵌入式系统

taibeihacker

Moderator
这是使用调试器接口的Paper:“模糊嵌入式系统”的伴随代码。可以在这里找到本文的预印本https://publications.cispa.saarland/3950/。该代码允许用户复制并扩展论文中报告的结果。在报告,复制或扩展结果时,请引用上面的论文。

Folder structure​


├ - ─基准#脚本构建Google的Fuzzer测试套件并运行实验
├ - 依赖项#包含一个用于安装gdbfuzz依赖关系的制作费
├ - ─评估#原始的升温数据,在论文中介绍
├├期example_firmware#嵌入式示例应用程序,用于评估
├├期example_programs#包含一个编译的示例程序和配置,以测试GDBFUZZ
├─.SRC#包含GDBFUZZ的实现
├─.dockerfile#用于创建使用所有GDBFUZZ依赖项创建Docker映像
├─期许可证#许可证
├├─makefile#makefile用于创建Docker映像或本地安装GDBFUZZ
└ - ─-readme.md#this readme文件

Purpose of the project​

GDBFuzz的想法是利用微控制器的硬件断点,作为覆盖范围引导的模糊的反馈。因此,GDB用作通用接口,以实现广泛的适用性。为了对固件进行二进制分析,使用了Ghidra。该代码包含用于评估方法的基准设置。此外,还包括示例固件文件。

Getting Started​

GDBFUZZ启用嵌入式系统的覆盖范围引导的模糊,但是- 出于评估目的,还可以模糊任意用户应用程序。对于微控制器上的模糊,我们建议将GDBFUZZ的本地安装发送到未完整测试的设备上。

Install local​

GDBFuzz已在Ubuntu 20.04 LTS和Raspberry Pie 32位上进行了测试。先决条件是Java和Python3。首先,创建一个新的虚拟环境并安装所有依赖关系。
Virtualenv .venv
源.venv/bin/activate
制作
CHMOD A+X ./src/gdbfuzz/main.py

Run locally on an example program​

GDBFUZZ读取带有以下键的配置文件的设置。
[SUT]
#进入SUT二进制文件的路径。
#例如,这可以是.elf文件或.bin文件。
binary_file_path=路径
#CFG根节点的地址。
#断点放置在此CFG的节点上。
#例如“ llvmfuzzertestoneinput”或“ main”
entrypoint=入口点
#必须执行无断点点击的输入数量直到
#断点是旋转的。
直到_Rotate_breakpoints=数字
#可以在任何给定时间放置的最大断点数。
max_breakpoints=数字
#被忽略的黑名单函数。
#ignore_functions是一个函数名称的空间分离列表,例如“免费malloc”。
ignore_functions=空间分离列表
#一个{硬件,Qemu,sutrunsonhost}
#Hardware:外部组件启动了GDB服务器,GDBFuzz可以连接到此GDB服务器。
#QEMU: GDBFUZZ启动QEMU。 QEMU模拟binary_file_path并启动gdbserver。
#SutrunsonHost: GDBFUZZ在GDB中启动目标程序。
target_mode=模式
#如果要启动ghidra,请分析SUT,将此设置为False,
#并手动启动Ghidra Bridge服务器。
start_ghidra=true
#空间分开的地址列表,其中软件断点(错误
#处理代码)设置。执行这些被认为是崩溃。
#example: software_breakpoint_addresses=0x1230x432
Software_BreakPoint_Addresses=
#是否将所有触发的软件断点视为崩溃
acvice_sw_breakpoint_as_error=false
[sutConnection]
#类“ sut_connection_class'in file'sut_connection_path'instrument
#如何将输入发送到SUT。
#输入可以通过Wi-Fi,串行,蓝牙发送,
#此类必须从./connections/sutconnection.py继承。
#有关更多信息,请参见./connections/sutconnection.py。
sut_connection_file=fifoconnection.py
[GDB]
path_to_gdb=gdb-multiarch
#在地址:PORT中撰写
gdb_server_address=localhost:4242
[Fuzzer]
#在字节中
maxture_input_length=100000
#在几秒钟内
single_run_timeout=20
#在几秒钟内
total_runtime=3600
#选修的
#通往每个文件包含一个种子的目录的路径。如果你不想
#使用种子,将值留为空。
seeds_directory=
[BreakpointStrategy]
#选择基本块的策略位于
#'src/gdbfuzz/breakpoint_strategies/'
#对于论文,我们使用以下策略
#'randombasicblockstrategy.py' - 随机选择未接触的基本块
#'randombasicblocknodomstrategy.py' - 像以前一样,但不利用优势关系来传递传递的节点。
# 'RandomBasicBlockNoCorpusStrategy.py' - Like first, but prevents growing the input corpus and therefore behaves like blackbox fuzzing with coverage measurement.
#“ blackboxstrategy.py', - 未设置任何断点
Breakpoint_strategy_file=randombasicblockstrategy.py
[依赖关系]
path_to_qemu=依赖项/qemu/build/x86_64-linux-user/qemu-x86_64
path_to_ghidra=依赖项/ghidra
[logsandvisualization]
#{调试,信息,警告,错误,关键}之一
loglevel=信息
#通往输出文件(例如图形,logfiles)的目录的路径。
output_directory=./output
#如果设置为true,则MQTT客户端发送UI元素(例如图形)
enable_UI=False An example config file is located in ./example_programs/together with an example program that was compiled using our fuzzing harness in benchmark/benchSUTs/GDBFuzz_wrapper/common/.通过以下命令开始融合一个小时。
chmod a+x ./example_programs/json-2017-02-12
./src/GDBFuzz/main.py --config ./example_programs/fuzz_json.cfg We first see output from Ghidra analyzing the binary executable and rarely messages when breakpoints are relocated or hit.

Fuzzing Output​

取决于配置文件中指定的output_directory,现在应该有一个文件夹试用-0具有以下结构

├ - 语料库#包含输入语料库的文件夹。
├──崩溃#一个包含崩溃输入的文件夹- 如果有的话。
CFG#控制流程图作为邻接列表。
├ - 。fuzzer_stats#模糊活动的统计数据。
├ - plot_data#表显示了在模糊活动中哪个相对时间到达哪个基本块。
├ - reverse_cfg#反向控制流程图。

Using Ghidra in GUI mode​

通过设置start_ghidra=false在配置文件中,gdbfuzz连接到在GUI模式下运行的ghidra实例。因此,需要从脚本管理器手动启动Ghidra_bridge插件。在模糊过程中,到达的程序块以绿色突出显示。

GDBFuzz on Linux user programs​

For fuzzing on Linux user applications, GDBFuzz leverages the standard LLVMFuzzOneInput entrypoint that is used by almost all fuzzers like AFL, AFL++, libFuzzer, In benchmark/benchSUTs/GDBFuzz_wrapper/common There is a wrapper that can be used to compile any compliant fuzz harness into a独立程序通过/tmp /frofgdbfuzz通过命名管道获取输入。这允许模拟嵌入式设备,该设备通过定义明确的输入接口消耗数据,因此在任何应用程序上运行GDBFUZZ。为了方便起见,我们在基准/台式的脚本中创建了一个脚本,该脚本将与包装器评估中的所有程序一起编译,如稍后所述。
NOTE:GDBFUZZ不打算fuzz Linux用户应用程序。因此,请使用AFL ++或其他模糊器。包装器只是出于评估目的而存在,可以在规模上运行基准和比较!

Install and run in a Docker container​

The general effect of our approach is shown in a large scale benchmark deployed as docker containers.
使DockErimage在Docker容器中运行上述实验(按照配置文件中指定的一个小时),将示例_程序和输出文件夹映射为卷,然后按以下方式启动GDBFUZZ。
chmod a+x ./example_programs/json-2017-02-12
docker run -it --env CONFIG_FILE=/example_programs/fuzz_json_docker_qemu.cfg -v $(pwd)/example_programs:/example_programs -v $(pwd)/output:/output gdbfuzz:1.0 An output folder should appear in the current working directory with the structure explained above.

Detailed Instructions​

我们的评估分为两部分。 1。直接在硬件上的预期设置上的gdbfuzz。 2。在模拟环境中GDBFUZZ,以允许对结果进行独立的分析和比较。
GDBFuzz可以与任何GDB服务器一起使用,因此对于微控制器的大多数调试探针。

GDBFuzz vs. Blackbox (RQ1)​

注册RQ1从论文中,我们在example_firmware中使用不同的firmwares的不同微控制器上执行GDBFUZZ。对于每个实验,我们都会使用randombasicblock和randombasicblocknocorpus策略运行GDBFUZZ。后者的行为就像没有反馈的那样模糊,但我们仍然可以衡量所达到的覆盖范围。为了回答RQ1,我们比较了Randombasicblock和Randombasicblocknocorpus策略的覆盖范围。相应的配置文件位于相应的子文件夹中,我们现在说明如何在四个开发板上设置模糊。

GDBFuzz on STM32 B-L4S5I-IOT01A board​

GDBFUZZ需要访问GDB服务器。在这种情况下,使用B-L4S5I-IOT1A及其车载调试器。此机上调试器通过“ ST-Util”程序设置了GDB服务器,并可以通过LocalHost:4242访问该GDB服务器。
通过USB安装stlink驱动程序链接链接MCU板和PC(在MCU板上,连接到标记为'US的USB连接器
 
返回
上方