日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 程序喵大人


CVE-2021-22555:一個影響2006年(Linux kernel v2.6.19-rc1 發(fā)布)至今(Linux kernel v5.12-rc8)的所有Linux內(nèi)核版本的漏洞,可導(dǎo)致本地提權(quán)與容器逃逸;該漏洞是個內(nèi)核級漏洞,跟Linux的發(fā)行版本沒有關(guān)系,也就是說只要Linux 內(nèi)核版本在v2.6.19-rc1 ~v5.12-rc8 之間的內(nèi)核,都存在被黑客利用該漏洞攻擊的可能。


該漏洞是由Andy Nguyen (theflow@)發(fā)現(xiàn),于2021年07月16日發(fā)布。換句話說,該漏洞已經(jīng)存在了15年之久,都沒有被人發(fā)現(xiàn)。該漏洞將允許本地用戶通過用戶名空間獲取權(quán)限提升,和容器逃逸。



1.漏洞概述



漏洞編號 CVE-2021-22555
內(nèi)核組件 kernel-netfilter
漏洞類型 Linux kernel堆溢出、特權(quán)提升
影響版本 Linux Kernel : v2.6.19-rc1 ~ v5.12-rc8

簡述: Linux 內(nèi)核模塊Netfilter中存在一處權(quán)限提升漏洞,在 64位系統(tǒng) 上為 32位進(jìn)程 處理 setsockopt IPT_SO_SET_REPLACE(或 IP6T_SO_SET_REPLACE)時,如果內(nèi)核選項CONFIG_USER_NS 、CONFIG_NET_NS被開啟,則攻擊者可以通過該漏洞實現(xiàn)權(quán)限提升,以及從docker、k8s容器中實施容器逃逸。



2.漏洞環(huán)境和樣例




2.1.環(huán)境準(zhǔn)備


Linux發(fā)行版:Ubuntu 20.04.2 LTS

Linux kernel 版本:5.8.0-48-generic


如圖:




2.2.利用樣例





3 漏洞原理



在Linux內(nèi)核代碼net/netfilter/x_tables.c中的 xt_compat_target_from_user 函數(shù)內(nèi)的第1129行,在使用memset()時并未對傳進(jìn)來的參數(shù)進(jìn)行校驗,會導(dǎo)致在寫0時,越過堆的大小,導(dǎo)致“堆溢出”,從而破壞堆與堆之間的邊界。


而寫超的0 的內(nèi)核內(nèi)存,剛好又在應(yīng)用層程序(惡意程序)通過堆噴技術(shù)拿到感知控制。通過搜索,可以找到被寫超的內(nèi)核內(nèi)存;惡意程序在應(yīng)用層建立與這段內(nèi)核內(nèi)存的聯(lián)系,把要執(zhí)行代碼commit_creds(prepare_kernel_cred(NULL))封裝到回調(diào)函數(shù)內(nèi);利用內(nèi)核機(jī)制在內(nèi)核內(nèi)存中建立與回調(diào)機(jī)制使用關(guān)系,再把剛才封裝的函數(shù)地址更新到內(nèi)核內(nèi)存中。當(dāng)主動釋放這段內(nèi)核內(nèi)存,觸發(fā)回調(diào)函數(shù),從而調(diào)用到commit_creds()函數(shù)把權(quán)限升級到root權(quán)限。



4 前導(dǎo)技術(shù)知識點



4.1 UAF (Use-After-Free)


是一個與程序運行期間不正確使用動態(tài)內(nèi)存相關(guān)的漏洞利用方式。


程序在釋放內(nèi)存位置后,系統(tǒng)不會馬上回收內(nèi)存。指針指向的那段內(nèi)存依然存在,并且內(nèi)容沒有被清除,攻擊者可以利用該錯誤來入侵該程序。(本次漏洞重點使用。通過UAF,可以達(dá)到同一塊內(nèi)存在不同的操作對象之間交換控制管理權(quán))



4.2 SMAP & SMEP


SMAP(Supervisor Mode Access Prevention):管理模式訪問保護(hù)–禁止內(nèi)核CPU訪問用戶空間的數(shù)據(jù).

SMEP(Supervisor Mode Execution Prevention):管理模式執(zhí)行保護(hù)–禁止內(nèi)核CPU執(zhí)行用戶空間的代碼(并不會因為你權(quán)限高就能訪問/執(zhí)行低權(quán)限的資源,你的就是你的,我的就是我的).

SMEP和SMAP導(dǎo)致我們不能像從前那樣,利用惡意進(jìn)程提權(quán)到內(nèi)核權(quán)限后,扭頭去執(zhí)行布置在用戶態(tài)的惡意shellcode,用戶態(tài)shellcode注入也不好使了(Linux 內(nèi)核漏洞防御機(jī)制).


