作者:啟明星辰ADLab
公眾號:https://mp.weixin.qq.com/s/enoWQh1yo0Qjzck3ZzwidA

一、 漏洞背景

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)”的概念,它也是存在于兩臺主機之間,但可以使用每臺主機上的多個接口進行協作。

三、 漏洞原理

漏洞補丁代碼如下,補丁代碼將list_for_each_entry換成了list_for_each_entry_safe

宏定義list_for_each_entry功能是遍歷ep->asocs鏈表中的asoc節點。宏定義list_for_each_entrylist_for_each_entry_safe如下所示:

宏定義list_for_each_entry_safe中添加了一個 n,該 n 用來存放 pos 指向的節點的下一個節點位置。使用該宏可以對鏈表進行刪除操作。

下面對sctp_sendmsg函數調用鏈進行分析。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 指令的數據包格式。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函數根據狀態機對應的狀態進行操作。

行 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,即是零地址解引用,無法進一步利用。

五、 漏洞修復建議

該漏洞影響 Linux Kernel 4.19.x 和 4.20.x,建議更新到 version 4.20.8 或4.19.21。

補丁鏈接如下: https://git.kernel.org/linus/ba59fb0273076637f0add4311faa990a5eec27c0


啟明星辰積極防御實驗室(ADLab)

ADLab成立于1999年,是中國安全行業最早成立的攻防技術研究實驗室之一,微軟MAPP計劃核心成員,“黑雀攻擊”概念首推者。截止目前,ADLab已通過CVE累計發布安全漏洞近1000個,通過 CNVD/CNNVD累計發布安全漏洞近500個,持續保持國際網絡安全領域一流水準。實驗室研究方向涵蓋操作系統與應用系統安全研究、移動智能終端安全研究、物聯網智能設備安全研究、Web安全研究、工控系統安全研究、云安全研究。研究成果應用于產品核心技術研究、國家重點科技項目攻關、專業安全服務等。

img


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/938/