日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

該漏洞是 linux 內核(5.12.4版本之前)的近場通信 (NFC) 子系統中的釋放后使用 (UAF)。但是,為了介紹,我們將在5.15版本中使用它。

Si 是一個由以下內容構成的套接字:

socket(AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP)

然后假設我們將 Si 綁定到地址 A,Si 將加載一個指向類型為:nfc_llcp_local 的對象L的指針。但是,如果 Si 的綁定失敗,則L將被釋放,而 Si到 L 仍然被定義。因此,將來取消引用 Sito L 的計算會將內核轉換為一個奇怪的狀態。

當L在綁定失敗時被釋放時,補丁會刪除指向L的指針Si。更多信息請點擊這里。https://www.openwall.com/lists/oss-security/2021/05/11/4

io_uring

輸入/輸出(I/O)可以同步或異步執行。對于前者,當我們請求一個I/O操作時,我們等待它完成后再繼續其他工作。對于后者,我們可以同時執行其他任務。假設異步I/O是同步I/O的超集。

io_uring機制實現了異步I/O,在建立一個io_uring實例之后,我們得到了兩個相關的環形緩沖區:一個用于提交,一個用于完成。每個提交都是對內核執行 I/O 操作的請求。完成是從 I/O 請求返回狀態和數據的對象。我們從提交隊列條目數組中檢索一個對象,使用操作碼和相關數據對其進行初始化,然后發出系統調用 io_uring_enter 進行提交。

我們還可以使用標志 IORING_SETUP_SQPOLL 設置 io_uring 實例,這使內部內核線程能夠輪詢提交隊列以獲取新的提交。這通過確保始終有一個內核線程等待執行請求來減少系統調用開銷。當這個內核線程從內核堆中的對象加載它的憑證時,我們將利用這一點。

Userfaultfd

一種系統調用,使用戶能夠創建文件描述符以在用戶空間中實現按需分頁。我們通過處理在 copy_from_user 和 copy_to_user 中產生的保護漏洞,廣泛使用這個系統調用來管理內核堆。

msgsnd 和 msgrcv

支持消息隊列進程間通信的系統調用。它們分別是消息發送和消息接收。


頁面漏洞

通常,當線程嘗試訪問尚未與物理幀關聯的虛擬內存地址時,內存管理單元會發出頁面漏洞。在這種情況下,內核可以通過為指定頁面創建新的頁表條目來解決故障。然而,在這個更一般的上下文中,我們也指由嘗試訪問以某些方式保護的內存引起的一般保護漏洞,即寫入只讀內存。這是因為 userfaultfd 可以配置為處理“缺頁”漏洞和保護漏洞。


假設運行環境

1.重新引入了包含漏洞的內核5.15版本。請注意,io_ring_ctx 在 5.12版本中不能立即使用,因為它是從 kmalloc-4k 發布的。但也許我們可以通過以下方式實現更多與緩存無關的原語:a) 泄漏或猜測 io_ring_ctx 對象的地址,b) 將其鍛造成一個列表,該列表隨后由 kfree 在其所有節點上執行“破壞”,或覆蓋一個指針在L中,它也被傳遞給 kfree。

2.sysctl 旋鈕 vm.unprivileged_userfaultfd=1。

3.默認情況下或通過用戶命名空間使用 CAP.NET_RAW 功能。


戰略概述

策略是泄漏和覆蓋io_ring_ctx類型的對象R。這樣,我們就可以控制R的sq_creds字段。請注意,之所以選擇R的類型,是因為R和L類型的對象類似地從kmalloc-2k發出。

$R to$ sq_creds替換提交隊列輪詢器(SQP)線程執行io_uring請求時的當前憑證。如果sq_creds指向一個結構credit對象$C$,使$C$具有uid、gid等設置為$0$,那么SQP線程將執行I/O請求,就像調用用戶是根用戶一樣。

