Fuzzing Android binaries using AFL++ Frida Mode

+Ch0pinšŸ•·ļø
3 min readMay 14, 2024

--

You might find this to be a fitting prologue to my earlier post on Creating and using JVM instances in Android C/C++ applicationsā€¦ and you are right !! Well, consider this my way of enticing you by presenting the end goal youā€™ll eventually reach. After all, itā€™s not uncommon to wade through various write-ups without a clear understanding of their objectives.

With that said, if youā€™re interested in or considering exploring fuzzing, this serves as a step-by-step guide on configuring AFL++ and employing it to fuzz Android binaries. Iā€™ll try to keep it short and avoid boring paragraphs of type ā€¦how-to-set-up-your-Android-pentest-lab. After all if you donā€™t know what fuzzing or what AFL is, there are thousands of write ups out there in order to get you started.

I followed this step-by-step guide to set up AFL++ (Frida mode) on my MacBook Pro M1 running Sonoma v. 14.4.1, but I doubt youā€™ll encounter many challenges with your system.

Setting up AFL++

  1. Download the latest release here: https://github.com/AFLplusplus/AFLplusplus/releases/ and extract the compressed files.
  2. Install the Android-ndk using brew:
$brew install -- cask android-ndk

$export ANDROID_NDK_HOME="/opt/homebrew/share/android-ndk"

Set the ANDROID_NDK_HOME persistently, so you wonā€™t need to redefine it every time you start a shell session. Depending on your OS and shell, you may add the line export ANDROID_NDK_HOME='/opt/homebrew/share/android-ndk' to your shell configuration file (e.g. ~/.zshrc in case you are using zsh).

3. Download the following CMAKE file and save it under the directory you extracted AFL (in step 1):

https://github.com/Ch0pin/android-fuzzing/blob/main/AFLplusplus/CMakeLists.txt

If you face any issue with the above you ming thave to change this part:

execute_process(
COMMAND
bash -c "echo 'unsigned char api_js[] = {' > ${API_C}; \
xxd -p -c 12 ${API_JS} | sed -e \"s/\\([0-9a-f]\\{2\\}\\)/0x\\1, /g\" \
| sed -e \"s/^/ /\" >> ${API_C}; \
echo '};' >> ${API_C}; \
echo \"unsigned int api_js_len = $(stat --printf='%s' ${API_JS});\" \
>> ${API_C}"
)

As follows:

execute_process(
COMMAND
bash -c "echo 'unsigned char api_js[] = {' > ${API_C}; \
xxd -p -c 12 ${API_JS} | sed -e \"s/\\([0-9a-f]\\{2\\}\\)/0x\\1, /g\" \
| sed -e \"s/^/ /\" >> ${API_C}; \
echo '};' >> ${API_C}; \
echo \"unsigned int api_js_len = $(stat ${API_JS} | cut -d ' ' -f 8);\" \
>> ${API_C}"
)

4. Save the following script under the directory you downloaded AFL and run it in order to compile the afl-fuzz and afl-frida-trace.so:

mkdir build && cd build
cmake -DANDROID_PLATFORM=31 \
-DCMAKE_TOOLCHAIN_FILE=/opt/android-ndk-r25c/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a ..
make

You may need to change the DCMAKE_TOOLCHAIN_FILE value with the location of the ndk. In case it is installed with Brew, this path will be under the /opt/homebrew/Cascroom/android-ndk

If everything worked as expected

You may find the afl-fuzz and afl-frida-trace.so under the ./build path. Use adb to push these binaries in /data/local/tmp:

$adb push afl* /data/local/tmp

Give execute access to the afl-fuzz . If you followed my guide, you probably know what to fuzz. Indicatively, assuming that the binary you want to fuzz is called ā€˜fuzzā€™ :) you may start with:

./afl-fuzz -O -G 256 -i in -o out ./fuzz:

--

--