4.3 KASLR


KASLR(kernel address space layout randomization)也就是內(nèi)核地址空間布局隨機(jī)化。KASLR技術(shù)允許kernel image加載到VMALLOC區(qū)域的任何位置。當(dāng)KASLR關(guān)閉的時候,kernel image都會映射到一個固定的鏈接地址。

對于黑客來說是透明的,因此安全性得不到保證。KASLR技術(shù)可以讓kernel image映射的地址相對于鏈接地址有個偏移。如果bootloader支持每次開機(jī)隨機(jī)生成偏移數(shù)值,那么可以做到每次開機(jī)kernel image映射的虛擬地址都不一樣。

因此,對于開啟KASLR的kernel來說,不同的產(chǎn)品的kernel image映射的地址幾乎都不一樣。因此在安全性上有一定的提升(Linux 內(nèi)核漏洞防御機(jī)制)。


4.4 rop 鏈攻擊


rop(Return Oriented Programming)。X86架構(gòu)下,函數(shù)調(diào)用規(guī)則是,當(dāng)剛跳轉(zhuǎn)到其他函數(shù)去執(zhí)行時,從被調(diào)用者的視角看:棧頂是返回地址,緊接著是自己的參數(shù)。

被調(diào)用者會對??臻g進(jìn)行一系列操作,保存寄存器和存儲臨時變量,但在即將退出時會清理自己消耗的??臻g,以使其回到自己被調(diào)用前的??臻g,保持棧平衡;

最后,被調(diào)用者以ret指令結(jié)尾,ret指令將棧頂?shù)刂穫鬟f到 RIP寄存器 ,隨后代碼也就跳轉(zhuǎn)到之前棧頂存放的返回地址處;

rop鏈即是基于以上這個簡單的原理,在代碼空間中尋找以ret結(jié)尾的代碼片段或函數(shù)(代碼片段稱為Rop gadgets),組合可以實現(xiàn)拓展可寫??臻g、寫入內(nèi)存、shell等功能,依靠ret將 代碼執(zhí)行權(quán) 緊握在自己的手里。



4.5 一段代碼的運行


在計算機(jī)體系中,所有的行為邏輯,都是要以“程序”為媒介得以執(zhí)行。當(dāng)然,這也包含了所有“惡意行為”在內(nèi)的病毒、木馬等待。

而“程序”的本質(zhì)是通過代碼來對“現(xiàn)實行為”在計算機(jī)內(nèi)的行為仿真(程序沒有“惡意”和“非惡意”之分,惡意的是寫這份代碼的人心);既然是代碼,也是要遵照計算機(jī)體系的約定。

4.5.1 代碼運行的條件


在Linux系統(tǒng)中所有的行為都是被“權(quán)限”所規(guī)范起來。


換句話說,程序想要被運行起來就需要“獲得”相應(yīng)的權(quán)限。而在Linux系統(tǒng)權(quán)限是被嚴(yán)格的劃分。我們可以從2個維度(應(yīng)用層/內(nèi)核層)來對權(quán)限進(jìn)行了解。




4.5.2 應(yīng)用層(Ring 3)


也就是平時我們操作Linux界面。在應(yīng)用層中是以用戶為單位進(jìn)行管理,又劃分成2類:特權(quán)用戶(也就是root),普通用戶。

Linux限定了普通用戶的行為,也包含普通用戶的程序;在普通用戶模式下,有很多系統(tǒng)級的接口、功能,都是不能使用的;基本也就是只能使用主機(jī)的“計算能力”,不能使用到“管理能力”。


4.5.4 內(nèi)核層(Ring 0)


操作系統(tǒng)是對物理硬件的抽象,而內(nèi)核層是操作系統(tǒng)的核心。

在內(nèi)核層中,沒有像應(yīng)用層那樣,做權(quán)限區(qū)分,任何執(zhí)行代碼都是一樣的權(quán)限。

而內(nèi)核層相對于用戶層,擁有的特權(quán)是最高。


4.5.5 漏洞利用邏輯


根據(jù)前面提到的,想要運行代碼,需要2個條件:

1、代碼在內(nèi)存中

2、裝載代碼的內(nèi)存擁有執(zhí)行權(quán)限


一個普通用戶的程序,正常情況下只能通過高權(quán)限的授權(quán),來提升自己的權(quán)限,除此別無他法。

而CVE-2021-22555漏洞可以通過“內(nèi)核特權(quán)”來打破這一規(guī)則。



5 漏洞利用步驟



5.1 堆噴:建立線性的內(nèi)核堆內(nèi)存


