作者:看具戴_370 | 来源:互联网 | 2023-10-13 16:02
作者:360MarvelTeam稿费:600RMB(不服你也来投稿啊!)投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿前言360 Marvel Team一直致力于云安全领域技术研
作者:360MarvelTeam
稿费:600RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
360 Marvel Team一直致力于云安全领域技术研究。在刚刚过去的Pwnfest比赛中一举完成vmware workstation的首次破解,实现虚拟机逃逸攻击全球首秀。团队目前在qemu,kvm,xen,docker,vmware workstation,vmware esxi,linux kernel中都已积累了丰富的漏洞挖掘和利用经验。linux kernel漏洞可以帮助攻击者在虚拟机逃逸之后夺取宿主机最高权限,也可以使黑客完成docker容器攻击,是云系统漏洞攻击链条中非常关键的一环。在这篇文章中,Marvel Team将分享一枚最新公开的linux kernel漏洞的相关研究成果。
360 Marvel Team目前正在招聘 漏洞挖掘&漏洞利用&linux内核及应用层开发 岗位,有兴趣的同学欢迎发简历到tangqinghao@360.cn。
0x0 序
TIPC网络协议也叫透明进程间通信协议,是一种进程间通信的网络协议,原本是为集群间通信特别设计,Linux kernel 自2.6.16版本开始支持TIPC协议,该协议在VxWorks和Solaris操作系统中应用广泛。然而TIPC处理数据切包的代码存在一处堆溢出,可造成特权提升。漏洞说明见:https://access.redhat.com/security/cve/cve-2016-8632。
0x1 漏洞细节
当创建一个TIPC协议的socket后,可以通过很多种方式触发tipc_msg_build。比如说用户态调用connet,TIPC协议栈根据当前socket的状态,需要发送第一个SYN包,然而这时需要调用tipc_msg_build来构造TIPC的协议头(长度可变),如下图:
首先解释几个变量含义:
1. msz : TIPC协议头长度 + 实际发送数据长度。
2. pktmax : 实际上是上层函数传递下来的TIPC协议设置的MTU,该值可从设备MTU继承
3. skb : socket buffer数据结构,其中包含一个char *类型的data指针,指向实际缓冲区
4. dsz : 附加数据的长度
5. mhsz : TIPC协议头长度,该协议内容根据用户态传递的目标地址类型不同而不同
从上图可以看出,如果要发送数据长度小于设备允许的最大传输单元,则数据包不需要切包,可以直接发送出去,否则把数据包按pktmax长度切开,然后依次发送出去。
函数根据pktmax创建socket buff,之后进行两次skb_copy_to_linear_data操作。
两次memcpy的长度是INT_H_SIZE + mhsz:
1. INT_H_SIZE长度固定为40字节
2. mhsz根据目标地址类型不同而不同,可取的值是24、32、40、44、60字节
我在POC中设置mhsz为32字节,那么两次memcpy共拷贝72字节。该函数在memcpy前并没有检查pktmax(MTU)是否小于INT_H_SIZE + mhsz, 然而回溯调用堆栈也没有发现内核检查过MTU的值。
那么在内核其它地方创建一个MTU小于72字节,也就能够造成堆溢出。
接下来就需要寻找TIPC是如何设置MTU的,以得到可用最小的MTU值。内核在调用tipc_msg_build 前会根据目的地址类型不同,调用2种不同方法获取MTU值,但是无论哪种方法其实都是取TIPC link上的MTU值:
TIPC link是当整个TIPC网络出现2个以上节点后,内核调用tipc_node_link_up自动建立的
当TIPC link建立后,n->links结构的mtu属性被赋值,然而这里减去了40字节的头大小,然并卵,还是没有检查合法的最小MTU大小。
tipc_link_mtu()的值由tipc_link_set_mtu()设置,tipc_link_set_mtu()在整个4.9-rc4内核代码中只有一处调用,就是在tipc_bcbase_select_primary()。
那么这里可以清晰的看到mtu的值来自于tipc_bearer_mtu(),整个内核只有2处修改过tipc bearer的值,一个是当TIPC网络建立后,内核调用tipc_enable_l2_media()
另一处是当我们在shell中使用类似 `ifconfig eth0 mtu 60 up` 来修改网络设备MTU时,内核调用tipc_l2_device_event():
通常情况下网络设备MTU的值是1500,当然这个值最大最小区间需要根据不同的网卡驱动来决定,比如我的网卡驱动是e1000,支持的mtu最小是46
那么问题来了:
1. 把设备MTU设置成60(大部分网卡驱动最小支持MTU是60)
2. 创建TIPC网络,当TIPC link建立成功后,内核调用tipc_node_link_up()
3. tipc_node_link_up()这时候又把60减了个40,使得n->links[bearer_id].mtu = 20
4. 调用connect,触发tipc_msg_build,因为最小的TIPC协议头也得24,所以需要切包
5. 以20字节申请socket buffer
6. 第一次调用skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE), 溢出40 – 20字节
7. 第二次调用skb_copy_to_linear_data_offset(skb, INT_H_SIZE, mhdr, mhsz),再次溢出mhsz字节
第一步修改设备MTU,用户不得具有CAP_NET_ADMIN权限么,然而如果clone出一个具有user_namespace及net_username的进程则可以轻松修改设备MTU
0x2 漏洞影响
大部分网卡驱动最少可以溢出52字节,如果合理布局堆空间,可以造成特权提升。
受影响的较新内核版本:
Linux kernel 4.9-rc4
Linux kernel 4.9-rc3
Linux kernel 4.9
Linux kernel 4.8.3
Linux kernel 4.8.1
Linux kernel 4.8 rc1
Linux kernel 4.8
Linux kernel 4.7.9
Linux kernel 4.7-rc6
Linux kernel 4.7-rc5
+ Redhat Linux 7.2
+ S.u.S.E. Linux 7.2
+ S.u.S.E. Linux 7.1
Linux kernel 4.6.3
Linux kernel 4.6.2
未测试较旧内核版本
0x3 补丁及相关
https://www.mail-archive.com/netdev@vger.kernel.org/msg133205.html
https://access.redhat.com/security/cve/CVE-2016-8632
http://www.securityfocus.com/bid/94211/info
传送门
360 Marvel Team虚拟化漏洞第一弹 – CVE-2015-6815 漏洞分析
360 Marvel Team虚拟化漏洞第二弹 – CVE-2015-5279 漏洞分析
360 Marvel Team虚拟化漏洞第三弹 – CVE-2015-7504 漏洞分析(含高清视频)
360 Marvel Team虚拟化漏洞第四弹 – CVE-2015-8567 漏洞分析
360 Marvel Team虚拟化漏洞第五弹 – CVE-2016-3710 Dark Portal漏洞分析