因此,通過向io_uring實例(由受控的R管理)發出請求,我們可以作為非特權用戶讀寫磁盤上的文件。這里的演示只是讀取/etc/shadow。但要獲得根權限,只需編輯/etc/passwd以進入一個根shell。


組件

我們使用以下組件和技術:

三個 NFC 套接字:S1、S2 和 S3;

六個線程:main、X、Y、Z、T 和 H;

msgsnd + msgrcv 用于泄漏 R。

userfaultfd + setxattr 用于寫入 R 并確保 R 在利用期間和使用之后不會被另一個線程重新分配。


背景

使用三個 NFC 接口,我們可以釋放L三次。但是,每次釋放之后,我們需要覆蓋L的某些部分,我們稱之為local header,以確保隨后的釋放不會導致崩潰。具體來說,我們將 refcount 設置為 1,這樣在下一次釋放時不會將 refcount 設置為 $-1$,從而引發警告或導致進程崩潰。此外,我們確保L的第一個 list_head 字段定義明確。

使用線程 X、Y、Z,我們繼續協調:再次分配 L,將L保存在內存中,從L讀取并寫入 L。這樣,L就用R 表示,因為我們將曾經用于Si的相同對象重新分配給L為R。目的是通過我們的利用邏輯證明 L≡R。

用戶使用setxattr 技術分配一個 kvalue 對象,其大小和內容由用戶確定。它允許我們從內核對象開始寫入。然而,當我們從用戶空間完成對kvalue的寫入后,kvalue被釋放。

msgsnd + msgrcv 技術也是已知的,msgsnd 分配一個 msg_msg 對象,該對象充當標頭,后跟消息文本,其長度和內容由用戶確定。如果我們希望 msgrcv 正常工作,msg_msg 對象字段應該保持良好定義。因此,我們不能從內核對象的開頭開始寫。另一方面,msgrcv 將消息文本復制到用戶空間,然后釋放 msg_msg 對象。用戶確定消息文本的長度以及接收和釋放 msg_msg 的時間。

我們使用 userfaultfd 通過 setxattr 在內核上下文中暫停線程。我們使用該技術的兩種變體。當讀取用戶空間地址時,會出現一個頁面錯誤。另一個問題是在寫入用戶空間地址時出現頁面錯誤。它們分別對應于copy_from_user和copy_to_user。前者與setxattr關聯,后者與msgrcv關聯。

“解除阻塞線程 X”通常意味著在內核上下文中處理由線程 X 引起的頁面漏洞。一個線程不能處理它自己的頁面漏洞,而是將它委托給層次結構中更上層的線程。但是,不一定是下一個,即線程 Z 解除線程 main 和線程 Y 的阻塞,而線程 Y 解除線程 X 的阻塞。

如果我們正在處理 setxattr 頁面漏洞,那么“處理頁面漏洞”意味著我們使用 ioctl 為 userfaultfd 子系統提供一個新緩沖區。然后這允許繼續寫入 kvalue (L) ,然后釋放 kvalue (L)。同樣,對于 msgrcv 頁面漏洞,我們取消保護緩沖區并繼續讀取。建議讀者查看上面鏈接的 Vitaly Nikolenko 的解釋。這將解釋我們在下一節中說的“特定偏移處的頁面漏洞”時的意思。


方法描述

首先,我們關閉 S1,釋放 L。然后我們分配 7 msgsnd 緩沖區,刪除額外的分配。現在L是免費的,我們可以使用 setxattr 重新分配它。我們傳遞給 setxattr 的值是受內存保護的,因此在某個偏移量處讀取將導致頁面漏洞。使用 userfaultfd 我們注冊相應的范圍,以便線程 X 可以捕獲頁面漏洞。偏移量是我們自己為L類型定義的標頭的大小。我們需要覆蓋L的標頭,以便再次釋放它(當我們關閉 S2 時)不會導致早期崩潰。該標頭僅包含一個 list_head 和一個 refcount 字段,我們將其計數器值設置為 1。

