Frist, we are going to set up the environment for android kernel exploitation. And the tutorial can be found here.
But there are some problems with those instructions so I will provide what I did in this post. The OS I am using is Ubuntu 16.04.
sudo apt-get install default-jdk
Download the sdk
tar xvf android-sdk_r24.4.1-linux.tgz
Then install these two.
If you are using 64-bit machine, there might some additional libraries that you want to install. I tried first on ubuntu 16.04 and the process above works well for me but when I tried ubuntu 18.04, there is a lot more pain. But just google it, you can solve your problem.
Ok, let’s start the exploitation.
Take a look at the vulnerable module.
We can see that the copy_from_user functions actually copy the user input to the buffer. And this will cause the buffer overflow. So all we need to do is to manipulate the shellcode to get privilege. But what will our shellcode looks like? There should be 3 steps.
- Use commit_creds(prepare_kernel_cred(0)) to change into root user
- Use mov R3,#0x40000010; MSR CPSR_c,R3; This can change from kernel mode into user mode. Because the function address of payload is in the user mode. So we need to go back to user mode so it can return to the payload function.
- In the payload function, it will call /system/bin/sh so we can get a root shell.
That’s all we need.
For the first step, we need to get the address of the prepare_kernel_cred and commit_creds. Start the emulator and use the adb to get a shell. But remember, before this you need to do “echo 0 > /proc/sys/kernel/kptr_restric”. Otherwise, you can’t resolve the symbol for those functions in the kernel.
After this, you need to get the address of the payload.
Add a printf here so you will be able to see the address of the shellcode and payload.
Then, we are able to write the shellcode.
I think what the shellcode does here is quite obviously.
Use ndk-build to get the exp and you are able to get the root shell.
The corresponding code will be in my github: samohyes.