In this article, i’ll show you how to get root after gaining kernel arbitrary address read and write.

Android 7.0 still use 3.1x version of Linux kernel by 2017.3.31. So ,we use Linux kernel 3.18 as example to explain how to gain root access. The precondition is gaining arbitrary address read and write.  Any process that fork from zygote  has  same libc / libandroid_runtime / dalvik – heap base address.

Previous ARM architecture, ARMv7, is 32-bit only ,ARMv8 has two execution modes:AArch64 and AArch32, we take arm64 as an example.

1.Basic structs of kernel

Before we make our user process root,we need to know some basic struct of linux kernel,first is thread_union:

http://androidxref.com/kernel_3.18/xref/include/linux/sched.h#2245

in arm64(AArch64) kernel stack has 16384/16k/0x4000 bytes,in arm32 ,it’s 8k bytes. Every process use the same kernel stack.

next is thread_info struct :

http://androidxref.com/kernel_3.18/xref/arch/arm64/include/asm/thread_info.h#46

thread_info struct has an element : addr_limit,this field indicate that the max address this process can access .If we set this field to -1 ,we can access any address in this process.In kernel source code, set_fs(KERNEL_DS) does the same thing:

http://androidxref.com/kernel_3.18/xref/arch/arm64/include/asm/uaccess.h#KERNEL_DS

the most important field of thread_info struct is task, this field contains almost all  infos about a process:

http://androidxref.com/kernel_3.18/xref/include/linux/sched.h#1235

Each process has it’s credentials,kernel decides how and whether a process can access other resource by credentials:

http://androidxref.com/kernel_3.18/xref/include/linux/cred.h#102

the security field is inited in cred_init_security function:

http://androidxref.com/kernel_3.18/xref/security/selinux/hooks.c#188

security field in cred is actually task_security_struct struct:

http://androidxref.com/kernel_3.18/xref/security/selinux/include/objsec.h#31

this struct is associated with SeLinux.

2.Step from user to root

after we get kernel arbitrary address read and write,we need to do the followings things to  privilege escalation  to root:

  1. find thread_info struct of current process
  2. patch addr_limit of thread_info struct
  3. find cred struct of task_struct
  4. patch cred of this process
  5. patch SeLinux

3.How to find thread_info struct

thread_info struct is at the bottom of kernel stack:

If we get some of kernel sp, we can directyly get current process’ thread_info addr by using (addr & 0xFFFFFFFFFFFFC000),because kernel stack address is always aligned.

4.How to find cred of a special process

there are many ways to find cred of a special process:

  1. find executable name ( use prctl(PR_SET_NAME, “xxx”, 0, 0, 0); to set executable name first) in a range of kernel memory.
  2. before real_cred field of task_struct , there are 3 list_head, each list_head’s next equal to pre and it’s address must be above kernel start addr.

5.Privilege Escalation

5.1 patch addr_limit

5.2 patch cred:

5.3 patch selinux

patch selinux_enforcing and selinux_enabled, set these two values to 0

6.appendix

linux cred管理

CVE-2015-1805 iovyroot 查找绝对内核地址

exploiting-stack-overflows-in-the-linux-kernel

https://www.kernel.org/doc/Documentation/arm64/memory.txt

https://events.linuxfoundation.org/images/stories/pdf/lcna_co2012_marinas.pdf

http://files.cnblogs.com/files/jiayy/xkungfoo2015-%E7%94%B3%E8%BF%AA.pdf

http://blog.csdn.net/hu3167343/article/details/47394707

观看更多有关 的文章?

*

+
跳转到评论