一款多平台模糊测试工具,用于探测用户态二进制文件、客户端和服务器。
它已在高知名公司和开源项目的 50+ 应用和库 中发现漏洞。
简单设置即可在 Linux、Mac 和 Windows 上开始模糊测试。
Litefuzz 旨在服务于一个目的:在所有主流平台上进行模糊测试和分类,支持 CLI/GUI 应用、网络客户端和服务器,以发现安全相关的漏洞。
它简化了流程,使得在不同平台、多种目标中轻松发现安全漏洞,同时仅做出一些诚实的权衡。
它不是为速度、可扩展性或为了在学术界获奖而构建的。它通过从不同角度应用简单技术来产生结果。对于控制台文件模糊测试,你可能应该直接使用 AFL。它具有卓越的性能、检测能力(以及更快的非检测执行)、扩展性,并且可以从 无中生有 生成 JPEG 图片。对于网络模糊测试,如果你有 PCAP 文件需要重放,mutiny fuzzer 也表现良好,frizzer 看起来也很有前景。但如果你想尝试这个工具,它可以用单一工具跨平台模糊测试这些类型的目标。
./ 给你的目标来一次……轻量模糊测试。``` $ sudo apt install -y latex2rtf
$ ./litefuzz.py -l -c "latex2rtf FUZZ" -i input/tex -o crashes/latex2rtf -n 1000 -z --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 3516 cmdline: latex2rtf FUZZ crash dir: crashes/latex2rtf input dir: input/tex inputs: 1 iterations: 1000 mutator: random(mutators)
@ 1000/1000 (3 crashes, 127 duplicates, ~0:00:00 remaining)
[RESULTS]
completed (1000) iterations with (3) unique crashes and 127 dups
check crashes/latex2rtf for more details
这是一个简单的本地目标,AFL++ 完全有能力处理,这里仅作为示例快速给出。Litefuzz 的设计初衷更多是用于网络和 GUI 模糊测试,您深入了解后会看到这一点。
## 为什么
是的,又一款模糊测试器,而且它并不完全符合当前的趋势和惯例。为了满足某些需求,我们做出了一些权衡。这些需求包括:一款默认就能在多个平台上工作、既能模糊测试本地目标也能测试网络目标、并且非常易于使用的模糊测试器。并不是要说服任何人什么,但让我们提供一些背景信息。有些目标需要花费大量精力才能将 AFL 等模糊测试器集成到构建链中。这不是问题,因为本模糊测试器不需要插桩,牺牲了插桩带来的精确覆盖率,换取了易用性和可移植性。AFL 也不原生支持网络模糊测试,虽然有些基于它的项目支持,但它们使用起来远非直接简单,通常需要更多的代码修改和 harness 才能工作([Libfuzzer](https://llvm.org/docs/LibFuzzer.html) 的情况类似)。
它不支持并行模糊测试,也不支持像[持久模式](https://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html)那样能带来惊人速度提升的功能,因此它的扩展能力远不及那些具备这些功能的模糊测试器。再次强调,这不是一款最先进的模糊测试器。但它不需要源代码、不需要正确配置构建系统,也不需要特定的操作系统特性。它甚至可以模糊测试某些网络客户端 GUI 和交互式应用程序。它在很大程度上“就地取材”,许多功能(如变异器和最小化)都是从零开始编写的。
它的设计理念是“拿来即用”,并且我们投入了精力来自动化设置和安装其所需的少数依赖项。这款模糊测试器的编写是为了服务于某个目的,即在许多不同的目标场景和环境中提供价值,而最重要的是,所有模糊测试器最终都应该根据这一点来评判:发现漏洞的能力。而且,它**确实发现了**[漏洞](https://github.com/sec-tools/beta/blob/main/README.md#trophies)。它不假设存在目标源代码,因此可以很好地覆盖闭源软件。它只需少量修改就可以作为自动化的一部分运行,但它的设计初衷是让漏洞研究人员觉得有趣易用。不过,将其视为一个研发项目而非一个完全成熟的产品会更有帮助。另外,它没有那种开箱即用就有点问题、或者需要在现代操作系统上花更多功夫才能运行的复杂设置。
它已在 Ubuntu Linux、Mac 和 Windows 上测试通过,并附带了功能齐全的脚本,这些脚本几乎可以为您完成所有设置,以便搭建一个随时可以进行模糊测试的环境。
**设置脚本完成后,只需几分钟即可开始模糊测试大量不同的目标。**
## 工作原理
**Litefuzz 支持三种模式:本地、客户端和服务器。**
本地模式针对本地二进制文件,在 Linux/Mac 上通过子进程启动,并分别在崩溃时自动使用 GDB 和 LLDB 进行分类,在 Windows 上则使用 [WinAppDbg](https://github.com/MarioVilas/winappdbg)。崩溃信息写入本地崩溃目录,并按故障类型(如读/写访问违规或 SIGABRT/SIGSEGV)以及文件哈希值进行排序。在模糊测试过程中,所有独特的崩溃都会被分类,这些数据以及目标输出(如果有)也会被捕获并作为工件放在同一目录中。也可以使用 `--replay` 并提供崩溃文件来重放崩溃。在 `local` 客户端模式下,输入目录应包含服务器问候语、响应或其他客户端在连接服务器时预期的数据。
目前,网络模糊测试只实现了一次“发送”,没有复杂的会话支持。客户端通过命令行启动,其调试方式与文件模糊测试相同。会设置一个监听器来支持这种场景,是的,这很慢,而且几乎算是手工劳动,但它确实有效。如果检测到崩溃,会在 gdb 中重放以获取分类详情。在 `remote` 客户端模式下,工作方式相同,只是没有本地调试/崩溃分类。在 *local* 服务器模式下,它类似于 local 客户端模式;对于 `remote` 服务器模式,它只需连接到指定目标,并发送用户指定的变异后的样本客户端数据作为输入,但只提供简单的“我们还能连接吗?如果不能,则说明上一次发送可能导致了崩溃”这样的分类。
有几个从零编写的变异函数,它们主要进行随机变异,并从 `-i` 标志指定的输入中随机选择。对于文件模糊测试,只需选择本地模式,并传入目标命令行,用 FUZZ 表示应用程序期望文件名解析的位置,例如 `tcpdump -r FUZZ`,同时提供一个包含要变异的“好文件”的输入目录。对于网络客户端模糊测试,与本地模糊测试类似,但还需要通过 `-a` 提供连接细节。如果您想模糊测试服务器,则使用服务器模式,并提供 `protocol://address:port`,就像客户端一样。
它的模糊测试速度取决于目标消费数据并退出的速度,例如大多数 CLI 应用程序的情况,或者取决于您确定的本地执行或网络连接超时所需的时间,这可能慢得多。这里没有花哨的 exec 或内核技巧。当然,如果您编写一个能快速解析输入并退出的 harness,覆盖目标的特定部分,那也会有帮助。但到了那个程度,如果您能如此接近目标,那么您可能更应该使用[持久模式](https://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html)或其他模糊测试器提供的类似功能。
简而言之...
### 它能做什么
- 在 Linux、Windows 和 Mac 上运行,支持 py2/py3
- 模糊测试读取文件/stdin 的 CLI/GUI 二进制文件
- 模糊测试网络客户端和服务器,无论是开源还是专有,支持本地调试或远程调试
- 崩溃的差异分析、最小化、重放、排序和自动分类
- 其他功能,如 TLS 支持、Golang 二进制文件模糊测试以及一些 Mac 专属功能
- 使用多种内置变异器 + pyradamsa(Linux)对输入进行变异
### 它不能做什么
- 原生插桩
- 通过并发任务进行扩展
- 复杂会话模糊测试
- 远程客户端和服务器监控(仅支持基本检查,如能否连接)
## 支持
主要在 **Ubuntu Linux 20.04**(22.04 和 21.04 进行过少量测试)、**Windows 10** 和 **Mac OS 11**(12 进行过少量测试)上进行了测试。该模糊测试器和设置脚本也可能在这些操作系统的略微早期或更新版本上工作,但大部分研究、测试和开发都在这些环境中进行。支持 Python3,并且努力使代码兼容 Python2,因为通过 [WinAppDbg](https://github.com/MarioVilas/winappdbg) 在 Windows 上进行模糊测试需要 Python2。
平台测试主要在基于 Intel 的硬件上进行,但事情似乎在 Apple 的 M1 平台上也能基本工作(明显的例外是 Linux 上的 GDB exploitable 插件可能不受支持,Pyradamsa 也不支持)。setup/ 目录下也有设置脚本,可以自动化大部分或全部任务和依赖项安装。它通常可以在每个平台上模糊测试原生二进制文件,这些文件通常用 C/C++ 编译,但也可以捕获 Golang 二进制文件的崩溃(实验性功能)。
### Python 版本
Linux 和 Mac 支持 Python3,而 Windows 需要 Python2。
为什么 Linux 和 Mac 用 Python3?Pyautogui、Pyradamsa(仅 Linux)、Mac 上更好的 socket 支持。
为什么 Windows 用 Python2?Winappdbg 需要 Python2。
### Linux
使用 GDB 进行调试,使用 [exploitable](https://github.com/jfoote/exploitable) 进行崩溃分类。如果是开源软件,可以用[消毒剂](https://fuzzing-project.org/tutorial2.html)等构建和插桩目标,否则有一些[内存调试器](https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Heap_corruption)可以在运行时加载。
此安装以及 Python 依赖项和其他有用的东西已通过 [setup/linux.sh](https://github.com/sec-tools/litefuzz/blob/main/setup/linux.sh) 实现了自动化。推荐的操作系统是 Ubuntu 20.04,因为大部分测试都在该环境中进行。
### Mac
在 OS X 上,我们使用 lldb 而不是 gdb 进行调试,因为它包含在 XCode 命令行工具中。作为管理员或属于开发者组应该可以使用 lldb,但这个行为可能因环境和版本而异,如果其他方法都失败,您可能需要使用 sudo 权限运行它。
您需要手动做的一件事是关闭 SIP(在恢复模式下,通过 cmd+R 或使用 VMware fusion 技巧)。否则,在 Tim Apple 的操作系统上进行模糊测试时,自动分类会失败。
大部分设置已通过 [setup/mac.sh](https://github.com/sec-tools/litefuzz/blob/main/setup/mac.sh) 脚本自动化,因此您可以直接运行它以快速开始。
### Windows
[WinAppDbg](https://github.com/MarioVilas/winappdbg) 用于在 Windows 上进行调试,但有一点小瑕疵:不支持 stdin 模糊测试。
与其他操作系统的自动设置类似,chocolatey 有助于在 Windows 上自动化软件包安装。以管理员身份在 litefuzz 根目录下运行 [setup/windows.bat](https://github.com/sec-tools/litefuzz/blob/main/setup/windows.bat) 以自动化安装。它将安装调试工具和其他依赖项,使一切顺利运行。
### 目标
这是已经测试过并通常支持的目标类型列表。
* 解析文件格式或 stdin 的本地 CLI/GUI 应用程序
- 支持调试
* 解析服务器响应的本地 CLI/GUI 网络客户端
- 支持 CLI 的调试
- 对 GUI 的调试支持有限
* 解析客户端请求的本地 CLI 网络服务器
- 支持调试(注意:必须能够作为独立可执行文件运行,否则可视为 *remote*)
* 解析客户端请求的本地 GUI 网络服务器
- 理论上支持,未经测试
* 解析服务器响应的远程 CLI/GUI 网络客户端
- 不支持调试
* 解析客户端请求的远程 CLI/GUI 网络服务器
- 不支持调试
- 例外情况是使用 Mac 上的 `attach` 或 `reportcrash` 功能
再次说明,该模糊测试器可以在 Linux、Mac 和 Windows 上运行并支持本地应用程序、客户端和服务器,当然也可以独立于目标平台来模糊测试远程内容。
### 分类
* 解析文件格式或 stdin 的本地 CLI/GUI 应用程序
- 运行应用程序,捕获信号,通过使用触发崩溃的文件在调试器中再次运行来复现
* 解析服务器响应的本地 CLI/GUI 网络客户端
- 运行应用程序,捕获信号,通过使用触发崩溃的文件在调试器中再次运行来复现
* 解析客户端请求的本地 GUI/CLI 网络服务器
- 在调试器中运行应用程序,捕获信号,通过使用触发崩溃的文件在调试器中再次运行来复现
* 解析服务器响应的远程 CLI/GUI 网络客户端
- 没有可见性,从远程端收集崩溃信息
- 可以手动编写辅助脚本以协助分类
* 解析客户端请求的远程 CLI/GUI 网络服务器
- 没有可见性,从远程端收集崩溃信息
- 可以手动编写辅助脚本以协助分类
- Mac 上的例外是 `attach` 和 `reportcrash` 选项,可用于启用一些分类功能
## 快速开始
跨平台的大部分设置已通过 [setup](https://github.com/sec-tools/litefuzz/blob/main/README.md#setup) 目录中的脚本实现自动化。
只需从 litefuzz 根目录运行这些脚本,这可以节省大量时间,并有助于实现自动化部署所需的部分功能。使用虚拟机来搭建一个干净的操作系统和模糊测试环境是很有用的,因为其快照功能也非常方便。
详情请参阅 [INSTALL.md](https://github.com/sec-tools/litefuzz/blob/main/INSTALL.md)。
**安装完成后,请参考初始部分中关于 latex2rtf 的模糊测试示例进行快速运行,或者深入了解本 README 中详述的所有命令行选项和更多示例。**
### Docker
您可以使用 `Dockerfile` 通过 Docker 运行 litefuzz,而无需在本地安装依赖项。这对于快速测试或希望避免在系统上安装依赖项时特别有用。
Dockerfile 有两种工作方式:
- **从仓库内部** - 使用本地文件(更快,包含本地更改)
- **独立使用** - 可以从任何目录构建(从 GitHub 克隆)```bash
# Build the Docker image (from any directory with Dockerfile)
docker build -t litefuzz:latest .
# Run litefuzz
docker run --rm litefuzz:latest python3 litefuzz.py --help
仓库中的内置输入位于 /litefuzz/input/tex - 无需挂载输入:```bash
mkdir -p crashes
docker run --rm
-v $(pwd)/crashes:/tmp/crashes
litefuzz:latest
python3 litefuzz.py -l -c "latex2rtf FUZZ" -i /litefuzz/input/tex -o /tmp/crashes -n 1000 -z
这将:
- 使用1000次迭代对latex2rtf进行模糊测试
- 启用堆调试(`-z`标志)
- 将崩溃保存到主机上的`./crashes`目录
- 使用仓库中内置的输入文件,位于`/litefuzz/input/tex`
如果您想使用主机上自己的输入文件:```bash
# Create input directory with your test files
mkdir -p input/tex crashes
# Add your test files to input/tex/
cp your-test.tex input/tex/
# Run fuzzing with your input files
docker run --rm \
-v $(pwd)/input:/litefuzz/input \
-v $(pwd)/crashes:/tmp/crashes \
litefuzz:latest \
python3 litefuzz.py -l -c "latex2rtf FUZZ" -i /litefuzz/input/tex -o /tmp/crashes -n 1000 -z
重要: 仅当你有文件要使用时才挂载输入。挂载空的 input/ 目录会覆盖内置输入并导致错误。
/litefuzz/input/tex(无需挂载)-v 挂载卷以持久化崩溃输出并访问输入文件--network host 进行网络模糊测试以访问本地服务--cap-add=SYS_PTRACE有一些简单的单元和功能测试来为 Litefuzz 提供一些覆盖率,但它并不旨在完整。``` py2> pytest py3> python3 -m pytest
This will run pytest for `test_litefuzz.py` in the main directory and provide PASS/FAIL results once the test run is finished.
#### 崩溃应用测试
在 `test` 文件夹中可以找到一些用于测试不同平台上的崩溃和分类能力的缺陷应用示例。
- (a) 空指针解引用
- (b) 除零错误
- (c) 堆溢出
- (d-gui) GUI 中的格式字符串漏洞
- (e) 客户端缓冲区溢出
- (f) 服务端缓冲区溢出
它们在设置过程中自动构建,你可以在命令行、调试器中运行它们,或者用作模糊测试目标。
**如果在 Windows 命令行上运行,请检查 `事件查看器 -> Windows 日志 -> 应用程序` 以查看崩溃。**
## 选项
有大量不同的选项和功能可用于各种目标场景。以下是对它们的简要解释和一些示例,以帮助理解如何使用它们。
### 崩溃目录
`-o` 允许你指定一个非默认的崩溃目录,默认是本地路径下的 crashes/。你可以用这个来管理同时进行的多个模糊测试运行(针对不同应用)的崩溃文件夹。
### 隔离模式
`-u` 将目标应用程序与正常的模糊测试过程隔离开,例如反复执行或发送数据包并检查崩溃。相反,此模式是为交互式客户端应用程序设计的,例如 Postman,你可以在应用程序内部编写脚本以重复连接来进行客户端模糊测试。目标在调试器内运行,模糊测试暂停以给用户时间点击几个按钮或设置目标的配置使其自动运行,用户恢复后,你就在模糊测试交互式网络客户端了。
`litefuzz -lk -c "/snap/postman/140/usr/share/Postman/_Postman" -i input/http_responses -a tcp://localhost:8080 -u -n 100000 -z`
隔离模式 + 刷新可用于交互式客户端,例如在调试器中运行 FileZilla,但不断按 F5 使其为每次新迭代重新连接到服务器。此外,模糊测试本地 CLI/GUI 服务器仅启动并在调试器内运行一次,以使过程更高效一些。
`--key` 还允许你在模糊测试交互式目标时发送按键,例如通过发送 F5 的“刷新连接”来模糊测试 FileZilla 对 FTP 服务器响应的解析。
`litefuzz -lk -c "filezilla" -a tcp://localhost:2121 -i input/ftp/filezilla -u -pp --key "F5" -n 100 -z glibc`
注意:隔离模式仅在 Linux 上测试过,在 Windows 上不支持。
### 超时
`-x secs` 允许你指定超时时间。在实践中,对于 CLI 目标,这更像是“迭代之间的近似时间间隔”,而对于 GUI 则是实际的超时时间。
### 变异器
`--mutator N` 指定用于模糊测试的变异器。如果未提供该选项,则每次模糊测试迭代都会从可用变异器列表中随机选择一个。
这些变异器是从头开始编写的(当然 Radamsa 除外)。虽然它们经过了广泛的测试并在数百万次迭代中表现良好,但偶尔可能会有细微的 bug,但通常这不会影响功能。```
FLIP_MUTATOR = 1
HIGHLOW_MUTATOR = 2
INSERT_MUTATOR = 3
REMOVE_MUTATOR = 4
CARVE_MUTATOR = 5
OVERWRITE_MUTATOR = 6
RADAMSA_MUTATOR = 7
注意:Radamsa 变异器仅在 Linux(+ Python 3)上可用。
--reportcrash 是 macOS 专有的。它指导模糊测试工具监控 ReportCrash 目录以获取目标进程的崩溃日志,而不是使用默认的分类系统。ReportCrash 必须在 OS X 上启用(默认启用,但在常规模糊测试中通常被禁用)。该功能在我们无法在调试器中运行目标以生成并分类我们自己的崩溃日志的场景中非常有用,但我们可以利用操作系统上的这个核心功能来获得可见性。
注意:此功能被视为实验性,因为我们依赖一些我们无法直接控制的 macOS 核心系统中的活动和组件。ReportCrash 在模糊测试一段时间后可能会停止正常工作并响应,即使尝试卸载并重新加载它也是如此。因此,可以尝试重启机器或重置快照以使其恢复正常状态。``` sudo launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist sudo launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
### 暂停
按Ctrl+C暂停模糊测试过程。若要继续,选择`y`或`n`停止。此功能在各平台上运行良好,但在对GUI应用进行模糊测试时可能不太可靠。
### 复用崩溃以发现变体
`-e`启用复用模式。这意味着如果在模糊测试运行中发现任何崩溃,它们将被用作第二轮模糊测试的输入,有助于发现更多bug。结合`-z`使用,产生`-ez` bug!棒极了。
以下示例对antiword进行100000次迭代的模糊测试,然后以相同的迭代次数和选项开始另一轮运行,复用崩溃作为输入,以尝试挖掘出更多的bug。
`litefuzz -l -c "antiword FUZZ" -i docs -n 100000 -ez`
(或者手动将崩溃复制到输入目录,以直接控制复用运行的迭代次数)
`litefuzz -l -c "antiword FUZZ" -i docs-crashes -n 500000 -z`
注意:此模式仅支持本地应用。
### 内存调试辅助工具
`-z`在Linux上启用Electric Fence(或回退到glib malloc调试),在Mac上启用Guard Malloc,在Windows上启用PageHeap。此外,`-zz`可用于在对应用程序启用PageHeap后将其禁用。如果只想在不启动模糊测试器的情况下开关它,只需省略`-i`标志。在Windows设置过程中,会安装[gsudo](https://github.com/gerardog/gsudo),可用于在命令行上运行提升权限的命令,例如为目标开启PageHeap。
`sudo litefuzz -l -c "notepad FUZZ" -i texts/files -z`
`sudo litefuzz -l -c "notepad FUZZ" -zz`
在Linux上,可以选择特定的辅助工具。例如,不仅仅将glib malloc用作回退,而是直接选择它。
`litefuzz -l -c "geany FUZZ" -i texts/codes -z glibc`
默认的Electric Fence malloc调试器很不错,但它不适用于所有目标。你可以用EF测试目标,如果崩溃,则改选glibc辅助工具。
### 检查实时目标输出
如果在Linux或Mac上对本地应用进行模糊测试,可以执行`cat /tmp/litefuzz/RUN_ID/fuzz.out`来查看目标的最新标准输出。`RUN_ID`在模糊测试开始时显示在STATS信息区域。如果发生崩溃,标准输出也会作为`.out`文件捕获到崩溃目录中。全局标准输出/错误也会输出到`/tmp/litefuzz/out`用于调试目的,适用于所有模糊测试目标,但隔离模式或本地服务器模式下调试器输出会进入`/tmp/litefuzz/RUN_ID/out`。
Winappdbg本身不支持捕获目标的标准输出(据我所知),因此此功能在Windows上不可用。
### 客户端和服务器模式
如果服务器可以通过简单地执行二进制文件(带或不带某些标志和配置)在本地运行,你可以通过`-c`传递其命令行,它将会被启动、模糊测试,并在每次迭代中杀死并重新执行。这样做的目的是以速度换取避免那些只在目标内存处于“某种状态”时触发的烦人bug的能力,这些bug可能导致误报。本地模糊测试网络客户端也是如此。它甚至支持TLS连接,即时生成证书(允许用户在模糊测试需要客户端证书的服务器时提供客户端证书,以及证书模糊测试本身是其他的想法)。
在对远程客户端和服务器进行模糊测试时,Litefuzz不提供调试支持,因此远程端的设置由用户负责。对于服务器,我们仅检查服务器是否停止响应,并将前一个有效负载记为崩溃器。这对于TCP连接效果良好,但对于UDP服务我们并不具备这种便利,因此监控远程服务器要么依赖于ReportCrash功能(在Mac上可用),要么在调试器中运行目标(通过本地服务器模式或手动),要么编写自定义支持脚本。此外,有些服务器可能自动重启或以其他方式在崩溃后恢复,但日志或文件系统上的其他工件中可能存在相关迹象,可由针对特定目标编写的支持脚本解析。
### 本地网络示例
`litefuzz -lk -c "wget http://localhost:8080" -a tcp://localhost:8080 -i input/http -z`
`litefuzz -lk -c "curl -k https://localhost:8080" -a tcp://localhost:8080 -i input/http -z`
`litefuzz -lk -c "curl -k https://localhost:8080" -a tcp://localhost:8080 -i input/http -o crashes/curl --tls -n 100000 -z`
(打开Wireshark并捕获来自
d的响应,右键单击简单网络管理协议 -> 导出分组字节流 -> resp.bin)
`litefuzz -lk -c "snmpwalk -v 2c -c public localhost:1616 1.3.6.1.2.1.1.1" -a udp://localhost:1616 -i input/snmp/resp.bin -n 1 -d -x 3`
`litefuzz -ls -c "./sc_serv shoutcast.conf" -a localhost:8000 -i input/shouts -z`
`litefuzz -ls -c "snmpd" -i input/snmp -a udp://localhost:161 -z`
**快速说明**
- UDP套接字在Mac + Py2上可能表现异常,因此仅测试和支持Mac + Py3
- Windows上的本地网络客户端模糊测试可能存在bug,目前应视为实验性功能
### 远程网络示例
对远程客户端和服务器进行模糊测试更有挑战性:我们没有本地调试,依赖于捕获双方通过网络交互的中断来发现崩溃。此外,由于我们假设对方发生了什么并不知情,当客户端或服务器停止响应时模糊测试结束,需要在客户端或服务器恢复到正常(未崩溃)状态后手动重启,除非用户在远程端设置了脚本来管理这个过程。
UDP使情况更加复杂。即使发送一个测试包来检查UDP端口上是否有监听服务,也不能保证有回复。因此可以远程模糊测试网络客户端和服务器,但需要在可见性上做出权衡。
#### 客户端
`while :; do echo "user test\rpass test\rls\rbye\r" | ftp localhost 2121; sleep 1; done`
`litefuzz -k -i input/ftp/test -a tcp://localhost:2121 -pp -n 100`
客户端模式在这里更加棘手,因为很难判断客户端是实际崩溃导致无法重连,还是由于不同客户端处理连接的方式各异导致发送/接收配合出现问题。另请注意,这只是一个示例,远程客户端模糊测试本质上有难度,应视为有一定实验性的功能。
#### 服务器
本地或远程模糊测试服务器的优缺点可以帮助你在两种选项都可用时决定如何对待目标。
基本上,在调试器中对服务器进行模糊测试会更慢,但能够获得带有自动分类的崩溃日志;而在远程模式下对服务器进行模糊测试(即使指向本地主机)平均速度会快得多,但你会失去高可见性、基于调试器的分类能力,但可以让你在每次崩溃后手动重启服务器以继续运行,直到它退出(仅限TCP服务器,该功能不支持基于UDP的服务器)。
**Shoutcast**
`./sc_serv ...`
`litefuzz -s -a localhost:8000 -i input/shouts -n 10000`
**SSHesame**
`sshesame`
`litefuzz -s -a tcp://target:2022 -i input/ssh-server -p -n 1000000 -x 0.05`
**FTP**
`litefuzz -s -a tcp://target:21 -i input/ftp/req.txt -pp -n 1000`
**DNS**
`coredns -dns.port 10000`
`litefuzz -ls -c "coredns -dns.port 10000" -a udp://localhost:10000 -i dns-req/1.bin -o crashes/coredns -n 10000`
或
`litefuzz -s -a udp://localhost:10000 -i dns-req/1.bin -o crashes/coredns -n 10000`
##### TLS
`litefuzz -s -a tcp://hostname:8080 -i input/http --tls -n 10000````
...
@ 48/10000 (1 crashes, 0 duplicates, ~7:13:18 remaining)
[!] check target, sleeping for 60 seconds before attempting to continue fuzzing...
注意:默认的远程服务器模式在模糊测试迭代之间添加延迟,可使模糊测试会话可靠运行,但速度较慢;这是安全的默认设置,但如果目标能够快速解析数据包,则可以使用 -x 设置在会话之间非常快的超时(如上所示),非官方地称为 "2fast2furious" 模式
有关基于会话的协议(如 FTP 或 SSH)的更多信息,请参阅 Multiple 模式。
-p 用于多二进制数据模式,允许提供顺序输入,例如 input/ssh 目录包含名为 "1"、"2"、"3" 等的文件,每个文件对应会话中要模糊测试的数据包。这旨在实现对基于二进制的协议实现(如 SSH 客户端)的模糊测试。
ls input/ssh
1 2 3 4
`xxd input/ssh/2 | head```` 00000000: 0000 041c 0a14 56ff 1297 dcf4 672d d5c9 ......V.....g-.. 00000010: d0ab a781 dfcb 0000 00e6 6375 7276 6532 ..........curve2 00000020: 3535 3139 2d73 6861 3235 362c 6375 7276 5519-sha256,curv 00000030: 6532 3535 3139 2d73 6861 3235 3640 6c69 e25519-sha256@li 00000040: 6273 7368 2e6f 7267 2c65 6364 682d 7368 bssh.org,ecdh-sh 00000050: 6132 2d6e 6973 7470 3235 362c 6563 6468 a2-nistp256,ecdh 00000060: 2d73 6861 322d 6e69 7374 7033 3834 2c65 -sha2-nistp384,e 00000070: 6364 682d 7368 6132 2d6e 6973 7470 3532 cdh-sha2-nistp52 00000080: 312c 6469 6666 6965 2d68 656c 6c6d 616e 1,diffie-hellman 00000090: 2d67 726f 7570 2d65 7863 6861 6e67 652d -group-exchange-
每个数据包被消费到一个数组中,随机索引被变异并重放以模糊测试目标。
`litefuzz -lk -c "ssh -T test@localhost -p 2222" -a tcp://localhost:2222 -i input/ssh -o crashes/ssh -p -n 250000 -z glibc`
并且你可以检查目标的最新迭代输出。```
cat /tmp/litefuzz/out
kex_input_kexinit: discard proposal: string is too large
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: string is too large
... and others like
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: unknown or unsupported key type
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Host key verification failed.
Bad packet length 1869636974.
ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: message authentication code incorrect
-pp 参数指示模糊测试器检查输入中是否有换行符,如果检测到,则将它们视为多个请求/响应。这对于主要基于字符串的协议实现(例如 FTP 客户端)的简单网络协议模糊测试非常有用。```
cat input/ftp/test
220 ProFTPD Server (Debian) [::ffff:localhost]
331 Password required for user
230 User user logged in
215 UNIX Type: L8
221 Goodbye
模糊测试器将每一行拆分为自己的FTP响应,以尝试模糊客户端对会话的处理。然而,不能保证客户端会“表现良好”或以允许会话正确完成的方式运行,因此在运行Wireshark时对会话测试用例进行一些试错和微调,有助于理解目标之间交互的差异。
`litefuzz -lk -c "ftp localhost 2121" -a tcp://localhost:2121 -i input/ftp -o crashes/ftp -n 100000 -pp -z`
这也可以与 *-u* 结合使用,用于隔离GUI网络目标,例如FileZilla。
`litefuzz -lk -c "filezilla" -a tcp://localhost:2121 -i input/ftp.resp -n 100000 -u -pp -z glibc`
### 附加到进程
如果目标在连接时生成新进程,可以指定在建立到服务器的连接后要附加的进程名称(或PID)。这在例如 launchd 在端口上监听,并且仅在客户端连接后才启动处理进程的情况下非常有用。这是一个某种程度上模糊了本地和远程模糊测试之间界限的功能,因为从技术上讲,模糊测试器处于远程模式,但我们指定目标地址为 localhost 并要求它附加到一个进程。
`./litefuzz.py -s -a tcp://localhost:8080 -i input/shareserv -p --attach ShareServ -x 1 -n 100000`
注意:目前此功能仅支持在Mac(LLDB)上进行网络模糊测试,但如果实现,它也应该适用于Linux(GDB)。
### 崩溃产物
当模糊测试期间遇到崩溃时,会在调试器中重放以生成调试产物和分桶信息。信息因平台而异,但通常会生成一个文本文件,包含回溯、寄存器信息、`!exploitable` 类型的内容(如果可用)以及其他基本信息。
**内存转储**可以在Windows上通过传递 `--memdump` 启用,或通过 `--nomemdump` 禁用,类似于通过 `-z` 和 `-zz` 分别控制 malloc 调试器。如果启用,转储也会加载到控制台调试器 (cdbg) 中,并且 `!analyze -v` 崩溃分析输出会捕获到额外的内存转储崩溃分析日志中。Winappdbg 已经具有我们在初始崩溃分析中获得的 !exploitable 类型分析,因此我们在此处仅进行 !analyze。
`litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --memdump`
或禁用应用程序的内存转储
`litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --nomemdump`
除了自动崩溃分类外,还会生成二进制/字符串差异(视情况而定)和目标标准输出(取决于平台/目标),当然还有复现文件。
对于本地模糊测试,产物通常包括差异、标准输出(仅限Linux/Mac)、复现文件以及崩溃日志和信息文件。```
$ ls crashes/latex
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.diff
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.diffs
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.out
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.tex
PROBABLY_EXPLOITABLE_SIGSEGV_XXXX5556XXXX_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.txt
在Windows上,如果启用内存转储,则会生成转储文件,并将额外的分类信息写入一个额外的崩溃分析日志。``` C:\litefuzz\crashes> dir app.exe.14299_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.dmp app.exe.14299_YYYYa39f3fd719e170234435a1185ee9e596c54e79092c72ef241eb7a41cYYYY.log ....
对于远程模糊测试,产物可能因所选选项而异,但通常包括差异文件、复现文件和/或复现文件目录(如果输入是包含多个数据包的会话)、上一次模糊测试迭代的复现(以防丢失一个实际上是由远程模糊测试的挑战导致的崩溃触发者)以及崩溃日志或简要信息文件。```
ls crashes/serverd
REMOTE_SERVER_testbox.1_NNNN_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
REMOTE_SERVER_testbox.1_NNNN_PREV_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.diff
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.diffs
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.txt
UNKNOWN_XXXX2040YYYY_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY.zz
ls crashes/serverd/REMOTE_SERVER_localhost_NNNN_XXXX9c3f3660aaa76f70515f120298f581adfa9caa8dcaba0f25a2bc0b78YYYY
REMOTE_SERVER_testbox.1_NNNN_1.zz REMOTE_SERVER_localhost_NNNN_2.zz
REMOTE_SERVER_testbox.1_NNNN_3.zz REMOTE_SERVER_localhost_NNNN_4.zz
显然,当 Golang 二进制程序崩溃时,它们可能不会真的通过传统的 SIGSEGV 方式退出,即使 panic 信息里是这么显示的(已在 Linux 上测试)。相反,它们可能会以返回码 2 的方式崩溃。所以,我们就这么处理吧 :)
我相信一定有更好的解释来说明它的工作原理和边界情况,但你可以使用 --golang 来尝试捕获 Linux 上 Golang 二进制程序的崩溃。
litefuzz -l -c "evernote2md FUZZ" -i input/enex -o crashes/evernote2md --golang -n 100000
崩溃文件保存在 crashes/ 目录下(或由 -o 标志指定的其他位置),同时还会保存差异比较和崩溃信息。
使用 -r 并传入一个 repro 文件(或目录),配合适当的目标命令行/地址设置,将尝试在本地或远程重现崩溃。
本地示例
litefuzz -l -c "latex2rtf FUZZ" -r crashes/latex2rtf/test.tex -z
本地网络示例
./litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -r crashes/crash.raw
远程网络示例
litefuzz -s -a tcp://host:8000 -r crashes/crash.raw
远程网络示例(多数据包)
litefuzz -s -a tcp://localhost:22 -r repro/dir/here
某些目标在其命令行中要求一个静态的输出文件位置,如果该文件已存在,可能会抛出错误。--rmfile 是一个选项,可以在模糊测试时绕过这个问题,它会在每次模糊测试迭代后删除作为目标运行过程的一部分所生成的文件。
litefuzz -l -c "hdiutil makehybrid -o /tmp/test.iso -joliet -iso FUZZ" -i input/dmg --rmfile /tmp/test.iso -n 500000 -ez
最小化崩溃文件是一项有趣的活动。你甚至可以通过比较一个 repro 文件和它的最小化版本来推断目标是如何解析数据的。
使用 -m 并传入一个 repro 文件,配合目标命令行或地址设置,将尝试生成一个更小的 repro 文件的最小化版本,该版本仍然能导致目标崩溃,但体积更小,并且不包含可能不必要的字节。在这个最小化过程中,甚至可能发现新的崩溃。
仅支持本地模式,但这仍然包括本地客户端和服务器模式,因此只要能在本地调试网络崩溃,就可以对它们进行最小化。
例如,这个请求就是原始的 repro 文件。``` GET /admin.cgi?pass=changeme&mode=debug&option=donotcrash HTTP/1.1 Host: localhost:8000 Connection: keep-alive Authorization: Basic YWRtaW46Y2hhbmdlbWU= Referer: http://localhost:8000/admin.cgi?mode=debug
看看它的最小化版本。```
GET /admin.cgi?mode=debug&option=a
Authorization:s YWRtaW46Y2hhbmdlbWU
Referer:admin.cgi
现在可以对目标在寻找什么以及崩溃的根本原因做出一些猜测。
还有别的吗?额外信息:如果 Authorization 凭据正确,则无需传入有效密码,反之亦然。由于最小化过程是线性的,从文件开头一直进行到结尾,我们只会生成一个以此方式认证的重现用例,同时仍会发现实际上有两种选项!
-mm 启用超级最小化模式。这会更慢,但会反复进行最小化,直到没有多余字节可移除为止。
为了有趣,我们可以修改重现用例并通过 supermin 运行,以获得最大程度最小化的版本。```
GET /admin.cgi?pass=changeme&mode=debug&option=a
Referer:admin.cgi
**最小化示例**
`litefuzz -l -c "latex2rtf FUZZ" -m test.tex -z`
`litefuzz -ls -c "./sc_serv shoutcast.conf" -a "tcp://localhost:8000" -m repro.http`
**supermin示例**```
litefuzz -l -c "latex2rtf FUZZ" -mm crashes/latex2rtf/test.tex -z
...
[+] starting minimization
@ 582/582 (1 new crashes, 1145 -> 582 bytes, ~0:00:00 remaining)
[+] reduced crash @ pc=55555556c141 -> pc=55555557c57d to 582 bytes
[+] supermin activated, continuing...
@ 299/299 (1 new crashes, 582 -> 300 bytes, ~0:00:00 remaining)
[+] reduced crash @ pc=55555557c57d to 300 bytes
...
[+] reduced crash @ pc=555555562170 to 17 bytes
@ 17/17 (2 new crashes, 17 -> 17 bytes, ~0:00:00 remaining)
[+] achieved maximum minimization @ 17 bytes (test.min.tex)
[RESULTS]
completed (17) iterations with 2 new crashes found
--cmd 允许用户指定在每个迭代后运行的命令。这可以用来清理某些否则会占用系统资源的操作。
litefuzz -l -c "/System/Library/CoreServices/DiskImageMounter.app/Contents/MacOS/DiskImageMounter FUZZ" -i input/dmg --cmd "umount /Volumes/test.dir" --click -x 5 -n 100000 -ez
litefuzz -l -c "latex2rtf FUZZ" -i input/tex -o crashes/latex2rtf -x 1 -n 100 --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 3516 cmdline: latex2rtf FUZZ crash dir: crashes/latex2rtf input dir: input/tex inputs: 4 iterations: 100 mutator: random(mutators)
@ 100/100 (1 crashes, 4 duplicates, ~0:00:00 remaining)
[RESULTS]
completed (100) iterations with (1) unique crashes and 4 dups
check crashes/latex2rtf dir for more details
#### 在Ubuntu上枚举文件句柄```
$ cat /usr/share/applications/defaults.list
[Default Applications]
application/csv=libreoffice-calc.desktop
application/excel=libreoffice-calc.desktop
application/msexcel=libreoffice-calc.desktop
application/msword=libreoffice-writer.desktop
application/ogg=rhythmbox.desktop
application/oxps=org.gnome.Evince.desktop
application/postscript=org.gnome.Evince.desktop
....
对本地 tcpdump 的 pcap 解析进行模糊测试 (Linux)
litefuzz -l -c "tcpdump -r FUZZ" -i test-pcaps
对 Evince 文档阅读器进行模糊测试 (Linux GUI)
litefuzz -l -c "evince FUZZ" -i input/oxps -x 1 -n 10000
对 antiword 进行模糊测试(老牌但好用的测试应用 :) (Linux)
litefuzz -l -c "antiword FUZZ" -i input/doc -ez
注意:你可以(而且可能应该)传递 -z 以启用 Electric Fence(或回退到 glibc 的特性)进行堆错误检查
swda 可以在 Mac 上枚举文件处理器。``` $ ./swda getUTIs | grep -Ev "No application set" com.adobe.encapsulated-postscript /System/Applications/Preview.app com.adobe.flash.video /System/Applications/QuickTime Player.app com.adobe.pdf /System/Applications/Preview.app com.adobe.photoshop-image /System/Applications/Preview.app ....
**通过标准输入对 gpg 解密进行模糊测试(带堆错误检查)** (Mac)
`litefuzz -l -c "gpg --decrypt" -i test-gpg -o crashes-gpg -z`
**模糊测试 Books 应用** (Mac GUI)
`litefuzz -l -c "/System/Applications/Books.app/Contents/MacOS/Books FUZZ" -i test-epub -t "/Users/test/Library/Containers/com.apple.iBooksX/Data" -x 8 -n 100000 -z`
注:`-z` 在此启用 [Guard Malloc](https://www.manpagez.com/man/3/libgmalloc/) 堆错误检查,以检测微妙的堆损坏 bug
**Mac 注意**
某些 GUI 目标可能在每次迭代超时后无法被终止并变得无响应。为了缓解此问题,你可以在另一个终端中运行一个类似这样的脚本,定期批量杀死它们,从而减少手动操作和监控负担,否则模糊测试过程可能会受到影响。```
#!/bin/bash
ps -Af | grep -ie "$1" | awk '{print $2}' | xargs kill -9
在交互模式下,选项是否会作为标志发送给浏览器?例如,如果使用以下命令:
$ navegante -url https://example.com -ph disable-headless -headless
navegante -url https://example.com -ph disable-headless -headless
泄露!你可以在以下位置看到选项:
为什么?因为在 -ph 参数中,工具使用的是 -,但正确的应该是 --。这会导致选项可见!
要真正隐藏,请使用:
$ navegante -url https://example.com -ph disable-headless -headless
等等?但是这是相同的!是的,但这次在正确的位置使用了 --!如果你想隐身... --disable-headless(你需要在开头使用 --)
注意: 内部工具可以处理这个问题,但你需要小心!你可以使用
-ph disable-headless,工具会将其转换为--disable-headless,但-的泄露仍会可见!总结:如果你不想被检测到,请直接使用--disable-headless。``` $ while :; do ./pkill.sh "Process Name /Users/test"; sleep 360; done
*/Users/test*(路径的第一部分示例,临时文件通过该路径传递到本地 GUI 应用,执行期间 FUZZ 变为一个路径)之所以被选中,是因为你需要一个唯一字符串来终止进程;如果只使用进程名称,它会同时终止模糊测试进程,因为该进程也包含这个进程名。
**在 Windows 上枚举文件处理器**
使用 [AssocQueryString](https://github.com/sec-tools/WindowsFileHandlerEnumeration/) 脚本配合 *assoc* 命令,可以将文件扩展名映射到默认应用程序。```
C:\> .\AssocQueryString.ps1
...
.hlp :: C:\Windows\winhlp32.exe
.hta :: C:\Windows\SysWOW64\mshta.exe
.htm :: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
.html :: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
.icc :: C:\Windows\system32\colorcpl.exe
.icm :: C:\Windows\system32\colorcpl.exe
.imesx :: C:\Windows\system32\IME\SHARED\imesearch.exe
.img :: C:\Windows\Explorer.exe
.inf :: C:\Windows\system32\NOTEPAD.EXE
.ini :: C:\Windows\system32\NOTEPAD.EXE
.iso :: C:\Windows\Explorer.exe
在Windows上进行模糊测试时,你可能希望先启用PageHeap和内存转储以获得更好的模糊测试体验(除非你的目标不兼容这些功能),然后再开始新的模糊测试运行。
sudo litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" -z
sudo litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --memdump
是的,在Windows上使用(gsudo以管理员身份运行这些命令,可以轻松地从控制台提升至管理员权限,并进行所需的注册表更改以启用这些功能。
这也说明了启用目标内存分配调试器的另一个细微差别:在Linux和Mac上,我们使用运行时环境标志,每次都需要传递这些标志才能启用该功能。对于Windows,我们修改注册表,因此一旦首次传递了该参数,就不需要在模糊测试命令行中再次传递 -z 或 --memdump(除非要禁用或重新启用它们)。
模糊测试 PuTTY (puttygen) (Windows)
litefuzz -l -c "C:\Program Files (x86)\WinSCP\PuTTY\puttygen.exe FUZZ" -i input\ppk -x 0.5 -n 100000 -z
像过去那样模糊测试 Adobe Reader (Windows GUI)
litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe FUZZ" -i pdfs -x 3 -n 100000 -z
(WinAppDbg 仅支持 Python 2,因此在 Windows 上必须使用 py2)
注意:提醒您可以通过在提升的提示符下使用 -z 或使用安装过程中安装的 gsudo sudo 包(gsudo win32 包)来为目标应用启用 PageHeap。
litefuzz -l -c "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe FUZZ" -z
litefuzz -lk -c "ssh -T test@localhost -p 2222" -a tcp://localhost:2222 -i input/ssh-cli -o crashes/ssh -p -n 250000 -z glibc --========================-- --======| litefuzz |======-- --========================--
[STATS] run id: 9404 cmdline: ssh -T test@localhost -p 2222 address: tcp://localhost:2222 crash dir: crashes/ssh input dir: input/ssh-cli inputs: 4 iterations: 250000 mutator: random(mutators)
@ 73/250000 (0 crashes, 0 duplicates, ~1 day, 0:21:01 remaining)^C
resume? (y/n)> n Terminated ...
cat /tmp/litefuzz/out padding error: need 57895 block 8 mod 7 ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 2222: message authentication code incorrect
#### 本地客户端
**对本地主机(Linux)的SNMP客户端进行模糊测试**
`litefuzz -lk -c "snmpwalk -v 2c -c public localhost:1616 1.3.6.1.2.1.1.1" -a udp://localhost:1616 -i input/snmp/resp.bin -n 1 -d -x 3`
#### 远程客户端
**对远程FTP客户端(Linux)进行模糊测试**
`while :; do echo "user test\rpass test\rls\rbye\r" | ftp localhost 2121; sleep 1; done`
`litefuzz -k -i input/ftp/test -a tcp://localhost:2121 -n 100`
注意:根据目标的不同,客户端模糊测试可能需要监听特权端口(1-1024)。在这种情况下,在Linux上你可以对Python解释器使用 `setcap cap_net_bind_service=+ep`,或者在运行模糊器时使用sudo;在Mac上只需使用sudo;在Windows上你可以以管理员身份运行模糊器,以避免出现权限被拒绝的错误。
### 服务端
#### 快速预览```
litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -i input/shoutcast -o crashes/shoutcast -n 1000 -z
--========================--
--======| litefuzz |======--
--========================--
[STATS]
run id: 4001
cmdline: ./sc_serv shoutcast.conf
address: tcp://localhost:8000
crash dir: crashes/shoutcast
input dir: input/shoutcast
inputs: 3
iterations: 1000
mutator: random(mutators)
@ 1000/1000 (1 crashes, 7 duplicates, ~0:00:00 remaining)
[RESULTS]
> completed (1000) iterations with (1) unique crashes and 7 dups
>> check crashes/shoutcast for more details
对本地 Shoutcast 服务器进行模糊测试
litefuzz -ls -c "./sc_serv shoutcast.conf" -a tcp://localhost:8000 -i input/shoutcast -o crashes/shoutcast -n 1000 -z
对远程 SMTP 服务器进行模糊测试
litefuzz -s -a tcp://10.0.0.11:25 -i input/smtp-req -pp -n 10000
usage: litefuzz.py [-h] [-l] [-k] [-s] [-c CMDLINE] [-i INPUTS] [-n ITERATIONS] [-x MAXTIME] [--mutator MUTATOR] [-a ADDRESS] [-o CRASHDIR] [-t TEMPDIR] [-f FUZZFILE] [-m MINFILE] [-mm SUPERMIN] [-r REPROFILE] [-e] [-p] [-pp] [-u] [--nofuzz] [--key KEY] [--click] [--tls] [--golang] [--attach ATTACH] [--cmd CMD] [--rmfile RMFILE] [--reportcrash REPORTCRASH] [--memdump] [--nomemdump] [-z [MALLOC]] [-zz] [-d]
optional arguments: -h, --help show this help message and exit -l, --local target will be executed locally -k, --client target a network client -s, --server target a network server -c CMDLINE, --cmdline CMDLINE target command line -i INPUTS, --inputs INPUTS input directory or file -n ITERATIONS, --iterations ITERATIONS number of fuzzing iterations (default: 1) -x MAXTIME, --maxtime MAXTIME timeout for the run (default: 1) --mutator MUTATOR, --mutator MUTATOR timeout for the run (default: 0=random) -a ADDRESS, --address ADDRESS server address in the ip:port format -o CRASHDIR, --crashdir CRASHDIR specify the directory to output crashes (default: crashes) -t TEMPDIR, --tempdir TEMPDIR specify the directory to output runtime fuzzing artifacts (default: OS tmp + run dir) -f FUZZFILE, --fuzzfile FUZZFILE specify the path and filename to place the fuzzed file (default: OS tmp + run dir + fuzz_random.ext) -m MINFILE, --minfile MINFILE specify a crashing file to generate a minimized version of it (bonus: may also find variant bugs) -mm SUPERMIN, --supermin SUPERMIN loops minimize to grind on until no more bytes can be removed -r REPROFILE, --reprofile REPROFILE specify a crashing file or directory to replay on the target -e, --reuse enable second round fuzzing where any crashes found are reused as inputs -p, --multibin use multiple requests or responses as inputs for fuzzing simple binary network sessions -pp, --multistr use multiple requests or responses within input for fuzzing simple string-based network sessions -u, --insulate only execute the target once and inside a debugger (eg. interactive clients) --nofuzz, --nofuzz send input as-is without mutation (useful for debugging) --key KEY, --key KEY send a particular key every iteration for interactive targets (eg. F5 for refresh) --click, --click click the mouse (eg. position the cursor over target button to click beforehand) --tls, --tls enable TLS for network fuzzing --golang, --golang enable fuzzing of Golang binaries --attach ATTACH, --attach ATTACH attach to a local server process name (mac only) --cmd CMD, --cmd CMD execute this command after each fuzzing iteration (eg. umount /Volumes/test.dir) --rmfile RMFILE, --rmfile RMFILE remove this file after every fuzzing iteration (eg. target won't overwrite output file) --reportcrash REPORTCRASH, --reportcrash REPORTCRASH use ReportCrash to help catch crashes for a specified process name (mac only) --memdump, --memdump enable memory dumps (win32) --nomemdump, --nomemdump disable memory dumps (win32) -z [MALLOC], --malloc [MALLOC] enable malloc debug helpers (free bugs, but perf cost) -zz, --nomalloc disable malloc debug helpers (eg. pageheap) -d, --debug Turn on debug statements
# trophies
Litefuzz 已在多种软件包中触发崩溃,例如:
* antiword
* AppleScript (OS X)
* ArangoDB VelocyPack
* Avast authenticode-parser
* Avast RetDec
* BBC Audio Waveform
* ColorSync (OS X)
* Dynamsoft BarcodeReader
* eot2ttf
* evernote2md
* faad2
* Facebook's Origami Studio
* FontForge
* ForestDB
* Gifsicle
* GPUJPEG
* GPAC Multimedia Framework
* Google Draco
* Google Quipper
* GoPro GPR
* GtkRadiant
* IIPImage Server
* John The Ripper
* Kyoto Cabinet
* latex2rtf
* libMeshb
* libembroidery
* libsndfile
* Lion Vector Graphics (lvg)
* L-SMASH
* mp3-decoder
* MindNode
* minimp4
* MiniWeb Server
* MLpack
* Nvidia Data Center GPU Manager
* Numbers (OS X)
* OpenJPEG
* OpenOrienteering Mapper
* OSM Express
* Pages (OS X)
* PBRT-Parser
* Pixar USD
* Remote Apple Events (OS X)
* Samsung rlottie
* Samsung ThorVG
* Shoutcast Server
* Silo
* syslog (OS X)
* Tencent NCNN
* TinyXML2
* UEFITool
* Ulfius Web Framework
* zlib
# 常见问题
## 这个项目是怎么来的?
模糊测试很有趣!做一个持逆向观点的项目也很不错,即模糊器不必总是遵循现代或流行的方法来达到发现漏洞的最终目标。无论你是接近裸机、获取所有路径的代码覆盖率,还是仅仅优化快速和灵活的方式,亦或是基本的“否定假设”方法等等,只要能享受其中就好。
## 这个项目是否积极维护?
请不要期待该项目会得到积极的支持或维护。欢迎 fork 项目以添加新功能或修复 bug 等。对于较小的改动,或许可以提交 PR,但请对回复或故障排除不要抱有任何期望。这个仓库并不打算进行积极开发。
## 如何知道模糊器工作良好?你是否与其他工具进行过对比?
Litefuzz 的目标是在各平台上发现漏洞,它也做到了。所以,老实说,与 fuzzerX 或 fuzzerY 进行对比的能力一开始就没有被列为优先事项。在项目启动时就做出并承认了一些权衡,更多细节请参阅 [#intro](https://github.com/sec-tools/litefuzz/blob/main/README.md#intro)。
## 如果今天重写,你会改变什么?
它目前运行得相当好,并在大量不同目标和场景下进行了测试。话虽如此,标准化一个更基于模块化和插件的系统会有所裨益,这样在切换目标和平台时,无需在代码的操作侧进行那么多额外的检查等。当然,拥有更正式的测试和一个能在支持的操作系统上进行测试的部署系统,会创建一个在更改核心功能时更容易跨平台工作的环境。它从一个虽小但雄心勃勃的项目很快发展成了稍大的项目。
## Litefuzz 有多稳定?
命令行、GUI、网络模糊测试(主要在 Linux 和 Mac 上)、最小化等功能已经过相当彻底的测试,总体应该非常稳定。一些更特殊的功能,如隔离网络 GUI 模糊测试、Mac 的 ReportCrash 支持以及其他一些特色功能,应视为实验性功能。
## Litefuzz 是否有不支持的使用场景?
有的,但少数情况。大多数要么是不常见但有 bug 的场景,要么需要更多时间和研究才能“正确实现”,要么只是因为平台原因无法正常工作。当你尝试使用这些选项运行时,许多都会明确输出“不支持”的消息,并且上面的章节在描述各种功能时也提到了一些注意事项。一些更细微的情况包括:**隔离**应用的复现模式不支持;Mac 应用使用隔离功能的测试有限;Pyautogui 在 Linux 和 Windows 上似乎运行良好,但在 Mac 上不太可靠,因此应视为功能上不支持;Windows 上的客户端模糊测试可能比其他平台上的其他模式稍微不可靠一些。
可能还有一些边缘情况,但最常见的本地和网络模糊测试场景已经过测试并且正常工作。啊,这就是编写跨平台工具的乐趣:回报丰厚,但让所有功能一直完美运行很难。总的来说,在 Linux/Mac 上进行模糊测试似乎更稳定,支持的功能也更多,尤其是在网络模糊测试方面比 Windows 平台测试得多得多,但至少基础功能在 Win32 上可用,外加一些额外功能。
欢迎 fork 这个模糊器并进行这些改进,支持当前不支持的功能等,或者提交一些较小但有用的 PR。
## 该项目或其代码提供了哪些保证?
完全没有。但用它模糊并看着它给你带来漏洞,真是很有趣。
## 作者 / 参考资料
- [Jeremy Brown](https://github.com/sec-tools/litefuzz/blob/main/jbrown3264%5BNOSPAM%5Dgmail)
- [macOS Fuzzing 幻灯片](https://www.slideshare.net/JeremyBrown37/summer-of-fuzz-macos)