【bsauce讀論文】2021-USENIX-EXPRACE-采用中斷機制來利用多變量競爭漏洞

本文提出的技術(shù)最開始在2020 BlackHat上展示,名字叫Exploiting Kernel Races Through Taming Thread Interleaving,今年又在2021 USENIX會議上發(fā)表出來ExpRace: Exploiting Kernel Races through Raising Interrupts,實驗材料尚未公布。

目標(biāo):對于多變量競爭漏洞,其觸發(fā)時指令的執(zhí)行順序很特殊,沒有人工干預(yù)的話很難觸發(fā)。

解決:提出ExpRace,采用中斷機制(rescheduling IPI,TLB shootdown IPI,membarrier IPI,hardware interrupts)來增大競爭窗口。

實驗:對10個真實CVE進行測試,全部在10~118s內(nèi)成功利用;如果不利用ExpRace的話24小時都不能利用成功。

貢獻:分析內(nèi)核數(shù)據(jù)競爭漏洞的可利用性;提出采用多種中斷機制來利用多變量競爭漏洞;對10個真實的CVE進行測試,全部利用成功。


1.內(nèi)核競爭漏洞的可利用性

Figure 1-multi-variable race.png

內(nèi)核競爭漏洞可分為兩類,一是單變量競爭,二是多變量競爭,多變量競爭又分為包含式和非包含式。

1.1 單變量競爭

描述:見Figure 1-a,3條競爭指令A(yù)、B、C訪問同一變量,若B在AC之間修改了變量M,則C會獲得和A不同的M值,如果多線程競爭使得指令執(zhí)行順序為A->B->C,就會觸發(fā)競爭漏洞。

利用方法:蠻力攻擊。用戶層不斷調(diào)用Syscallx和Syscally。利用成功率P_{single}=\frac{T_y}{T_{Syscall_x}} (通常情況下{T_{Syscall_x}} \ge T_y),盡管Psingle看上去很低,但蠻力攻擊還是很有效。

1.2 多變量競爭

描述:見Figure 1-b,A、B訪問同一變量M1,C、D訪問同一變量M2,如果C在A、D之間訪問M2,則D點獲得不同的M2值,導(dǎo)致原子違例。原子違例的前提條件是嚴(yán)格按A->B->C->D的順序執(zhí)行。

原因:內(nèi)核訪問變量有一種常見的模式,這很容易產(chǎn)生多變量競爭漏洞。(i) 先搜索數(shù)據(jù)位置,例如枚舉數(shù)據(jù)結(jié)構(gòu)(list 或 tree);(ii) 根據(jù)虛地址讀取數(shù)據(jù)或更新數(shù)據(jù)。

利用挑戰(zhàn):通過蠻力攻擊,使得Tx位于Ty中(假設(shè)T_{Syscall_x} \leq T_{Syscall_y})??赏ㄟ^線段圖來進行理解,如果T_x \geq T_y(非包含式),則競爭幾乎不可能成功。

1.png

實例-CVE-2017-15265:見Figure 2。

  • 分析:Tasky采用create命令創(chuàng)建緩沖區(qū)port,并插入到p->list,對應(yīng)A點;然后將用戶輸入拷貝到port->name,對應(yīng)D點。Taskx采用delete命令釋放port,先從p->list找到相應(yīng)的port,對應(yīng)B點;再釋放,對應(yīng)C點。
  • 競爭變量:p->list 和 port
  • 漏洞:如果按照A->B->C->D,則會導(dǎo)致UAF。
  • 利用:需要觸發(fā)UAF 3次。首先采用msgsnd()噴射file指針;然后觸發(fā)漏洞來部分覆寫snd_seq_queue->tickq,以泄露噴射的file指針;接著,觸發(fā)漏洞來覆寫iovec結(jié)構(gòu),構(gòu)造任意讀,讀取 struct file中的struct *f_cred;最后,觸發(fā)漏洞來覆寫iovec,構(gòu)造任意寫,修改cred提權(quán)。
  • 問題:Tx比Ty大太多(12倍),幾乎不可能競爭成功。
Figure 2-CVE-2017-15265.png

2.概率模型與中斷分類

本文目標(biāo):針對非包含的多變量競爭(non-inclusive multivariable race,也即T_x \geq T_y的情況),采用中斷來增大AD競爭窗口(也即Ty的值)。

Figure 3-enlarge approach.png

競爭成功率(概率模型):TE—中斷處理耗時;Ty'=Ty+TE,稱Ty'為競爭窗口(race window)。

  • (1)若Tx肯定位于Ty'中,只需看中斷是否恰好出現(xiàn)在Ty中間;
  • (2)若Tx<Ty'<Tsyscallx,需保證中斷出現(xiàn)在Ty中間,且Tx位于Ty'中間;
  • (3)若Tx>Ty',則很難競爭成功。
2.png

