VenusEye首页 > 资讯列表 > Linux内核SCTP协议漏洞分析与复现

Linux内核SCTP协议漏洞分析与复现2019-05-30    ADLab

漏洞背景

Linux 内核 SCTP 协议实现中存在一个安全漏洞 CVE-2019-0708(CNVD-2019-06182、CNNVD-201902-823) ,可以导致拒绝服务。该漏洞存在于 net/sctp/socket.c 中的 sctp_sendmsg() 函数 ,该函数在处理 SENDALL 标志操作过程时存在 use-after-free() 漏洞。

SCTP协议简介

流控制传输协议 (Stream Control Transmission Protocol,SCTP) 是一种可靠的传输协议,它在两个端点之间提供稳定、有序的数据传递服务 (非常类似于 TCP) ,并且可以保护数据消息边界 (例如 UDP) 。与 TCP UDP 不同, STCP 是通过多宿主 (Multi-homing) 和多流 (Multi-streaming) 功能提供这些收益的,这两种功能均可提高可用性。

多宿主 (Multi-homing) 为应用程序提供了比 TCP 更高的可用性。多宿主主机就是一台具有多个网络接口的主机,因此可以通过多个 IP 地址来访问这台主机。在 TCP 中,连接 (connection) 是指两个端点之间的一个通道(在这种情况下,就是两台主机的网络接口之间的一个套接字)。 STCP 引入了“联合 (association) ”的概念,它也是存在于两台主机之间,但可以使用每台主机上的多个接口进行协作。



漏洞原理

漏洞补丁代码如下,补丁代码将 list_for_each_entry 换成了 list_for_each_entry_safe。



宏定义 list_for_each_entry 功能是遍历 ep->asocs 链表中的 asoc 节点。宏定义 ep->list_for_each_entry list_for_each_entry_safe 如下所示:



宏定义 list_for_each_entry_safe 中添加了一个n,该n用来存放 pos 指向的节点的下一个节点位置。使用该宏可以对链表进行删除操作。

下面对 sctp_sendmsg 是基于SCTP协议的 sendmsg 类型函数,用于发送SCTP数据包。关键实现如下:



2038 ,从 msg 中解析出 sinfo ,行 2043 ,获取到 sflags。



2055 判断 sflags 是否为 SCTP_SENDALL 。如果存在,进入 list_for_each_entry 循环中,依次遍历 ep->asocs 链表。这里的 asocs 就是存放多个 association 连接的链表。 SCTP_SENDALL 标志代表向 asocs 链表中的所有 association 连接发送数据包。所以 asocs 链表中至少要存在一个 association 节点。进入 sctp_sendmsg_check_sflags 函数后,该函数实现如下:



首先,检查 asoc 是否处于 CLOSED 状态,检查 asoc 是否处于监听状态,检查 asoc 是否 shutdown。



接下来,检查 sflags 是否为 SCTP_ABORT ,根据 rfc 文档可知 ABORT 的用法以及 ABORT 的用法以及 ABORT 指令的数据包格式。 SCTP_ABORT 标志代表中止一个 association 连接,这个也是导致漏洞的关键。



1863,sctp_make_abort_user 构造 ABORT 指令的 chunk ;行 1868 ,调用 sctp_primitive_ABORT 发送中止一个 association chunk。



通过调试可知调用 sctp_sf_do_9_1_prm_abort 函数进行ABORT操作,该函数将会进行如下操作:



添加一条删除 asoc commands ,然后返回 SCTP_DISPOSITION_ABORT 。正常返回,继续分析,返回到 sctp_do_sm 函数中。



1188 正常返回后,行 1191 调用 sctp_side_effects 函数根据状态机对应的状态进行操作。



漏洞复现

sflags 设置成 SENDALL | ABORT ,保证进入 list_for_each_entry 循环和 sctp_sendmsg_check_sflags() 函数即可。在 4.20 内核下验证如下。由于该漏洞是 NULL-PTR deref ,即是零地址解引用,无法进一步利用。



修复建议

该漏洞影响 Linux Kernel 4.19.x 4.20.x ,建议更新到 version 4.20.8 4.19.21。

补丁链接如下:

https://git.kernel.org/linus/ba59fb0273076637f0add4311faa990a5eec27c0

·

end

·

https://mmbiz.qpic.cn/mmbiz_gif/fO5Mfy7Ke978LRdI7ec72DzTIqYUhKhtficxBU3ib5FwrV3ExXgQOjdIkE5vowwt6oWJW880fxzyVEZ6RwP9J4gg/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1

数据运营·情报赋能