mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-08 08:11:34 +00:00
206 lines
4.6 KiB
Markdown
Executable File
206 lines
4.6 KiB
Markdown
Executable File
# qbdi-based binary-only instrumentation for afl-fuzz
|
|
|
|
NOTE: this code is outdated and first would need to be adapted to the current
|
|
AFL++ versions.
|
|
Try FRIDA mode or fpicker [https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) first, maybe they suite your need.
|
|
|
|
## 1) Introduction
|
|
|
|
The code in ./qbdi_mode allows you to build a standalone feature that
|
|
using the QBDI framework to fuzz android native library.
|
|
|
|
## 2) Build
|
|
|
|
First download the Android NDK
|
|
|
|
```
|
|
https://developer.android.com/ndk/downloads
|
|
https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip
|
|
```
|
|
|
|
Then unzip it and build the standalone-toolchain
|
|
For x86_64 standalone-toolchain
|
|
|
|
```
|
|
unzip android-ndk-r20-linux-x86_64.zip
|
|
cd android-ndk-r20/
|
|
./build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 --install-dir ../android-standalone-toolchain-x86_64
|
|
```
|
|
|
|
For x86 standalone-toolchain
|
|
|
|
```
|
|
./build/tools/make_standalone_toolchain.py --arch x86 --api 21 --install-dir ../android-standalone-toolchain-x86
|
|
```
|
|
|
|
In alternative you can also use the pre-built toolchain, in that case make sure
|
|
to set the proper CC and CXX environment variables because there are many
|
|
different compilers for each API version in the pre-built toolchain.
|
|
|
|
For example:
|
|
|
|
```
|
|
export STANDALONE_TOOLCHAIN_PATH=~/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/linux-x86_64/
|
|
export CC=x86_64-linux-android21-clang
|
|
export CXX=x86_64-linux-android21-clang++
|
|
```
|
|
|
|
Then download the QBDI SDK from website
|
|
|
|
```
|
|
https://qbdi.quarkslab.com/
|
|
```
|
|
|
|
For Android x86_64
|
|
|
|
```
|
|
https://github.com/QBDI/QBDI/releases/download/v0.7.0/QBDI-0.7.0-android-X86_64.tar.gz
|
|
```
|
|
|
|
Then decompress the sdk
|
|
|
|
```
|
|
mkdir android-qbdi-sdk-x86_64
|
|
cp QBDI-0.7.0-android-X86_64.tar.gz android-qbdi-sdk-x86_64/
|
|
cd android-qbdi-sdk-x86_64/
|
|
tar xvf QBDI-0.7.0-android-X86_64.tar.gz
|
|
```
|
|
|
|
Now set the `STANDALONE_TOOLCHAIN_PATH` to the path of standalone-toolchain
|
|
|
|
```
|
|
export STANDALONE_TOOLCHAIN_PATH=/home/hac425/workspace/android-standalone-toolchain-x86_64
|
|
```
|
|
|
|
set the `QBDI_SDK_PATH` to the path of QBDI SDK
|
|
|
|
```
|
|
export QBDI_SDK_PATH=/home/hac425/workspace/AFLplusplus/qbdi_mode/android-qbdi-sdk-x86_64/
|
|
```
|
|
|
|
Then run the build.sh
|
|
|
|
```
|
|
./build.sh x86_64
|
|
```
|
|
|
|
this could build the afl-fuzz and also the qbdi template for android x86_64
|
|
|
|
### Example
|
|
|
|
The demo-so.c is an vulnerable library, it has a function for test
|
|
|
|
```c
|
|
int target_func(char *buf, int size) {
|
|
|
|
printf("buffer:%p, size:%p\n", buf, size);
|
|
switch (buf[0]) {
|
|
|
|
case 1:
|
|
puts("222");
|
|
if (buf[1] == '\x44') {
|
|
|
|
puts("null ptr deference");
|
|
*(char *)(0) = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
case 0xff:
|
|
if (buf[2] == '\xff') {
|
|
|
|
if (buf[1] == '\x44') {
|
|
|
|
puts("crash....");
|
|
*(char *)(0xdeadbeef) = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
default: puts("default action"); break;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
```
|
|
|
|
This could be built to `libdemo.so`.
|
|
|
|
Then load the library in template.cpp and find the `target` function address:
|
|
|
|
```c
|
|
void *handle = dlopen(lib_path, RTLD_LAZY);
|
|
..........................................
|
|
..........................................
|
|
..........................................
|
|
p_target_func = (target_func)dlsym(handle, "target_func");
|
|
```
|
|
|
|
Then read the data from file and call the function in `fuzz_func`:
|
|
|
|
```c
|
|
QBDI_NOINLINE int fuzz_func() {
|
|
|
|
if (afl_setup()) { afl_forkserver(); }
|
|
|
|
/* Read the input from file */
|
|
unsigned long len = 0;
|
|
char * data = read_file(input_pathname, &len);
|
|
|
|
/* Call the target function with the input data */
|
|
p_target_func(data, len);
|
|
return 1;
|
|
|
|
}
|
|
```
|
|
|
|
Just compile it
|
|
|
|
```
|
|
./build.sh x86_64
|
|
```
|
|
|
|
Then push the `afl-fuzz`, `loader`, `libdemo.so`, the `libQBDI.so` from the QBDI SDK and the `libc++_shared.so` from android-standalone-toolchain to android device
|
|
|
|
```
|
|
adb push afl-fuzz /data/local/tmp
|
|
adb push libdemo.so /data/local/tmp
|
|
adb push loader /data/local/tmp
|
|
adb push android-qbdi-sdk-x86_64/usr/local/lib/libQBDI.so /data/local/tmp
|
|
adb push ../../android-standalone-toolchain-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so
|
|
/data/local/tmp
|
|
```
|
|
|
|
In android adb shell, run the loader to test if it runs
|
|
|
|
```
|
|
cd /data/local/tmp
|
|
export LD_LIBRARY_PATH=/data/local/tmp
|
|
mkdir in
|
|
echo 0000 > in/1
|
|
./loader libdemo.so in/1
|
|
p_target_func:0x716d96a98600
|
|
offset:0x600
|
|
offset:0x580
|
|
buffer:0x716d96609050, size:0x5
|
|
offset:0x628
|
|
offset:0x646
|
|
offset:0x64b
|
|
offset:0x65c
|
|
offset:0x6df
|
|
offset:0x590
|
|
default action
|
|
offset:0x6eb
|
|
```
|
|
|
|
Now run `afl-fuzz` to fuzz the demo library
|
|
|
|
```
|
|
./afl-fuzz -i in -o out -- ./loader /data/local/tmp/libdemo.so @@
|
|
```
|
|
|
|
 |