通過系統(tǒng)提供的消息隊列功能,建立大量的消息隊列,并往每個消息隊列里面?zhèn)魅胂ⅲ總€消息大?。?096)。這些消息會緩存到內(nèi)核當(dāng)中。

緩存在內(nèi)核,也就意味著有大量的內(nèi)存占用。而當(dāng)有大量的內(nèi)存申請使用,內(nèi)核的內(nèi)存管理模塊為了減小內(nèi)存碎片的問題,會把相鄰的內(nèi)存返回給內(nèi)存使用者。

也就是說,這些緩存的消息,在內(nèi)存中是連續(xù)存在,緊挨著的。


如圖:

這樣還不夠,再次往各個消息隊列發(fā)送消息,這次發(fā)送的消息大小是1024。而在消息隊列中的消息是用鏈表的方式來連接的,在內(nèi)存中的布局如圖:

這里面的選用 4096 大小作為第一條消息,是為了適配漏洞代碼 memset() 做格式化的大小。


而選用1024 大小作為每二條消息,是為了利用上漏洞后,當(dāng)內(nèi)核內(nèi)存使用,與后續(xù)的回調(diào)機(jī)制匹配。




5.2 漏洞觸發(fā) & UAF攻擊


現(xiàn)在讀出部分各個消息隊中的 4096大小的消息,其目的是為了釋放在內(nèi)核內(nèi)存中緩存的內(nèi)存。在讀出的消息的同時內(nèi)存也得到釋放。


接下應(yīng)用層利用 socket 觸發(fā)漏洞函數(shù)。觸發(fā)代碼:

setsockopt(fd, SOL_IP, IPT_SO_SET_REPLACE, &data, sizeof(data))

data 的大小通過人為的方式來構(gòu)造,其中sizeof(data) 的大小,會傳到漏洞語句。造成堆寫0溢出,踩到相鄰的內(nèi)存。

內(nèi)核層對應(yīng)的漏洞函數(shù) xt_compat_target_from_user 被觸發(fā)時,會在內(nèi)核層申請內(nèi)核內(nèi)存。根據(jù)UAF攻擊原理,xt_compat_target_from_user 函數(shù)內(nèi)申請的內(nèi)存剛好會是上面消息隊在內(nèi)核層釋放的內(nèi)存塊。

而該內(nèi)存塊相連的是其它的 4096大小的消息內(nèi)存塊。當(dāng)漏洞函數(shù)被觸發(fā),寫超的內(nèi)存,就會寫到相鄰的 4096 消息內(nèi)。

4096 消息在應(yīng)用層可以通過遍歷,來找出被踩的那塊內(nèi)核消息塊。

在溢出寫0的長度是在應(yīng)用層可以人為的控制,而這里,我們設(shè)計溢出的長度為 2 個字節(jié)。

根據(jù)消息結(jié)構(gòu)體在內(nèi)核層中的定義,溢出寫0的2個字節(jié)剛好會覆蓋消息結(jié)構(gòu)體內(nèi)的指向下一條1024消息的指針的后2位。就會導(dǎo)致被溢出踩的4096消息會指向另一個1024消息,而這條1024同時會被另一個4096的消息指向。

也就是同一個1024消息被2個4096消息指向,為后續(xù)的UAF利用提供了條件。


如圖:

5.2.1 一點題外話


該漏洞的利用開始就是從寫超2個字節(jié)的堆內(nèi)存,而該漏洞的發(fā)現(xiàn)者也因此獲取得了10000$的獎勵。而在作者后續(xù)的文章說明中,也是很幽默地把該點寫到文章的標(biāo)題上。

如圖:


5.3 繞過內(nèi)核 SMAP 機(jī)制


其實目的是為了把權(quán)限升級的相關(guān)的代碼傳到內(nèi)核層讓,讓內(nèi)核層的權(quán)限去運行權(quán)限升級的代碼,來提升用戶層用戶的權(quán)限。

繞過SMAP的基礎(chǔ),就是要知道內(nèi)核內(nèi)存的地址。知道地址的基礎(chǔ),把我們要提升權(quán)限的代碼以ROP攻擊鏈的方式寫到該內(nèi)核內(nèi)存當(dāng)中。

通過對消息隊的遍歷,找到了被雙重引用的1024消息,而目前還不知道該被雙重引用的1024消息的地址。

不知道該消息的內(nèi)核內(nèi)存地址,是沒辦法繞過SMAP機(jī)制,同時在后面作為ROP鏈的媒介內(nèi)存,在不知道內(nèi)存地址的情況下,是沒辦法使用的。


接下來就是需要知道該消息的內(nèi)核內(nèi)存地址了。

好在可以通過消息結(jié)構(gòu)(struct msg_msg)的 m_ts字段,再利用 copy_msg()函數(shù)



