v1.4 版权所有 (C) 2020 Andrea Fioraldi [email protected]
根据 Apache 许可证 v2.0 发布
这个实验性模糊测试器用于 API 内存中的模糊测试。
设计深受 AFL/AFL++ 的启发和影响。
目前,变异器相当简单,只有 AFL 的 havoc 和 splice 阶段。
我仅在 tests/ 下的示例中测试过,这是一个进行中的项目,但已知至少在 GNU/Linux x86_64 和 Android x86_64 上可以工作。
你需要 Frida >= 12.8.1 来运行它(pip3 install -U frida),以及 frida-tools 来编译 harness。
fuzz 库需要被导入到一个自定义 harness 中,然后用 frida-compile 编译生成代理,frida-fuzzer 会将代理注入到目标应用中。
模糊测试器的大部分逻辑都在代理中。
一个 harness 遵循以下格式:
var fuzz = require("./fuzz");
var TARGET_MODULE = "test_linux64";
var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;
var RET_TYPE = "void";
var ARGS_TYPES = ['pointer', 'int'];
var func_handle = new NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { traps: 'all' });
fuzz.target_module = TARGET_MODULE;
var payload_mem = Memory.alloc(fuzz.config.MAX_FILE);
fuzz.fuzzer_test_one_input = function (/* Uint8Array */ payload) {
Memory.writeByteArray(payload_mem, payload, payload.length);
func_handle(payload_mem, payload.length);
}
fuzz.fuzzer_test_one_input 是必须的。如果你不指定 fuzz.target_module,所有执行的代码都会被插桩。
你也可以设置 fuzz.manual_loop_start = true 来告诉模糊测试器,你将在回调中调用 fuzz.fuzzing_loop(),因此它不应替你调用(例如,在 Android 应用中点击按钮时启动模糊测试)。
可以设置回调 fuzz.init_callback 来在模糊测试器准备好开始时执行代码。参见 tests/test_java.js 的示例。
fuzz.dictionary 是一个经典的模糊测试字典,一个数组,你可以向其中添加元素(接受的类型有 Array、ArrayBuffer、Uint8Array、String),这些元素在变异器中作为额外的值使用。参见 tests/test_libxml2.js 的示例。
frida-fuzzer 接受以下参数:
如果你不指定输出文件夹,会在 /tmp 下创建一个临时文件夹。
如果你不指定包含初始种子的文件夹,会使用一个无信息的种子 0000 作为起始种子。
如果你在对本地应用进行模糊测试,你可能希望在运行 frida-fuzzer 之前先执行 system-config 来调整系统参数并加速。
运行 ./frida-fuzzer -spawn ./tests/test_linux64,你会在终端上看到类似下面的状态屏幕:

你也可以轻松地在 fuzz/fuzzer.js 中添加自定义阶段,并将其添加到 fuzz/index.js 的阶段列表中。
要自定义模糊测试器,编辑 fuzz/config.js。
你可能想要更改的变量有 MAP_SIZE(如果你模糊测试的代码很小,可以减小它以获得一些速度提升)、MAX_FILE(生成输入的最大大小)和 QUEUE_CACHE_MAX_SIZE(增加队列缓存大小以获得更快的速度,尤其是在 Android 上)。
让我们对 tests 中示例 Android 应用里的原生共享库进行模糊测试。
确保你的虚拟设备已 root:
host$ adb root
从仓库发布页面下载 Android x86_64 的 frida-server,并将其复制到设备上的 /data/local/tmp 目录下(使用 adb push)。
启动一个 shell 并运行 frida-server:
device# cd /data/local/tmp
device# ./frida-server
现在使用拖放的方式将测试应用 tests/app-debug.apk 安装到模拟器窗口中。
然后打开该应用。
使用 frida-compile 编译代理脚本:
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
在模拟器中打开应用。
使用以下命令对测试应用附带的 libnative-lib.so 库中的 test_func 函数进行模糊测试:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
有趣的测试用例和崩溃信息都会被保存到 output_folder 中。
祝愉快。

嘿,开源社区,如果有人想贡献,这里有很多待办事项。
如果你对这些功能有疑问,随时在 Twitter 上私信我。
对于功能建议,请参考 Issues 板块。
| -i FOLDER | 包含初始种子(seeds)的文件夹 |
| -o FOLDER | 包含中间种子和崩溃信息的输出文件夹 |
| -U | 连接到 USB |
| -spawn | 启动并附加,而不是简单地附加 |
| -script SCRIPT | 脚本文件名(默认为 fuzzer-agent.js) |