Linux提权CVE-2022-0847分析
漏洞利用原理:
通過pipe生成一個管道,然后使用write調用pip_write將管道填滿flag為PIPE_BUF_FLAG_CAN_MERGE,然后用read將緩沖區全部釋放,但是根據splice進行零拷貝時copy_page_to_iter_pipe沒有將flag初始化,導致緩沖區仍然留存PIPE_BUF_FLAG_CAN_MERGE。進而在write上檢測flag存在PIPE_BUF_FLAG_CAN_MERGE來達成越權寫入操作。
什么是零拷貝?
零拷貝是作用于兩個文件間移動,正常文件拷貝流程一般為cpu對內存空間進行多次讀寫操作將拷貝數據從用戶態到內核態再返回用戶態,而零拷貝讓數據不需要經過用戶態,而是將內核緩沖區與用戶程序進行共享,這樣就不需要把內核緩沖區的內容往用戶空間拷貝。應用程序再調用write(),操作系統直接將內核緩沖區的內容傳輸到指定輸出端了。
具體的文件通過管道傳輸流程:
in端 == write == pipe == splice == out端
out端通過splice與內核緩沖區進行共享,然后in端調用write將內容拷貝到內核緩沖區進而寫入到out端。
【→所有資源關注我,私信回復“資料”獲取←】
1、網絡安全學習路線
2、電子書籍(白帽子)
3、安全大廠內部視頻
4、100份src文檔
5、常見安全面試題
6、ctf大賽經典題目解析
7、全套工具包
8、應急響應筆記
設置緩沖區flag為PIPE_BUF_FLAG_CAN_MERGE
分析pipe_write函數源碼
當我們給pipe->tmp_pipe = NULL下斷點后,可以看到當我們執行exp后的flags設置為0x10(PIPE_BUF_FLAG_CAN_MERGE)
這里的page = 0xffffea00001b09c0,是我們write申請的頁,然后用于與內核緩沖區進行數據傳輸
根據堆棧回溯可以看到,這個只是調用write時會將flags設置為PIPE_BUF_FLAG_CAN_MERGE
上述代碼實質就是將pipe緩沖區所以flag設置為PIPE_BUF_FLAG_CAN_MERGE,然后調用read是釋放pipe緩沖區來讓緩沖區變為閑置等待調用狀態,進而讓flag為PIPE_BUF_FLAG_CAN_MERGE執行下一次exp中的write。
但是我們只關注flag上的PIPE_BUF_FLAG_CAN_MERGE,那么調用read后會不會將flags上的PIPE_BUF_FLAG_CAN_MERGE呢?
splice實現零拷貝傳輸
在調用splice時會調用到__copy_page_to_iter
下面是splice的調用鏈:(查看copy_page_to_iter_pipe堆棧平衡得出)
在splice_file_to_pipe上存在3種調用情況:
- in/out都是pipe類型
- in是pipe類型
- out是pipe類型(這是exp調用類型)
如下即為exp使用的第三種splice零拷貝的源碼:
上面只校驗了out端是否為pipe類型,然后檢測執行程序用戶是否對root權限文件具有讀寫操作,然后就調用splice_file_to_pipe來進行下一步漏洞利用。
注意下面這個判斷:
if (off_in) { //這里限制了只能從偏移值1開始if (!(in->f_mode & FMODE_PREAD)) //判斷輸入是否有讀權限,所以exp只需要對輸出到的root權限文件具有可讀權限return -EINVAL;offset = *off_in;} else { .....if (off_in) {判斷是導致進行越權寫入偏移值必須為0的原因。
分析copy_page_to_iter_pipe
上述即為splice零拷貝過程中“out端與內核緩沖區共享”的調用源碼
可以看到,由于是頁引用行為,所以我們傳輸的數據大小不能大于原文件大小。
補丁上也是在這個文件上對緩沖區的flag進行了初始化操作。
那么我們可以得知,只要在這里對flag進行初始化,就不可能導致越權讀寫產生,那么說明了判定flag存在PIPE_BUF_FLAG_CAN_MERGE進而達到下一步利用這個過程是不在splice上的。
下面是利用代碼:
調用write連接pipe進行splice零拷貝時的檢測手段
分析零拷貝中所有涉及函數可知,只有在調用pipe_write時存在檢測操作。
分析pipe_write:
當緩沖區上的flag為PIPE_BUF_FLAG_CAN_MERGE則直接調用copy_page_from_iter對數據進行管道寫入操作,進而達成越權寫。
所以可以知道read釋放緩沖區時沒有對flag進行初始化操作。
下面是利用代碼:
關于參數測試
經案例上使用的"root"可以使用,而""root"可以使用,而""root"可以使用,而"root"無輸出
總結
以上是生活随笔為你收集整理的Linux提权CVE-2022-0847分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [web安全]深入理解反射式dll注入技
- 下一篇: CVE-2016-0095提权漏洞学习笔