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