Linux内核SCTP和谈缝隙分析与复现

颁布功夫 2019-05-30
缝隙布景


Linux内核SCTP和谈实现中存在一个安全缝隙CVE-2019-8956(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分歧,, ,,,,,,SCTP 是通过多宿主(Multi-homing)和多流(Multi-streaming)职能提供这些收益的,, ,,,,,,这两种职能均可提高可用性。 。。。。。


多宿主(Multi-homing)为利用法式提供了比 TCP 更高的可用性。 。。。。。多宿主主机就是一台拥有多个网络接口的主机,, ,,,,,,因而能够通过多个 IP 地址来接见这台主机。 。。。。。在 TCP 中,, ,,,,,,衔接(connection) 是指两个端点之间的一个通路(在这种情况下,, ,,,,,,就是两台主机的网络接口之间的一个套接字)。 。。。。。SCTP 引入了“结合(association)”的概想,, ,,,,,,它也是存在于两台主机之间,, ,,,,,,但能够使用每台主机上的多个接口进行合作。 。。。。。

8827太阳集团(Macau)股份有限公司-Official website


缝隙道理


缝隙补丁代码如下,, ,,,,,,补丁代码将list_for_each_entry换成了list_for_each_entry_safe。 。。。。。


8827太阳集团(Macau)股份有限公司-Official website


宏界说list_for_each_entry职能是遍历ep->asocs链表中的asoc节点。 。。。。。宏界说list_for_each_entry和list_for_each_entry_safe如下所示:


8827太阳集团(Macau)股份有限公司-Official website


宏界说list_for_each_entry_safe中增长了一个n,, ,,,,,,该n用来存放pos指向的节点的下一个节点地位。 。。。。。使用该宏能够对链表进行删除操作。 。。。。。


下面对sctp_sendmsg函数挪用链进行分析。 。。。。。sctp_sendmsg是基于SCTP和谈的sendmsg类型函数,, ,,,,,,用于发送SCTP数据包。 。。。。。关键实现如下:


8827太阳集团(Macau)股份有限公司-Official website


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


8827太阳集团(Macau)股份有限公司-Official website


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


8827太阳集团(Macau)股份有限公司-Official website


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


8827太阳集团(Macau)股份有限公司-Official website


接下来,, ,,,,,,查抄sflags是否为SCTP_ABORT,, ,,,,,,凭据rfc文档可知ABORT的用法以及ABORT指令的数据包体式。 。。。。。SCTP_ABORT标志代表遏制一个association衔接,, ,,,,,,这个也是导致缝隙的关键。 。。。。。


8827太阳集团(Macau)股份有限公司-Official website


行1863,, ,,,,,,sctp_make_abort_user机关ABORT指令的chunk ;;;;;;;;行1868,, ,,,,,,挪用sctp_primitive_ABORT发送遏制一个association的chunk。 。。。。。


8827太阳集团(Macau)股份有限公司-Official website


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


8827太阳集团(Macau)股份有限公司-Official website


增长一条删除asoc的commands,, ,,,,,,而后返回SCTP_DISPOSITION_ABORT。 。。。。。正常返回,, ,,,,,,持续分析,, ,,,,,,返回到sctp_do_sm函数钟祝 。。。。。


8827太阳集团(Macau)股份有限公司-Official website


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


8827太阳集团(Macau)股份有限公司-Official website


行1246,, ,,,,,,将asoc置空,, ,,,,,,ABORT标志代表遏制一个association操作实现。 。。。。。从sctp_sendmsg_check_sflags函数返回到sctp_sendmsg函数中,, ,,,,,,宏list_for_each_entry循环中遍历获取第一个asoc节点时,, ,,,,,,进入sctp_sendmsg_check_sflags函数将第一个asoc置空,, ,,,,,,而后再进行遍历后面节点时,, ,,,,,,就产生了零地址引用导致缝隙产生。 。。。。。


缝隙复现


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

8827太阳集团(Macau)股份有限公司-Official website


建复建议


该缝隙影响Linux Kernel 4.19.x和4.20.x,, ,,,,,,建议更新到version 4.20.8 或4.19.21。 。。。。。补丁链接如下:https://git.kernel.org/linus/ba59fb0273076637f0add4311faa990a5eec27c0