神刀安全网

让子弹继续飞-如何利用一个漏洞代码root更多手机

让子弹继续飞-如何利用一个漏洞代码root更多手机

安卓漏洞攻防 bydroidsec

0x01 前言

随着linux漏洞挖掘的深入,品相极好的任意地址读写皆备的漏洞已经难得一见
(如putuser/getuser)。大部分的漏洞都是任意地址写或者是代码执行路径可控的漏洞,而且从内核2.6.37开始,普通shell用户没有办法从/proc/kallsyms中读到内核符号表地址,为了适配不同的安卓/linux设备,大部分的漏洞利用代码不得不针对不同的设备进行硬编码适配。

本文介绍一种方法,这种办法不需要对特定的手机进行硬编码,使得漏洞利用代码更容易在各种设备上运行和验证。为了方便学习,本文的附件中还给出了相关的针对CVE-2014-4323漏洞的免硬编码的利用代码, 这些代码在SAMSUNG I9508中测试通过。

0x02  inet_diag信息泄漏问题

为了动态适配设备,我们需要借助信息泄露的漏洞,才能实现完美的任意地址读写。
信息泄露的漏洞好比是雷达定位,如果不知道要写的目标地址,那么我们就只能硬编码了。
幸运的是LINUX内核的信息泄露的地方还不少,而且一直不受重视。
Netlink 是一种特殊的 socket,它是 Linux 所特有的,用户空间进程可以通过标准socket API来实现消息的发送、接收,在Linux中,有很多用户空间和内核空间的交互都是通过Netlink机制完成的。
通过netlink的NETLINK_INET_DIAG协议,用户空间的程序可以获取当前系统tcp连接的状态信息,类似ss 或netstat后的效果。
通信过程简单描述:
用户空间通过i_net_diag_request发起请求,
内核通过inet_diag_msg将数据返回到用户空间。

内核返回的inet_diag_msg中有个结构体inet_diag_sockid,netlink通信中通过这个结构体唯一标示了一个socket, 在这里socket不是用的五元组,而是源ip:源端口,目的ip:目的端口,从哪个设备获得的,还有唯一的标示内核中的一个socket的cookie,这个cookie值是在内核中计算sock结构体的sk_cookie域得出来的。

让子弹继续飞-如何利用一个漏洞代码root更多手机

在net/ipv4/inet_diag.c源代码中我们可以发现
sk_diag_fill/inet_twsk_diag_fill都会调用到sock_diag_save_cookie函数, sock_diag_save_cookienet/core/sock_diag.c中

sock_diag_save_cookie函数实现如下
void sock_diag_save_cookie(void *sk, __u32 *cookie) {
cookie[0] = (u32)(unsigned long)sk;
cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1);
}

在inet_diag调用会返回cookie,该cookie数组包括了sk的低32位地址及高32地址。对于32位的系统来说,cookie[0]泄漏了sock结构的地址。

0x03 sock结构体介绍

每个socket数据结构都有一个sock数据结构成员,sock是对socket的扩充,两者一一对应,socket->sk指向对应的sock,sock->socket
指向对应的socket; 操作系统把 socket通信分成两部分,把与文件系统关系密切的放在socket结构中,把与通信关系密切的放在另一个单独结构sock中;
sock记录了SOCKET通信的地址,端口号及相关的SOCKET操作函数指针。