來讀取出被雙重指向的1024消息的相鄰消息。(設(shè)置被雙重指向的1024消息的m_ts字段大于DATALEN_MSG(4096 - sizeof(struct msg_msg)) ),再通過該相鄰消息找出被雙重指定的1024消息的內(nèi)核內(nèi)存地址,現(xiàn)在我們得到了內(nèi)核內(nèi)存地址,就可以把我們的ROP鏈的代碼寫到該內(nèi)核內(nèi)存地址上,從而達(dá)到繞過SMAP機(jī)制。





5.4 解除內(nèi)核消息隊列的限制

在內(nèi)核的消息隊列,也就只是消息結(jié)構(gòu)類型(struct msg_msg),并且還需要保證里面的元素的合法性。換句話說,我們就不能使用消息隊列的對象來做內(nèi)核內(nèi)存的修改對象,因為沒有可塑性。

需要找一種有可塑造的內(nèi)核結(jié)構(gòu)消息來指向該內(nèi)核消息隊列內(nèi)存地址。

這里使用 struct sk_buff 結(jié)構(gòu)體類型, sk_buff就沒有 struct msg_msg的內(nèi)核限制。

利用雙重指向的1024消息的其中一個引用,來釋放該1024消息。再使用struct sk_buff類型的消息來堆噴1024大小,正常情況下,通過堆噴會找到剛釋放出被雙重指定的1024消息。而這樣做的目的是為了通過另一種控制的方式(sk_buff)來指向了該內(nèi)核內(nèi)存地址。

到目前為止,我們拿到了一段內(nèi)核內(nèi)存,大小1024,并且還一個struct sk_buff類型的指針可以對它進(jìn)行操作。

(為了方便大家理解,再次解釋一下:該步驟的目的是為了把同一塊內(nèi)存的控制管理權(quán)限轉(zhuǎn)交給 struct sk_buff 結(jié)構(gòu);因為在原消息結(jié)構(gòu) struct msg_msg 類型在內(nèi)核中是不允許對結(jié)構(gòu)體做超范圍的操作)



5.5 找一個有回調(diào)機(jī)制的結(jié)構(gòu)


也就是找到一個結(jié)構(gòu)體內(nèi)有函數(shù)指針的對象。

這里選用 struct pipe_buffer 結(jié)構(gòu)對象,該結(jié)構(gòu)體中的 const struct pipe_buf_operations *ops;剛好可以用來存放回調(diào)函數(shù)。


該結(jié)構(gòu)體剛好占1024字節(jié),同時也很容易使用 pipe()函數(shù)來制成。



5.6 繞過KASLR & SMEP


調(diào)用pipe()申請 struct pipe_buffer 結(jié)構(gòu)時,ops字段的內(nèi)容會默認(rèn)填充為anon_pipe_buf_ops,而內(nèi)容又存在內(nèi)核的 .data段內(nèi):


因為在內(nèi)核中的.data和.text段之間的偏移固定,我們可以計算內(nèi)核程序代碼基地址。

這就又要用到堆噴技術(shù)了,在上面我們提到有一段內(nèi)核內(nèi)存被sk_buff指向,同時還被另一個消息隊列給指針。

利用消息隊列釋放該段內(nèi)核內(nèi)存。隨后,調(diào)用大量的pipe()函數(shù)來實現(xiàn)堆噴,找回剛才被釋放的內(nèi)核內(nèi)存。

這樣同一塊內(nèi)核內(nèi)存就被 pipe 和 sk_buff同時指向,同時具有操作權(quán)。


而const struct pipe_buf_operations *ops 中有一個名為 release的回調(diào)函數(shù),會在 pipe被閉時實調(diào)用到。


利用內(nèi)核內(nèi)存部署上我們的ROP攻擊鏈(也就是我們要提升權(quán)限的函數(shù)),把并ROP鏈的觸發(fā)寫到ops的release內(nèi)。

ROP鏈代碼:


最后關(guān)閉pipe會調(diào)用release,也是會執(zhí)行到我們的權(quán)限提升函數(shù),得到root權(quán)限。

到此已完成了漏洞的利用。再利用root權(quán)限返回一個root權(quán)限的shell。


6  修復(fù)建議



請盡快升級Linux內(nèi)核到安全版本,如下:


Linux Kernel 5.12(b29c457a6511435960115c0f548c4360d5f4801d),5.10.31, 5.4.113, 4.19.188, 4.14.231, 4.9.267, 4.4.267.


臨時修補建議:

RedHat建議,用戶可通過以下命令禁止非特權(quán)用戶執(zhí)行CLONE_NEWUSER、CLONE_NEWNET來執(zhí)行此漏洞:


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