Linux惊现四个高危内核漏洞:
近日启明星辰ADLab(积极防御实验室)发现Linux内核存在四个极度危险的漏洞——代号“Phoenix Talon”(CVE编号:CVE-2017-8890、CVE-2017-9075、CVE-2017-9076、CVE-2017-9077)。经研究这些漏洞在Linux内核中至少已经存在了11年,几乎影响了这11年间发布的所有Linux内核和对应的发行版本以及相关国产系统。
漏洞危害
Linux存在着许多不同的版本,比如Redhat、Centos、Ubuntu、Suse,包括很多国产化操作系统也使用了Linux内核。Linux凭借其开源和安全性的优势,常被用作网站、游戏、应用服务器的操作系统。除此之外Linux可以运行在多种硬件平台上,比如X86服务器、台式计算机、网络设备、平板电脑、机顶盒、游戏机等。
“Phoenix Talon”漏洞可被攻击者利用来发起DOS攻击,且在符合一定利用条件的情况下可导致远程代码执行,包括传输层的TCP、DCCP、SCTP以及网络层的IPv4和IPv6协议均受影响。如攻击者利用该漏洞发起攻击可导致部署Linux操作系统的网站服务器、应用服务器、中间服务器宕机或被控制!
这些漏洞中以CVE-2017-8890最为严重,该漏洞一举拿下了Linux内核漏洞两个评分标准的史上最高分: CVSS V2评分达到满分10.0,CVSS V3评分是历史最高分9.8,由此可见该漏洞的恐怖程度!!!
影响范围
◆受影响的内核版本:
◆受影响的发行版本:
经开源社区验证部分受影响发行版本(不完整列表)如下:
Red Hat Enterprise MRG 2
Red Hat Enterprise Linux 7
Red Hat Enterprise Linux 6
Red Hat Enterprise Linux 5
SUSE Linux Enterprise Desktop 12 SP1
SUSE Linux Enterprise Desktop 12 SP2
SUSE Linux Enterprise Server 11 SP3 LTSS
SUSE Linux Enterprise Server 11 SP4
SUSE Linux Enterprise Server 12 GA
SUSE Linux Enterprise Server 12 SP1
SUSE Linux Enterprise Server 12 SP2
SUSE Linux Enterprise Server for SAP 11 SP3
SUSE Linux Enterprise Server for SAP 11 SP4
SUSE Linux Enterprise Server for SAP 12 GA
SUSE Linux Enterprise Server for SAP 12 SP1
SUSE Linux Enterprise Server for SAP 12 SP2
另外,启明星辰ADLab对下列的部分发行版本做了测试,确认均受“Phoenix Talon”漏洞影响:
Ubuntu 14.04LTS (Trusty Tahr)
Ubuntu 16.04LTS (Xenial Xerus)
Ubuntu 16.10(Yakkety Yak)
Ubuntu 17.04(Zesty Zapus)
Ubuntu 17.10(Artful Aardvark)
漏洞修复建议
“ Phoenix Talon ”在Linux内核中潜伏长达11年之久,影响范围非常广泛,漏洞如被利用,其攻击代码无法在网络层进行有效检测,因此请广大用户及时对该漏洞进行检测并给存在问题的系统内核打上补丁,避免遭受该漏洞导致的网络安全事件!
来源:启明星辰
CVE-2017-8890本身是一个 double free 的问题,使用setsockopt()函数中MCAST_JOIN_GROUP选项,并调用accept()函数即可触发该漏洞。
接着先看看几个组播相关的数据结构:
该结构体的两个成员分别用于指定所加入的多播组的组IP地址和所要加入组的本地接口IP地址。ip_setsockopt()实现了该功能,它通过调用ip_mc_join_group()把socket加入到多播组。
其中sk.__sk_common.skc_rcv_saddr对于组播而言,只接收该地址发来的组播数据,对于单播而言,只从该地址所代表的网卡接收数据;mc_ttl为组播的ttl;mc_loop表示组播是否发向回路;mc_index表示组播使用的本地设备接口的索引;mc_addr表示组播源地址;mc_list为组播列表。
next_rcu指向链表的下一个节点;multi表示组信息,即在哪一个本地接口上,加入到哪一个多播组;sfmode是过滤模式,取值为MCAST_INCLUDE或MCAST_EXCLUDE,分别表示只接收sflist所列出的那些源的多播数据报和不接收sflist所列出的那些源的多播数据报;sflist是源列表。
下面分别从该漏洞内存分配的关键代码及二次释放的关键代码进行分析。
1、The Allocate
内存分配调用链:
使用setsockopt()函数中的MCAST_JOIN_GROUP选项。
net/socket.c
进入内核调用SyS_setsockopt()函数,level 设置的不为 SOL_SOCKET即可,一般设置为SOL_IP,在1798行处被调用。紧接着调用sock_common_setsockopt()函数。
net/ipv4/ip_sockglue.c
然后进入ip_setsockopt()函数,调用 do_ip_setsockopt()函数(1264行代码)。
net/ipv4/ip_sockglue.c
代码1019~1021行调用copy_from_user()将用户态的数据拷贝到内核态。之前已经将option设置为MCAST_JOIN_GROUP,紧接着调用ip_mc_join_group()函数:
net/ipv4/igmp.c
代码2128行sock_kmalloc()进行了内存分配。
2、The first free
在内核里无时无刻都在产生软中断,而此次漏洞涉及的软中断是由 accept()系统调用引起的,由于该函数本身作用于进程上下文,并不会产生软中断。但是调用 accept() 时,会在内核中诱发某种软中断产生,该软中断会调用rcu_process_callbacks()函数:
kernel/rcu/tree.c
__rcu_process_callbacks调用rcu_do_batch()函数,如下:
kernel/rcu/tree.c
注意代码中第2879行,函数__rcu_reclaim()实现如下:
kernel/rcu/rcu.h
在113行调用kfree()进行了第一次释放。
3、The second free
当断开TCP连接时,内核通过sock_close()函数直接调用sock_release()来实现断开功能,该函数会清空ops,更新全局 socket 数目,更新 inode 引用计数。随后进入到 inet_release()函数调用 tcp_close()函数来最终关闭 sock。
net/ipv4/af_inet.c
用户程序断开TCP连接时,内核里使用 ip_mc_drop_socket()函数进行回收。
net/ipv4/igmp.c
代码2612行调用kfree_rcu()进行第二次释放。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课