#Linux Kernel Exploitation on Android# This repository is meant to serve as a hands on guide to Linux kernel exploitation with a special interest in Android. All the resources you need for setting up an exploitation play ground will be explained below. Each folder should have it's own challenge in the form of a loadable kernel module, it's own solution - code that will be executed from userspace to take advantage of the vulnerability (usually to gain us root), and a bit of a writeup about the vulnerability and the exploit.
I am hoping that this will serve as a jumpstart for people to get started with kernel exploitation as well as a learning exercise for myself. Feel free to fork and submit pull reqs for new challenges, documentations, etc..
##Prepare the Emulator for the Challenges##
git clone https://android.googlesource.com/platform/external/elfutils git clone https://android.googlesource.com/platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.6 cp elfutils/0.153/libelf/elf.h /usr/local/include
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6
The patch we are applying to the emulator kernel enables debugging symbols and builds our vulnerabilities into the kernel tree.
git clone https://android.googlesource.com/kernel/goldfish && \ git clone email@example.com:Fuzion24/AndroidKernelExploitation.git kernel_exploit_challenges && \ cd goldfish && git checkout -t origin/android-goldfish-3.4 && \ git am --signoff < ../kernel_exploit_challenges/kernel_build/debug_symbols_and_challenges.patch && \ cd .. && ln -s $(pwd)/kernel_exploit_challenges/ goldfish/drivers/vulnerabilities
Build the Kernel
export ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-linux-androideabi- &&\ export PATH=$(pwd)/arm-linux-androideabi-4.6/bin/:$PATH && \ cd goldfish && make goldfish_armv7_defconfig && make -j8
Run the Emulator
android create avd --force -t "Google Inc.:Google APIs:19" -n kernel_challenges emulator -show-kernel -kernel arch/arm/boot/zImage -avd kernel_challenges -no-boot-anim -no-skin -no-audio -no-window -qemu -monitor unix:/tmp/qemuSocket,server,nowait -s
Debug the kernel
While in the goldfish folder,
You should see something like the following:
GNU gdb (GDB) 7.3.1-gg2 Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-apple-darwin --target=arm-linux-android". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from <REDACTED>/goldfish/vmlinux...done. (gdb)
Connect to the running emulator:
(gdb) target remote :1234 Remote debugging using :1234 cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:74 74 mov pc, lr (gdb)
If you see this, then congrats! You're up and running!
Once we have managed to cause some memory corruption that we can control, we usually need to know where some of the symbols (pointers to functions, fields, structures, etc..) are located in memory. There exists a kernel proc entry which lists all of the symbols and their locations. This information can be read from userspace from the file located at
/proc/kallsyms. There is a proc interface kallsyms which names the exported kernel symbol as well as the address at which it is located.
In recent kernel versions, in order to make exploitation of kernel bugs more difficult, the kernel has restricted these symbols for viewing only by those with CAP_SYS_ADMIN privledeges. You can read the semantics of kptr_restrict submitted by Dan Rosenberg, et al. here and with respect to Android here.
Reading kallsyms with kptr restrict enabled:
adb shell cat /proc/kallsyms | grep commit_creds 00000000 T commit_creds
In order for this exploit to resolve symbols, you need to
adb shell su -c "echo 0 > /proc/sys/kernel/kptr_restrict" ``` And now we can properly see the kernel symbols and their addresses: ``` adb shell cat /proc/kallsyms | grep commit_creds c008e138 T commit_creds ``` We will make the assumption that we know the location of all kernel symbols. While this not strictly true in practice, it is fairly safe to assume that we will be able to access to kernel symbols one way or another. Locations of items in memory change with every compilation of the kernel. OEMs build a kernel for each device/product and that kernel is used across all instances of that device (the kernel can change with sytem upgrades, different regions of the phone, small hardware changes in same device). If you can obtain the OTA update, factory image, etc for the device, you can extract the necessary symbols in a static manner. Also, if you are able to obtain root on the device in some other manner (unlocked bootloaders, an 0-day you are holding, etc), you can use that to bootsrap yourself to get the necessary symbols Note: Deterministic builds ([here](https://wiki.debian.org/ReproducibleBuilds) and [here](https://blog.torproject.org/category/tags/deterministic-builds)) are interesting for proving the integrity of the build environment.