中斷分類:主要分為兩類。
(1)硬件中斷IRQ(Hardware interrupt request):通過IO-APIC,從外部硬件設(shè)備向OS發(fā)送信號;
(2)處理器間中斷IPI(Inter Processor Interrupt):從某個CPU核向其他核發(fā)送信號,例如rescheduling IPI, wake-up IPI, stop IPI, function call IPI。

Table 2-list exploit methods.png

3.中斷利用方法

3.1 Reschedule IPI

CONFIG_PREEMPT:設(shè)置該選項,表示如果需要調(diào)度,則會調(diào)用schedule,內(nèi)核態(tài)將被搶占。

介紹:Reschedule IPI由內(nèi)核函數(shù)smp_send_reschedule()來發(fā)送,包含參數(shù)cpu,來指定哪個核將接收到IPI。

用戶層調(diào)用:觸發(fā)smp_send_reschedule()的用戶態(tài)函數(shù)有兩種。第1種系統(tǒng)調(diào)用只需要1個進程,且相同時間內(nèi)能夠發(fā)送更多的 IPI,所以采用sched_setaffinity()調(diào)用。

  • 一是用戶態(tài)調(diào)用sched_setaffinity(),參數(shù)是pid和mask,最終設(shè)置在smp_send_reschedule()的cpu上運行指定pid進程;
  • 二是通過喚醒等待線程,首先綁定特定核與task A,通過read()將線程狀態(tài)改為等待狀態(tài),然后從task B調(diào)用write()喚醒等待的線程,內(nèi)核會將task A的進程狀態(tài)從waiting改為running,并向task A所在的核發(fā)送 reschedule IPI。

方法:創(chuàng)建3個task,Taskx / Tasky / Taskint,分別在核心C0 / C1 / C2上運行(Taskx和Taskint可以是Tasky的子線程或子進程,Taskx和Tasky負責(zé)觸發(fā)競爭),Taskint負責(zé)調(diào)用sched_setaffinity(C1)—B點,內(nèi)核會將Taskint從C2遷移到C1運行隊列,并向C1發(fā)送reschedule IPI—C點。如果C1在競爭窗口Ty中接收到 reschedule IPI,就會轉(zhuǎn)而去處理IPI—D點,然后C1切換到Task int的上下文—E點,最后再調(diào)度回來—F點。這樣就增大了Ty競爭窗口。

Figure 4-Reschedule IPI exploit.png

3.2 Non-Reschedule IPI

分類:根據(jù)發(fā)送命令的不同,將非調(diào)度的IPI分為兩類,一是TLB管理,二是內(nèi)存柵欄。

3.2.1 TLB Shootdown IPI

Translation Lookaside Buffer (TLB):地址轉(zhuǎn)換旁路緩沖存儲器。虛地址轉(zhuǎn)換為物理地址,每個核都有自己的TLB,需要進行核間同步。OS實現(xiàn)TLB shootdown機制來確保TLB正確同步。

原理:如果某核更新了TLB入口,則通過向具有相同入口的其他核發(fā)送TLB shootdown IPI,告知其刷新TLB。mm_struct->cpu_bitmap負責(zé)存儲含相同頁表入口的核。

用戶層調(diào)用mprotect()munmap()修改內(nèi)存權(quán)限,則內(nèi)核首先刷新當(dāng)前核的TLB,再向其他核發(fā)送IPI。

方法

  • (1)Taskx和Tasky必須位于不同進程,如果二者位于同一進程(不同線程),二者會指向同一mm_struct,且cpu_bitmap會將C0和C1都設(shè)置,導(dǎo)致IPI會發(fā)給C0和C1。Taskint則必須和Tasky位于同一進程,這樣才能有相同的頁表入口(便于發(fā)送TLB Shootdown IPI)。
  • (2)Tasky或 Taskint調(diào)用mmap()分配內(nèi)存M。
  • (3)Taskx和Tasky競爭時,Taskint調(diào)用mprotect(M, ...)修改M的權(quán)限—B點,內(nèi)核先刷新C2的TLB,并向C1發(fā)送function call IPI(因為M對應(yīng)C1的mm_struct->cpu_bitmap已經(jīng)設(shè)置了),如果C1在競爭窗口間收到IPI,就會停止Tasky并調(diào)用native_flush_tlb_one_user()來處理IPI。這樣就增大了Ty競爭窗口。
Figure 5-TLB shootdown exploit.png
3.2.2 Memory Barrier IPI

membarrier:多處理器系統(tǒng)中,控制內(nèi)存訪問順序。membarrier需要激活特定線程上的內(nèi)存柵欄,所以要用到IPI機制來通知運行特定線程的核。

用戶層調(diào)用membarrier(),可以從用戶層直接發(fā)送 memory barrier IPI。

