Android系统漏洞提权

(一) 序言

 1.1什么是root
Root——也就是我们这里说的系统提权,通常是针对Android系统的手机而言,它使得用户可以获取Android操作系统的超级用户权限。root通常用于帮助用户越过手机制造商的限制,使得用户可以卸载手机制造商预装在手机中某些应用程序,以及运行一些需要超级用户权限的应用程序。Android系统的root与Apple iOS系统的越狱类似。

 1.2如何实现root
 一般root有两种方式,一种是在recovery模式下刷入root包,另外一种就是利用系统层漏洞(应用层漏洞或内核漏洞)达到root提权目的,以下文章将简单介绍一下如何利用系统漏洞进行root提权。
关于root的效果,可以简单的分为两种:一种仅自身进程获得root权限;另外一种是自身程序和其它程序都能获取到root权限。

(二)基础知识

 2.1文件权限

 

 系统中文件的访问权限是通过用户ID(UID)和用户组ID(GID)来控制的。
 每一个用户都分配有一个UID,然后所有的用户又按组来进划分,每一个用户组都分配有一个GID。注意,一个用户可以属于多个用户组。
Linux中的每一个文件都具有三种权限:Read、Write和Execute。这三种权限又按照用户属性划分为三组:Owner、Group和Other。

 2.2进程UID
 
 在 默认情况下,进程UID等于创建它的进程的UID,即父进程的UID。第一个进程是init进程,内核在启动完成后创建的,UID是root。其它进程, 都是直接由init进程,或间接由init进程的子进程来创建。在父进程在创建(fork)子进程之后,可以调用setuid等来改变它的UID。

(三) setresuid提权

 3.1技术背景
setresuid0,0,0)可以用来设置进程的EUID,实现为当前进程提权的目的。但是普通用户直接调用并不能实现提取,原因如下:

 

 上 图中对应了内核文件中setresuid的部分代码信息,通过分析可以发现,函数在真正进行setresuid之前会对调用者拥有的权限进行检查,如上图 红框中的内容,满足调用权限时,R0的值为#0,对于普通用户的调用,R0是一个非零值,所以如果我们把比较的对象#0改成一个非零值,那么 setresuid的可以成功调用进行置位。
 至此,归结起来,我们要利用setresuid实现提权,需要解决如何修改内核文件的问题。步骤:
Step1:找到目标代码虚拟地址
Step2:找到目标代码的物理地址
Step3:利用漏洞修改内核文件
Step4:调用setresuid(0,0,0)提权

3.2寻找代码位置
①从手机中拖取内核img文件(也可以寻找匹配的刷机包,从里面直接获取)

②将img文件导出到PC,利用binwalk分析img文件

 一般(经验上,不一定100%准确)我们认为第一个出现的比较长的gzip段就是内核文件。
③利用dd从img文件中提取内核

④从内核文件中定位需要修改的代码位置
如果直接将刚刚解压出来的文件拖到IDA里面,我们是找不到setresuid的,因为我们缺少一个符号表——kallsyms:

 这里是在root下获取kallsyms,由于篇幅限制,这里就不介绍非root权限下获取kallsyms的方法了,大家自己找吧。
将kallsyms导出来后,利用扩展插件load起来,然后就可以在在IDA中找到对应的函数了,从而确定函数在内核文件中的虚拟地址(0xC009D12C),目标代码相对于内核起始地址的偏移offset= 0xC009D12C – 0xC0000000 = 0x9D12C
 ⑤获取目标代码的物理地址
 内核的起始物理地址:

 目标代码的物理地址:phaddr =  0x8600000 + 0x9D12C

 3.3寻找提权漏洞
 这里我们以华为mt2_u071中的一个mmap提权漏洞为例。
 扫描整个手机文件系统,发掘可疑文件:

 这个文件other应用rwx权限,列为可疑对象。
 同时在另外一个文件/kerneldrivers/hisi/hifidsp/hifi_lpp.c中:

 通过分析,发现phys_page_addr是固定值0x05a00000,结合remap_pfn_range函数的定义,我们知道phys_page_addr是物理地址,那么上面的代码就可以实现往一个固定的物理地址写数据的功能。
 更进一步分析发现当前文件中file_operations结构体hifi_misc_fops,在里面将mmap函数重定向到hifi_misc_mmap函数。
 

到这里我们先小小的总结一下:
mmap这个函数我们是可以随便调用的,结合我们的需求(到指定的物理地址上修改数据),由于要写的地址是受保护的,需要高权限。那么前面发现的“可疑对象”/dev/hifi_misc这时候就可以发威了。
物理地址上,目标代码相对于phys_page_addr的偏移 = 0x8600000 + 0x9d12c -0x5a00000 

3.4 漏洞提权代码


 至此,当前进程获得了root权限。

【via@比戈大牛