长亭科技于晨升在中国互联网安全领袖峰会现场发表演讲

作者:杜美洁 来源:北京长亭科技有限公司
2016-11-11 14:22:00

北京和上海2016年11月11日电 /美通社/ -- 现就读于北京理工大学计算机系,来自长亭科技安全研究实验室的实习生于晨升在第二届中国互联网安全领袖峰会上做了题为《我的手机怎么被别人控制了?-- 利用未公开漏洞ROOT掉一款最新款的流行手机》的精彩演讲。以下是来自51CTO.com的报道原文《干货分享| 教你如何利用漏洞ROOT安卓手机》:

随着移动互联网的快速发展,智能手机、平板电脑等智能终端设备逐渐普及,慢慢的融入了我们的生活。然而与此同时智能手机安全问题也越来越凸显,手机支付漏洞、手机远程定位、手机信息泄露等问题屡见不鲜。

11月9日,为期两天的第二届中国互联网安全领袖峰会(Cyber Security Summit,简称CSS)在北京成功召开。作为主办方的腾讯安全携手来自世界的顶级安全厂商、产业链上企业、个人等围绕时下物联网、互联网+等诸多议题进行探讨。并在大会第二日特设了安全极客秀分论坛,该论坛邀请了来自今年GeekPwn的优胜选手,对当时未能展示完全的项目进行深入展示。来自长亭科技安全研究实验室的实习生于晨升带来了题为《我的手机怎么被别人控制了?-- 利用未公开漏洞ROOT掉一款最新款的流行手机》的精彩演讲,现在他正就读于北京理工大学计算机系。

在论坛现场,首先他邀请了一位参会者一起演示了如何利用未公开漏洞控制安卓手机,随后与大家分享了自己是如何发现并利用漏洞,最终控制安卓手机的。

Android系统架构解析

于晨升指出,想要利用漏洞进行攻击,第一步应该对Android系统架构有足够的了解才行。Android系统架构主要分为四层,即是:Application层、Framework层、Library层以及Kernel层。手机的自带应用在Application层,这一层从安装到运行其权限最低。Framework层主要为Application层的应用提供系统服务,随后在安卓程序运行时,需要第三层Library层的支持,通过此层引入运行时所依赖的动态库。Kernel层为系统内核层。特别是在Android系统第四层内核层中包含许多厂商相关的驱动,例如显卡、相机、触摸屏的驱动等。于晨升表示,为了支持不同的手机不同的芯片,需要进行驱动编写给用户提供相同的接口,导致厂商驱动的安全性比Android内核本身的安全性差,厂商驱动为Android系统带来了新的攻击面新的漏洞。因此,寻找手机漏洞,可以从这个层面出发。

漏洞分析

在分会场现场,于晨升针对最新的一款手机实现了ROOT,所利用的漏洞还未公开,所以他选择了一个已经公开并修补的漏洞分享了CVE-2015-0569,CVE-2015-0570, CVE-2015-0571三个已知漏洞的利用思路和过程。

据悉,这三个漏洞由slipper在2015年的GeekPwn上公开,存在于高通WLAN驱动中的栈溢出与堆溢出漏洞,漏洞由于在进行内存拷贝之前未检验拷贝长度,导致缓冲区溢出。随后高通第一时间修补了漏洞,在内存拷贝操作之前进行了检查,同时在调用对应的代码块之前进行了权限检查(CAP_NET_ADMIN)。

漏洞利用

如何从发现漏洞到利用漏洞,再获得手机root权限呢?于晨升解释说,触发漏洞后,就能够达到的任意内核地址写0效果。从0开始的地址无法申请,写函数指针写0无法实现,所以需要提升条件,写0但是不把所有的指针写为0只是更改高位的,然后对地址进行操作。无KASLR,覆写固定地址的指针高位是可行的。有时改写函数值是不可行的,因为多数ARM64架构的手机上PXN是打开的,不能直接申请一段用户态内存让内核去执行shellcode。那么此时该如何利用呢?

为了解决以上问题,于晨升在链表头数组inetsw中寻找到了突破口,如图所示:

inetsw是linux内核用于维护socket创建时所需要的信息的双向链表,inet_register_protosw时,将特定类型的socket信息加入到链表中, inet_create时遍历链表寻找对应信息。包含proto, ops等结构的指针,这些结构中又含有许多的函数指针。

因此,如果在无PAN的条件下,覆写inetsw中某一个next指针的高位,在用户态伪造数据结构,可创建一个完全被控制的socket,最终达到如下效果:

如图所示,我们可以看到PC指针形成了一个特殊的指令,此时我们可以控制PC指令了。

那么,控制PC之后如何进一步利用呢?此时无法执行用户态代码,只能利用内核态代码。我们注意到ioctl中r0, r1, r2寄存器可以控制,于是可以利用以下gadget达到任意地址读写:

0x000000000021b598 : str w1, [x2] ;ret

0x00000000001e246c : ldr x0, [x2] ;add w0, w0, #1 ;ret

通过任意地址读写,利用init_task可以找到当前进程的task_struct(或者利用泄露sp的gadget,通过thread_info找到task_struct,更稳定)。找到task_struct之后即可修改cred,将uid等改为0即可。同时patch掉selinux_enforcing,关掉selinux、mount -o rw,remount /system即可关掉/system分区写保护。在实际利用中,发现mtk设备的内核代码是可写的。在关闭selinux之后,某处的assert会失败,可以利用上面的特性patch掉assert的代码。或者通过修改修改当前进程的sid,将其selinux的context修改为u:r:init:0。实际测试中,我们会发现u:r:init:0进程启动/system/bin/sh后权限会降为u:r:init_shell:0。

总结

演讲最后,于晨升表示,Android 6.0/7.0版本中已经增强了SEPolicy,防止未经授权的app访问白名单以外的设备,减少了攻击面,大大增强了安全性。并建议,厂商应该更加重视自家驱动的安全性,防止被黑客滥用,造成恶劣影响。

作者:杜美洁