【漏洞预警】雪藏11年:Linux kernel DCCP double-free 权限提升漏洞(CVE-2017-6074)

http://p3.qhimg.com/t0174949ebbab22aee9.jpg

漏洞描述

漏洞编号:CVE-2017-6074

漏洞发现者:Andrey Konovalov

漏洞危害:通过非特权进程获得内核代码执行进而提升权限

影响范围:Linux内核版本>2.6.18(2006年9月)。但DCCP(数据报拥塞控制协议)最早是在05年10月的Linux内核版本2.6.14中支持的。目前该漏洞与2017年2月17修复。详情请参看

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5edabca9d4cff7f1f2b68f0bac55ef99d9798ba4 

漏洞细节

数据报拥塞控制协议(DCCP)是一个针对传输层中UDP的新传输的协议而发展出来,用来传输实时业务。他是一个可以进行拥塞控制的非可靠传输协议,并同时提供多种拥塞控制机制,在通信开始时由用户进行协商选择。

更多详细的介绍说明:

https://www.kernel.org/doc/Documentation/networking/dccp.txt

http://www.read.cs.ucla.edu/dccp/ 

这个漏洞需要内核编译的时候开启CONFIG_IP_DCCP ,许多linux发行版本默认开启。

在当前DCCP实现中,如果dccp_rcv_state_process中的dccp_v6_conn_request返回“成功” ,dccp_type 为DCCP_PKT_REQUEST的packet的skb会被__kfree_skb强制释放。

但是,如果在socket上设置IPV6_RECVPKTINFO,则skb地址会被保存在ireq-> pktopts,然后dccp_v6_conn_request中会增加skb的引用计数,所以skb仍在使用中。然而,它仍然会在dccp_rcv_state_process中被释放。

修复的方式是调用consume_skb,它占用skb->users,而不是跳转到discard 然后调用__kfree_skb。

diff –git a/net/dccp/input.c b/net/dccp/input.c

index ba34718..8fedc2d 100644

— a/net/dccp/input.c

+++ b/net/dccp/input.c

int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 			struct dccp_hdr *dh, unsigned int len)
{
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 	const int old_state = sk->sk_state;
 	int queued = 0;
 	
 	if (sk->sk_state == DCCP_LISTEN) {
 		if (dh->dccph_type == DCCP_PKT_REQUEST) {
 			if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
 								skb) < 0)
 				return 1;
-			goto discard;
+			consume_skb(skb);
+			return 0;
 		}
 		if (dh->dccph_type == DCCP_PKT_RESET)
 			goto discard;
 		/* Caller (dccp_v4_do_rcv) will send Reset */
 		dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
 		return 1;
 	} else if (sk->sk_state == DCCP_CLOSED) {
 		dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
 		return 1;
 	}

要利用这个 double-free,可以把它转变成一个 use-after-free:

//第一次释放
kfree(dccp_skb)
//在与dccp_skb相同的位置分配的另一个对象:
some_object = kmalloc()
//第二次释放,实际释放的是some_object对象
kfree(dccp_skb)

此时some_object持有一个悬空指针,如此就构造出了一个UAF。攻击者可以控制对象,同时可以通过使用内核堆喷射技术写入任意数据到被覆盖对象。

如果被覆盖的对象有任何可触发的函数指针,攻击者可以在内核中执行任意代码。

Linux各发行版本对于该漏洞相关信息

debianhttps://security-tracker.debian.org/tracker/CVE-2017-6074 

redhathttps://rhn.redhat.com/errata/RHSA-2017-0295.html 

ubuntuhttp://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-6074.html 

susehttps://www.suse.com/security/cve/CVE-2017-6074/ 

PoC

https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074


修复建议

建议用户通过系统更新到最新发行版修复此漏洞

参考

http://www.openwall.com/lists/oss-security/2017/02/22/3

https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE 

http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2017-6074 

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5edabca9d4cff7f1f2b68f0bac55ef99d9798ba4 

https://www.kernel.org/doc/Documentation/networking/dccp.txt

http://www.read.cs.ucla.edu/dccp/ 

(完)