Fuzzing Android binaries using AFL++ Frida Mode
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++
- Download the latest release here: https://github.com/AFLplusplus/AFLplusplus/releases/ and extract the compressed files.
- 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
: