新闻中心

Linux内核漏洞可能导致特权升级

作者 / 无忧主机 时间 2017-11-23 19:43:09

Andrey Konovalov最近披露了本地特权升级的漏洞,他在Linux网络子系统内部发现了漏洞,同时使用工具syzcaller“fuzzing”。在oss – sec的邮件线程中,Konovalov写道:“当构建一个带有MSG_MORE __ip_append_data()的UFO包时,调用ip_ufo_append_data()来追加。然而,在两个send()调用之间,append路径可以从UFO切换到非UFO,这会导致内存损坏。

NIC分流和UFOs
网络接口卡(NIC)卸载允许协议栈传输大于以太网最大传输单元(MTU)的数据包,默认情况下是1500字节。当启用NIC offload时,内核将把多个数据包组装成一个大数据包,并将其传递给硬件,硬件处理IP碎片并将其分割成mtu大小的包。这种卸载经常使用高速网络接口来提高吞吐量,因为UFO可以发送大型的UDP数据包。 Linux内核可以利用各种NICs的分段卸载功能。
引发POC
下面是一个简单的概念证明 15108897525359 要在内核中构建UFO数据包,我们可以采取以下两个步骤之一:
使用UDP_CORK套接字选项,该选项告诉内核将此套接字上的所有数据累加到单个图中,以在禁用该选项时传输; 调用send / sendto / sendmsg时,使用MSG_MORE标志,告诉内核将此套接字上的所有数据累加到单个图中,以便在未指定此标志的调用时发送。此方法触发此漏洞。
在内核中,udp_sendmsg函数负责构造UDP数据包并将其发送到下一层。以下代码显示了在调用send / sendto / sendmsg时,由用户程序使用UDP_CORK套接字选项或MSG_MORE标志启用的UDP软木塞功能的剥离实现。启用UDP连接时,会调用ip_append_data函数将多个数据包累积为单个大数据包。 2221   函数ip_append_data是__ip_append_data的封装,它负责管理套接字缓冲区,方法是分配一个新的套接字缓冲区来存储传递给它的数据,或者在套接字被塞住时将数据附加到现有的数据。这个功能执行的一个重要任务是处理UFO。套接字缓冲区在套接字的发送队列中进行管理。在塞住套接字的情况下,队列中可以添加附加数据的条目。数据位于发送队列中,直到udp_sendmsg确定是时候调用udp_push_pending_frames,udp_push_pending_frames完成套接字缓冲并调用udp_send_skb。 Linux内核将数据包存储在结构sk_buff(套接字缓冲区)中,所有网络层都使用它来存储它们的标题,有关用户数据(有效负载)的信息以及其他内部信息。 2223 内核中的套接字缓冲区。 在上图中,sk_buff的头部,数据,尾部和尾部成员指向存储协议头部和用户有效载荷的内存区域的边界。头部和终点指向分配给缓冲区的空间的开始和结束。数据和尾部指向整个空间内的用户数据的开始和结束。紧接在结束边界后面,结构skb_shared_info包含IP分片的重要信息。
内存腐败
如前面的POC中所示,当第一次调用“send”时,MSG_MORE标志被调用,__ip_append_data通过调用ip_ufo_append_data创建一个新的套接字缓冲区,如下面的代码所示: 31 当这个调用完成,并且创建了新的套接字缓冲区时,用户数据被复制到片段中,共享信息结构被更新为片段信息,如下图所示。新创建的sk_buff被放入队列中。 32 在下一步中,PoC通过设置选项SO_NO_CHECK来更新套接字以不计算UDP上的校验和; 这将覆盖套接字结构的sk-> sk_no_check_tx成员。在__ip_append_data里面,这个变量被检查为调用ip_ufo_append_data之前的一个条件。 在POC第二次调用“发送”的过程中,在__ip_append_data内部采用非UFO路径,该路径进入片段长度计算循环。在循环的第一次迭代期间,副本的值变为负值,这会触发新的套接字缓冲区分配。另外碎片计算超过MTU并触发碎片。这会导致通过使用skb_copy_and_csum_bits函数将用户有效载荷从第一个发送调用创建的sk_buff复制到新分配的sk_buff。这将从源缓冲区中复制指定数量的字节到目标sk_buff并计算校验和。调用长度大于新创建的sk_buff边界结束限制的skb_copy_and_csum_bits会覆盖套接字缓冲区之外的数据,并破坏之前为sk_buff的skb_shared_info结构。 41 接下来是损坏的skb_shared_info结构。地址0xffff88003a4ca900处的内存是新创建的sk_buff,结尾= 1728,其中分段被触发。 42 当大多数默认的Ubuntu桌面系统允许非特权用户命名空间时,这个bug可以被非特权用户利用。用户应该可以做两件事情: 1:建立一个启用了UFO的接口(可能来自用户名字空间),或者使用那个接口(如果它已经存在)。(“lo”界面默认启用UFO。) 2:禁用NETIF_F_UFO接口功能或设置SO_NO_CHECK套接字选项。 代码执行可以通过在一个大缓冲区末尾简单地创建一个伪造的skb_shared_info结构并将回调成员设置为shellcode来转移到用户模式的shellcode。第二个“send”会触发套接字缓冲区的超出边界条件,用用户模式shellcode地址覆盖skb_shared_info-> destructor_arg,在从内核内存释放sk_buff之前调用该地址。 当暴露给非特权用户时,Linux内核提供了一个大的攻击面。所有的用户应该保持他们的系统补丁与最新的更新。

本文地址:https://www.51php.com/safety/25702.html

1
1
1
1
1
1
1

客户服务热线

0791-8623-3537

在线客服