首页
社区
课程
招聘
[原创][原创][原创]让子弹继续飞-如何利用一个漏洞代码root更多手机
发表于: 2016-6-14 14:05 9409

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

2016-6-14 14:05
9409
让子弹继续飞-如何利用一个漏洞代码root更多手机

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域得出来的。



  在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 8x30
lMSM 7x30

   配备了上述芯片的移动设备(例如三星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/xref/net/ipv4/inet_diag.c
2. Linux内核工程导论–网络:TCP:netlink与tcp_diag编程
http://blog.csdn.net/ljy1988123/article/details/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/01/26/release_poc_7911_4322.html

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 219
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
顶大神,前排学习。
2016-6-14 15:14
0
雪    币: 248
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
前排瓜子 。。。
2016-6-14 15:21
0
雪    币: 191
活跃值: (195)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
厉害多谢大神分享
2016-6-14 16:12
0
雪    币: 138
活跃值: (470)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
欢歌 威武, 期待更精彩的 后续文章
2016-6-14 16:13
0
雪    币: 76
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不明觉厉
2016-6-14 16:16
0
雪    币: 22
活跃值: (443)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
安卓还没入门。。谁推荐本好书...
2016-6-14 16:44
0
雪    币: 68
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
前排报道学习
2016-6-14 18:07
0
雪    币: 6976
活跃值: (1477)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
10
前排学习!
2016-6-14 18:10
0
雪    币: 5594
活跃值: (2168)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢分享!
2016-6-14 18:20
0
雪    币: 20
活跃值: (210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
菜鸟前来膜拜学习,感谢分享~
2016-6-15 09:21
0
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
13
菜鸟也来学习一下子 ,楼主继续发
2016-6-15 10:03
0
游客
登录 | 注册 方可回帖
返回
//