struct sock {

__u32 daddr; // dip,Foreign IPv4 addr

__u32 rcv_saddr; // 记录套接字所绑定的地址

__u16 dport; // dport

unsigned short num; /* 套接字所在的端口号

….

struct proto *prot; // 例如指向tcp_prot

void (*state_change)(struct sock *sk);

void (*data_ready)(struct sock *sk,int bytes);

void (*write_space)(struct sock *sk);

void (*error_report)(struct sock *sk);

int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb);

void (*destruct)(struct sock *sk);

};

我们比较关心的是void (*destruct)(struct sock *sk);

当socket被关闭时destruct指针指向的函数将被执行。

当然我们也可以修改prot的相关指针来实现漏洞触发。

下面是inet_diag的sock结构的几个函数指针示例。

inet_sock_destruct函数指针的偏移地址根据不同的内核版本有不同,我们建立起这样的表格对应起来就行。

0x03 总体流程

1. 建立netlink服务监听。
2. 通过inet_diag的netlink通信,从内核返回的cookie中获得sk结构体的地址。
3. 利用任意地址写的能力,修改sk中destruct的函数指针。使其指向我们的shellcode地址。
4. 关闭第一步建立的socket,触发shellcode的调用,获得root权限。

0x05 提权代码的动态适配

提权代码一般为commit_creds(prepare_kernel_cred(0)和修改task_struct的两种。其中commit_creds方式就需要针对不同的设备进行硬编码。而修改task_struct可以通过代码来解决适配的问题。Towelroot和shengdi的漏洞代码中就很经典地运用了这些技巧。
修改task_struct的方式可以总结如下:
1.  通过shellcode的临时变量,泄漏sp地址。
2.  通过sp地址和thread_info共用4K/8K空间的特点定位到thread_info地址。
3.  判断thread_info的addr_limit的地址范围,确定task_struct的位置。
4.  判断task_struct中的comm是否为进程名。
5.  判断cred和real_cred是否在内核地址范围而且相关参数相等,定位到cred和read_cred的偏移。
6.  修改cred和read_cred相关参数的值。
7.  判断是否是selinux,如果是定位到tsec结构体的地址。
8.  修改tsec结构体的参数的值。Bypass seliux。

0x06 CVE-2014-4323介绍

高通MSM设备中使用的MDP display driver for the Linux kernel 3.x版本的drivers/video/msm/mdp.c文件中的‘mdp_lut_hw_update’函数存在安全漏洞,该漏洞源于程序没有验证ioctl函数调用中的‘start’和‘length’值。攻击者可借助特制的应用程序利用该漏洞获取权限。
下列高通芯片的设备都存在有这个漏洞,具体的芯片信息如下:

lAPQ 8064 (Snapdragon S4 Pro)

lMSM 8960 (Snapdragon S4)

lMSM 8660 (Snapdragon S3)

lMSM 8×30lMSM 7×30

配备了上述芯片的移动设备(例如三星s4,Nexus 4和Nexus 7等设备),

以及内核日期在2014年12月之前的设备都会受到这个漏洞的影响。

该漏洞是个具备任意地址写能力的漏洞, 原有的exploit是commit_creds(prepare_kernel_cred(0))方式来提权的,这就需要针对不同的设备进行硬编码。

在本文的代码中,我们通过泄漏sock的地址,通过漏洞修改inet_sock_destruct函数指针的地址,使得函数指针指向我们的shellcode。

值得一提的是我们的shellcode并没有采用commit_creds(prepare_kernel_cred(0)方式来提权,而是采用修改task_struct的相关参数来实现的。这很大程度上也避免了硬编码。

0x07 总结

有时候漏洞虽然只有任意地址写的能力,但是由于linux系统中依然有不少信息泄漏的问题,使得我们可以确定写入的地址,从而触发权限获取代码的执行。
长期以来,linux信息泄漏的问题没有得到很好的重视,但随着漏洞利用难度的加大,linux信息泄漏的漏洞将会被更多地利用,在研究过程中,我还发现通过一些信息泄露漏洞无需麻烦的进行JOP轻松绕过PXN,相信今后LINUX信息泄露的漏洞会得到LINUX社区的更多重视。

0x08参考资料

1. 安卓内核源代码

http://androidxref.com/kernel_3.10/x…v4/inet_diag.c

2. Linux内核工程导论–网络:TCP:netlink与tcp_diag编程

http://blog.csdn.net/ljy1988123/arti…tails/51025298

3. Andorid 的内核提权漏洞 (CVE-2014-4323)

http://bobao.360.cn/learning/detail/609.html

4.申迪-CVE-2014-4322 exploit源代码

http://www.retme.net/index.php/2015/…7911_4322.html

转载自:http://bbs.pediy.com/showthread.php?t=211017    原文作者:ggggwwww

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 让子弹继续飞-如何利用一个漏洞代码root更多手机

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址