#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..
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, have restricted these symbols for viewing only by those with CAP_SYS_ADMIN privledeges. You can read the sematics 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.
##Prepare the Emulator for the Challeges##
##OSX
```
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
```
##General
```
git clone https://android.googlesource.com/kernel/goldfish
git clone [email protected]:Fuzion24/AndroidKernelExploitation.git
ln -s AndroidKernelExploitation/ goldfish/drivers/vulnerabilities
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-linux-androideabi-
export PATH=$(pwd)/arm-linux-androideabi-4.6/bin/:$PATH
cd goldfish
git checkout -b android-goldfish-3.4
cd -
```
We want to make two small changes to the emulator. First, we want to the kernel to be compiled with debugging symbols:
```diff
diff --git a/arch/arm/configs/goldfish_armv7_defconfig b/arch/arm/configs/goldfish_armv7_defconfig
index 4f273a0..edd7d11 100644
--- a/arch/arm/configs/goldfish_armv7_defconfig
+++ b/arch/arm/configs/goldfish_armv7_defconfig
@@ -193,3 +193,4 @@ CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_TWOFISH=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_DEBUG_INFO=y
```
Next, we need to link our buggy drivers into the build tree for an in-tree build. These could alternatively be built as loadable kernel modules and loaded that way.
```diff
diff --git a/drivers/Makefile b/drivers/Makefile
index d55b035..7553795 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -5,6 +5,7 @@
# Rewritten to use lists instead of if-statements.
#
+obj-y += vulnerabilities/kernel_build/
# GPIO must come after pinctrl as gpios may need to mux pins etc
obj-y += pinctrl/
obj-y += gpio/
(END)
```
```
make goldfish_armv7_defconfig && make -j8
```
```
emulator -show-kernel -kernel arch/arm/boot/zImage -avd Poop -no-boot-anim -no-skin -no-audio -no-window -qemu -monitor unix:/tmp/qemuSocket,server,nowait -s
```