其次,從線程 X 中,我們從主線程中捕獲 setxattr 中發出的頁面漏洞。現在我們在主線程中做同樣的事情,不同之處在于,我們為一個新值注冊一個新范圍,我們希望線程 Y 捕獲下一個頁面漏洞,并且頁面漏洞發生的偏移量是 struct msg_msg +8。我們仍然用我們的標頭覆蓋 L。

第三,從線程 Y,我們捕獲由 X 執行的 setxattr 中發出的前一個頁面漏洞。然而,這一次在我們關閉 S3,第三次釋放L之后,我們再次通過 msgsnd 分配 L。然后我們創建一個寫入保護緩沖區并將其注冊到 userfaultfd,我們的用戶空間接收器 msg_msg 位于寫入保護緩沖區的負偏移處。我們將 msg_msg 對象的地址傳遞給 msgrcv。當 msgrcv,特別是 store_msg 寫入 msg_msg 的偏移量時,將發出另一個頁面漏洞。此偏移量由 struct msg_msg 標頭的大小決定。

此時,main 暫停以將L固定。我們稍后通過處理 main 中的 setxattr 發出的頁面漏洞來解除對 main 的阻塞,這將釋放L以重新分配為 R。此外,Y 會暫停以將L固定到位。Y 的延續會將 L(此時為 R)中的數據泄漏到用戶空間,然后 Y 將通過解決 X 發出的 setxattr 頁面漏洞來繼續線程 X。最后,當 Y 解決 X 的頁面漏洞時,X 會暫停并繼續寫入L(R)。

第四,從線程 Z 中,我們捕獲由 Y 執行的 msgrcv 中發出的頁面漏洞。

現在 X 通過處理它的頁面漏洞來解除對 main 的阻塞。這將繼續 setxattr 寫入L并隨后第四次釋放 L。然后我們通過 io_uring_setup 系統調用分配一個 io_ring_ctx 對象,因此 Lequiv R$。最后,Z 嘗試獲取一個鎖,如果成功,它將導致它創建一個新線程 T,并使用 setxattr 再次分配 R。但是,此時,線程 Y 持有鎖,因此 Z 暫停嘗試獲取它。

第五,Z 通過處理寫入保護頁漏洞來解除對線程 Y 的阻塞。這首先將 R 復制到用戶空間。但是通過這樣做,它也釋放了R。因此,我們放棄上述鎖定,確保 Z 繼續。當 Z 繼續時,它使用帶有一個值的setxattr,當讀取該值時會導致第一個字節出現頁面漏洞。線程 T 捕捉到這個頁面漏洞并且不處理它。因此,R 不能用于其他線程的重新分配和潛在的損壞。

在我們有了R$的數據之后,我們將當前的R 定位到用戶空間緩沖區的sq_creds偏移量78(縮放因素 sizeof(uint64))。在讀取泄露的 sq_creds 后,我們從中減去 176 。目的是讓R 到sq_creds指向當前struct credt對象的“后面”。然后我們將新值寫回我們的用戶空間緩沖區。最后,我們通過處理 setxattr 發出的頁面漏洞來解除對線程 X 的阻塞。這會將我們的用戶空間緩沖區寫入 R,維護除我們操作的 sq_creds 之外的所有字段。但是通過這樣做,我們也釋放了 R。所以我們再次使用 setxattr 并在 H 中捕獲頁面漏洞,方法與 T 中相同。

最后,我們從線程 T 中直接使用 open 獲取目錄“/etc/”的文件描述符。然后我們向 io_uring 實例發出 openat 請求。檢索完成隊列條目后,我們有了一個文件描述符“/etc/shadow”。然后我們發出一個讀取請求,將“/etc/shadow”的內容復制到用戶空間緩沖區中。

最終結果如下:

參考及來源:https://ruia-ruia.github.io/NFC-UAF/

分享到:
標簽:漏洞
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定