Skip to content

Latest commit

 

History

History
71 lines (53 loc) · 4.37 KB

README.md

File metadata and controls

71 lines (53 loc) · 4.37 KB

gdb_2_root

This python script adds some usefull command to stripped vmlinux image.

What is this and why

This script adds some usefull commands for debugging kernel without symbols.

The main goal is to obtain a root shell with Android Emulator using common Google Play Images with the built-in kernel.

I started this little script because I needed a way to easily obtain a root shell in emulated AVD with Google Play (and Services) installed.

Installation

The installation is quite straightforward:

  1. Clone this repo
  2. Source inside GDB the script (source <path_to_repo>/root_gdb.py)

There is only one requirements: ELFFile

  pip install elffile

Usage

The script adds some usefull command to GDB.

If you only want to root a process, you can use:

  escalate <comm>/<pid>/<task_struct address>

and the script will disable selinux and change the process credentials.

Just a note: comm is intended as the field in task_struct kernel structure (char comm[16]) so it can be different from the real name (you can check the running process with ls-ps).

List of commands:

  • ptask <struct task_struct address>: Print some fields of task_struct structure.
  • f_task <comm/pid>: Search the process (by PID or COMM) and it returns the address of task_struct
  • ls-ps: List all process
  • current: GDB function. This is the address of the task_struct for the current running process
  • symbs <symbol name>: Try to find symbols using ksymtab section
  • kcall name_or_address(parameter, parameter, ...): Create a new stack frame and execute a kernel function. More of this later
  • klookup <symbs> <symbs> ...: Call kallsyms_lookup_name for each symbols passed as argument.
  • escalate: This command works like a script. It use kcall in order to disable SELinux and change the credentials of one process.

Android rooting AVD

The main objective of this script is to obtain a root shell in a any AVD without actually rooting the emulator. The steps are simple:

  1. emulator -avd <YourAVD> -ranchu -verbose | grep kernel.path: with this command you can see where the vmlinux image is located
  2. That image should be a bzImage so you should extract it. I use extract-vmlinux.
  3. You can now restart your emulator with: emulator -avd <YourAVD> -show-kernel -no-snapshot-load -ranchu -qemu -s -append "nokaslr". After the boot, open a shell with adb shell.
  4. Open GDB with gdb <path/to/extracted/vmlinux> -ex "target remote :1234"
  5. Source the script source <path/to/repo/root_gdb.py>
  6. escalate sh, wait for the completation and continue. This command refuses to execute if it is not in the context of swapper process so you should continue and break few times before catching the right process. escalate adb, this allows to have adb rooted.
  7. Enjoy your rooted Google Image emulator (or the panic :D)

The escalate commands can panic your kernel. You can retry.

Escalation example

Limitations

At this moment, this script works only with x86_64 image. In particular, I tested only with Android 10. Feedbacks are really appreciated.

There is an medium chance to panic your kernel. Just reboot and retry.

Kcall

The main command is kcall because it allows to modify the running kernel and inject the execution of kernel function. The main idea is to create a new stack frame and jump to the new address. The parameters are handled just copying the value to registers one by one.

If you need to pass some pointers, you can use kmalloc, set the value to that memory location and use that pointer as argument.

If you need others memory locations, you can call kallsyms_lookup_name(pointer_to_char*).

The return value is stored in $ret variable (so x/x $ret).

How this works

This script uses the _ksymtab in order to find init_task address. Then, we can search some fields like comm and the tasks list.

The escalation is made calling some kernel function. In particular, we can disable SELinux searching, thanks to kallsyms_lookup_name, the selinux_enforcing symbol. Then, we can create a new credential with prepare_cred and change the pointer in the task_struct structure.