Frida-Fuzzer : Experimental Fuzzer Used For API In-Memory Fuzzing

Frida-Fuzzer is a experimental fuzzer is meant to be used for API in-memory fuzzing. The design is highly inspired and based on AFL/AFL++. ATM the mutator is quite simple, just the AFL’s havoc and splice stages.

I tested only the examples under tests/, this is a WIP project but is known to works at least on GNU/Linux x86_64 and Android x86_64.You need Frida >= 12.8.1 to run this (pip3 install -U frida) and frida-tools to compile the harness.

Usage

The fuzz library has to be imported into a custom harness and then compiled with frida-compile to generate the agent that frida-fuzzer will inject into the target app.

The majority of the logic of the fuzzer is in the agent.

A harness has the following format:

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 is mandatory. If you don’t specify fuzz.target_module, all the code executed will be instrumented.

You can also set fuzz.manual_loop_start = true to tell the fuzzer that you will call fuzz.fuzzing_loop() in a callback and so it must not call it for you (e.g. to start fuzzing when a button is clicked in the Android app).

The callback fuzz.init_callback can be set to execute code when the fuzzer is ready to begin. See tests/test_java.js for an example.

fuzz.dictionary is a classic fuzzer dictionary, an array in which you can add items (accepted types are Array, ArrayBuffer, Uint8Array, String) that are used as additional values in the mutator. See tests/test_libxml2.js for an example.

Also Read – Pulsar : Network Footprint Scanner Platform

frida-fuzzer accepts the following arguments:

-i FOLDERFolder with initial seeds
-o FOLDEROutput folder with intermediate seeds and crashes
-UConnect to USB
-spawnSpawn and attach instead of simply attach
-script SCRIPTScript filename (default is fuzzer-agent.js)

If you don’t specify the output folder, a temp folder is created under /tmp. If you don’t specify the folder with the initial seed, an uninformed seed 0000 is used as starting seed.

If you are fuzzing a local application, you may want to execute system-config before frida-fuzzer to tune the parameters of your system and speed-up the things.

Running ./frida-fuzzer -spawn ./tests/test_linux64 you will see something like the following status screen on your terminal:

You can also easily add a custom stage in fuzz/fuzzer.js and add it to the stages list in fuzz/index.js.

To customize the fuzzer, edit fuzz/config.js. The variables that you may want to change are MAP_SIZE (If the code that you are fuzzing is small you can reduce it and gain a bit of speed), MAX_FILE (the maximum size of generated input) and QUEUE_CACHE_MAX_SIZE (increase the queue cache size for more speed, especially on Android).

Example

Let’s fuzz the native shared library in the example Android app in tests.

Make sure you have root on your virtual device:

host$ adb root

Download the Android x86_64 frida-server from the repo release page and copy it on the device under /data/local/tmp (use adb push).

Start a shell and run the frida-server:

device# cd /data/local/tmp
device# ./frida-server

Now install the test app tests/app-debug.apk using the drag & drop into the emulator window.

Then, open the app.

Compile the agent script wiht frida-compile:

host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js

Open the app in the emulator.

Fuzz the test_func function of the libnative-lib.so library shipped with the test app with the command:

host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1

Interesting testcases and crashes are both saved into output_folder.

Enjoy.

R K

Recent Posts

Shadow-rs : Harnessing Rust’s Power For Kernel-Level Security Research

shadow-rs is a Windows kernel rootkit written in Rust, demonstrating advanced techniques for kernel manipulation…

1 week ago

ExecutePeFromPngViaLNK – Advanced Execution Of Embedded PE Files via PNG And LNK

Extract and execute a PE embedded within a PNG file using an LNK file. The…

2 weeks ago

Red Team Certification – A Comprehensive Guide To Advancing In Cybersecurity Operations

Embark on the journey of becoming a certified Red Team professional with our definitive guide.…

3 weeks ago

CVE-2024-5836 / CVE-2024-6778 : Chromium Sandbox Escape via Extension Exploits

This repository contains proof of concept exploits for CVE-2024-5836 and CVE-2024-6778, which are vulnerabilities within…

3 weeks ago

Rust BOFs – Unlocking New Potentials In Cobalt Strike

This took me like 4 days (+2 days for an update), but I got it…

3 weeks ago

MaLDAPtive – Pioneering LDAP SearchFilter Parsing And Security Framework

MaLDAPtive is a framework for LDAP SearchFilter parsing, obfuscation, deobfuscation and detection. Its foundation is…

3 weeks ago