0
6
Login
Code
Issues
1
Pull requests
Events
Packages
ccea5b58b4e4f32574a6d8ce41f114ed08e5fd5a
ccea5b58b4e4f32574a6d8ce41f114ed08e5fd5a

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/ 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

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:

    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:

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 @@

screen1