方法

  • (1)Taskx和Tasky位于不同進程,才能擁有不同的mm,Taskx由Tasky fork產(chǎn)生,Taskint由Tasky調(diào)用 pthread_create() 產(chǎn)生;
  • (2)Tasky或Taskint調(diào)用membarrier(REGISTER)來注冊內(nèi)存柵欄;
  • (3)Taskx 和Tasky 觸發(fā)競爭,Taskint調(diào)用membarrier(EXPEDITED),內(nèi)核就會向C1發(fā)送 membarrier IPI(因為C1上的Tasky和Taskint引用了相同的mm_struct);
  • (4)Tasky收到IPI后,就會調(diào)用ipi_mb()來處理IPI,這樣就增大了Ty競爭窗口。
Figure 6-membarrier IPI.png

3.3 Hardware Interrupts

硬件中斷IRQ:通過IO-APIC從外設(shè)發(fā)送到處理器的電子信號。

原理

  • 發(fā)出IRQ后,中斷控制器將中斷發(fā)給指定的CPU核(Linux中通過bit掩碼確定目標(biāo)核,Windows通過輪詢確定目標(biāo)核),相應(yīng)的CPU核執(zhí)行中斷服務(wù)程序(ISR)。

  • 可通過讀取procfs確定bit掩碼,確定處理指定外設(shè)請求的目標(biāo)核,例如,默認(rèn)內(nèi)核配置中,enp2s0設(shè)備對應(yīng)IRQ122,由CPU core 11處理。

發(fā)送方式:不能直接從用戶層發(fā)送,先從用戶向設(shè)備發(fā)送請求,設(shè)備再向內(nèi)核發(fā)送IRQ。兩種方式——一是發(fā)送TCP請求到以太設(shè)備,設(shè)備再向內(nèi)核發(fā)送IRQ來處理包;二是采用文件讀寫發(fā)送disk請求,disk控制器設(shè)備(如AHCI設(shè)備)向內(nèi)核發(fā)送IRQ,表示disk請求已完成。

方法

  • (1)Taskx 和Taskint 可以跟Tasky 是不同線程或進程,硬件中斷與進程線程無關(guān),先讀取/proc/irq/#/smp_affinity獲得CPU核號(處理以太設(shè)備的IRQ的核號,暫設(shè)為C1);
  • (2)Taskx和Tasky 觸發(fā)競爭時,Taskint向自身發(fā)送TCP請求(外部IP—局部機器)—對應(yīng)B點;
  • (3)以太設(shè)備向C1發(fā)送IRQ—C點;
  • (4)若C1在Ty中間收到IRQ,就會調(diào)用相應(yīng)的ISR來處理—D點,這樣就增大了Ty競爭窗口。
Figure 7-HW interrupt exploit.png

4.其他操作系統(tǒng)上的中斷利用

說明:membarrier是Linux獨有,所以不用研究。這些中斷在Windows中都可用,Mac OS中Reschedule IRQ不可用,HW中斷沒測試。

Windows

  • Reschedule IPI:Windows中,優(yōu)先級比當(dāng)前線程更高的線程才能被調(diào)度。改進,用戶層使用SetThreadAffinityMask()調(diào)用替代sched_setaffinity(),并額外調(diào)用SetThreadPriority()來設(shè)置更高的優(yōu)先級。
  • TLB Shootdown IPI:需用到VirtualAlloc()、VirtualProtect()、VirtualFree()來分配、修改、釋放內(nèi)存頁。
  • HW Interrupt:不同點是,Windows沒有特定CPU來處理某個外設(shè)的IRQ,而是采用輪詢來確定CPU,所以理論上,k個CPU的話,增大Ty的幾率為Linux的1/k

Mac OS X

  • Reschedule IPI:不可用。
  • TLB Shootdown IPI:采用相同的函數(shù)mmap()、mprotect()、munmap()能夠增大Ty。
  • HW Interrupt:Mac OS沒有提供足夠的信息來研究其硬件斷點。
Table 3-other OSes.png

5.實驗評估

實驗設(shè)計:選取10個非包含式多變量競爭漏洞進行測試,選取的漏洞見Table 1,其中CVE-2019-1999 和 CVE-2019-2025 含有公開exp。每個漏洞最多嘗試?yán)?4h。

Table 1-CVE.png

實驗結(jié)果:結(jié)果見Table 4。不用ExpRace的話,10個CVE在24h內(nèi)全部利用失敗。

  • Reschedule成功3個,都在66s內(nèi)。
  • membarrier IPI成功3個。CVE-2019-6974, CVE-2019-1999, 11eb85ec, 1a6084f8, e20a2e9c是由于Ty'太小。
  • TLB shootdown成功7個。
  • hardware interrupts成功10個。

說明:membarrier 和 TLB shootdown 不能用于 CVE-2019-6974 和 da1b9564,因為這兩個漏洞要求兩個導(dǎo)致競爭的syscall位于同一進程。

Table 4-Exploit result.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,974評論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者,不喜歡去冒險,但是人生放棄了冒險,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 8,254評論 0 4

友情鏈接更多精彩內(nèi)容