新聞中心
Linux內(nèi)核漏洞可能導(dǎo)致特權(quán)升級
作者 / 無憂主機 時間 2017-11-23 19:43:09
Andrey Konovalov最近披露了本地特權(quán)升級的漏洞,他在Linux網(wǎng)絡(luò)子系統(tǒng)內(nèi)部發(fā)現(xiàn)了漏洞,同時使用工具syzcaller“fuzzing”。在oss – sec的郵件線程中,Konovalov寫道:“當(dāng)構(gòu)建一個帶有MSG_MORE __ip_append_data()的UFO包時,調(diào)用ip_ufo_append_data()來追加。然而,在兩個send()調(diào)用之間,append路徑可以從UFO切換到非UFO,這會導(dǎo)致內(nèi)存損壞。
NIC分流和UFOs
網(wǎng)絡(luò)接口卡(NIC)卸載允許協(xié)議棧傳輸大于以太網(wǎng)最大傳輸單元(MTU)的數(shù)據(jù)包,默認(rèn)情況下是1500字節(jié)。當(dāng)啟用NIC offload時,內(nèi)核將把多個數(shù)據(jù)包組裝成一個大數(shù)據(jù)包,并將其傳遞給硬件,硬件處理IP碎片并將其分割成mtu大小的包。這種卸載經(jīng)常使用高速網(wǎng)絡(luò)接口來提高吞吐量,因為UFO可以發(fā)送大型的UDP數(shù)據(jù)包。 Linux內(nèi)核可以利用各種NICs的分段卸載功能。引發(fā)POC
下面是一個簡單的概念證明 要在內(nèi)核中構(gòu)建UFO數(shù)據(jù)包,我們可以采取以下兩個步驟之一:使用UDP_CORK套接字選項,該選項告訴內(nèi)核將此套接字上的所有數(shù)據(jù)累加到單個圖中,以在禁用該選項時傳輸; 調(diào)用send / sendto / sendmsg時,使用MSG_MORE標(biāo)志,告訴內(nèi)核將此套接字上的所有數(shù)據(jù)累加到單個圖中,以便在未指定此標(biāo)志的調(diào)用時發(fā)送。此方法觸發(fā)此漏洞。在內(nèi)核中,udp_sendmsg函數(shù)負(fù)責(zé)構(gòu)造UDP數(shù)據(jù)包并將其發(fā)送到下一層。以下代碼顯示了在調(diào)用send / sendto / sendmsg時,由用戶程序使用UDP_CORK套接字選項或MSG_MORE標(biāo)志啟用的UDP軟木塞功能的剝離實現(xiàn)。啟用UDP連接時,會調(diào)用ip_append_data函數(shù)將多個數(shù)據(jù)包累積為單個大數(shù)據(jù)包。 函數(shù)ip_append_data是__ip_append_data的封裝,它負(fù)責(zé)管理套接字緩沖區(qū),方法是分配一個新的套接字緩沖區(qū)來存儲傳遞給它的數(shù)據(jù),或者在套接字被塞住時將數(shù)據(jù)附加到現(xiàn)有的數(shù)據(jù)。這個功能執(zhí)行的一個重要任務(wù)是處理UFO。套接字緩沖區(qū)在套接字的發(fā)送隊列中進行管理。在塞住套接字的情況下,隊列中可以添加附加數(shù)據(jù)的條目。數(shù)據(jù)位于發(fā)送隊列中,直到udp_sendmsg確定是時候調(diào)用udp_push_pending_frames,udp_push_pending_frames完成套接字緩沖并調(diào)用udp_send_skb。 Linux內(nèi)核將數(shù)據(jù)包存儲在結(jié)構(gòu)sk_buff(套接字緩沖區(qū))中,所有網(wǎng)絡(luò)層都使用它來存儲它們的標(biāo)題,有關(guān)用戶數(shù)據(jù)(有效負(fù)載)的信息以及其他內(nèi)部信息。 內(nèi)核中的套接字緩沖區(qū)。 在上圖中,sk_buff的頭部,數(shù)據(jù),尾部和尾部成員指向存儲協(xié)議頭部和用戶有效載荷的內(nèi)存區(qū)域的邊界。頭部和終點指向分配給緩沖區(qū)的空間的開始和結(jié)束。數(shù)據(jù)和尾部指向整個空間內(nèi)的用戶數(shù)據(jù)的開始和結(jié)束。緊接在結(jié)束邊界后面,結(jié)構(gòu)skb_shared_info包含IP分片的重要信息。
內(nèi)存腐敗
如前面的POC中所示,當(dāng)?shù)谝淮握{(diào)用“send”時,MSG_MORE標(biāo)志被調(diào)用,__ip_append_data通過調(diào)用ip_ufo_append_data創(chuàng)建一個新的套接字緩沖區(qū),如下面的代碼所示: 當(dāng)這個調(diào)用完成,并且創(chuàng)建了新的套接字緩沖區(qū)時,用戶數(shù)據(jù)被復(fù)制到片段中,共享信息結(jié)構(gòu)被更新為片段信息,如下圖所示。新創(chuàng)建的sk_buff被放入隊列中。 在下一步中,PoC通過設(shè)置選項SO_NO_CHECK來更新套接字以不計算UDP上的校驗和; 這將覆蓋套接字結(jié)構(gòu)的sk-> sk_no_check_tx成員。在__ip_append_data里面,這個變量被檢查為調(diào)用ip_ufo_append_data之前的一個條件。 在POC第二次調(diào)用“發(fā)送”的過程中,在__ip_append_data內(nèi)部采用非UFO路徑,該路徑進入片段長度計算循環(huán)。在循環(huán)的第一次迭代期間,副本的值變?yōu)樨?fù)值,這會觸發(fā)新的套接字緩沖區(qū)分配。另外碎片計算超過MTU并觸發(fā)碎片。這會導(dǎo)致通過使用skb_copy_and_csum_bits函數(shù)將用戶有效載荷從第一個發(fā)送調(diào)用創(chuàng)建的sk_buff復(fù)制到新分配的sk_buff。這將從源緩沖區(qū)中復(fù)制指定數(shù)量的字節(jié)到目標(biāo)sk_buff并計算校驗和。調(diào)用長度大于新創(chuàng)建的sk_buff邊界結(jié)束限制的skb_copy_and_csum_bits會覆蓋套接字緩沖區(qū)之外的數(shù)據(jù),并破壞之前為sk_buff的skb_shared_info結(jié)構(gòu)。 接下來是損壞的skb_shared_info結(jié)構(gòu)。地址0xffff88003a4ca900處的內(nèi)存是新創(chuàng)建的sk_buff,結(jié)尾= 1728,其中分段被觸發(fā)。 當(dāng)大多數(shù)默認(rèn)的Ubuntu桌面系統(tǒng)允許非特權(quán)用戶命名空間時,這個bug可以被非特權(quán)用戶利用。用戶應(yīng)該可以做兩件事情: 1:建立一個啟用了UFO的接口(可能來自用戶名字空間),或者使用那個接口(如果它已經(jīng)存在)。(“l(fā)o”界面默認(rèn)啟用UFO。) 2:禁用NETIF_F_UFO接口功能或設(shè)置SO_NO_CHECK套接字選項。 代碼執(zhí)行可以通過在一個大緩沖區(qū)末尾簡單地創(chuàng)建一個偽造的skb_shared_info結(jié)構(gòu)并將回調(diào)成員設(shè)置為shellcode來轉(zhuǎn)移到用戶模式的shellcode。第二個“send”會觸發(fā)套接字緩沖區(qū)的超出邊界條件,用用戶模式shellcode地址覆蓋skb_shared_info-> destructor_arg,在從內(nèi)核內(nèi)存釋放sk_buff之前調(diào)用該地址。 當(dāng)暴露給非特權(quán)用戶時,Linux內(nèi)核提供了一個大的攻擊面。所有的用戶應(yīng)該保持他們的系統(tǒng)補丁與最新的更新。本文地址:http://www.gle-technology.com/safety/25702.html