NEITHNET 情資分享
NEITHNET 資安實驗室
Dirty pipe是個2022年2月被提出來的Linux kernel function漏洞,CVE編號為CVE-2022-0847,攻擊者可以透過這個漏洞,以一般使用者權限帳號對唯讀檔案進行寫入動作。
揭露此漏洞的工程師Max Kellermann,會發現這個漏洞的原因是,他發現log壓縮儲存後無法成功解壓縮,但並不是每次都會發生,而是幾個月才發生一次,而且都只有CRC的部分出錯,檔案本身資料都沒有問題。因此Max Kellermann才深入挖掘這個漏洞,發現這個漏洞發生的原因在於splice這個kernel function裡。
splice function結構如下 :
ssize_t splice(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, size_t len, unsigned int flags);
splice function執行目的是從pipe中拼接data出來到另一個檔案,fd_in代表想要移的位置(pipe or file),fd_out代表想要寫入的位置,
執行後會將fd_in內容放到fd_out,中間是使用zero copy方法。
splice function行為流程步驟:
1、把fd_in內容丟到pipe
2、kernel會把pipe內容載入page cache,並創建新的pipe_buffer指向page cache
3、在這個步驟有機會可以覆寫資料到page cache汙染pipe
4、然後pipe內容在放置到fd_out (可以是pipe, file, socket, block device, character device)
問題會出在第三個步驟,因為page cache一直都是有寫入權限的,畢竟他是由kernel帶起的。這時假如PIPE_BUF_FLAG_CAN_MERGE設定為true,就可以接著上個page來寫,而非創建一個新的。原本PIPE_BUF_FLAG_CAN_MERGE的用意是防止浪費空間,但在splice中並沒有將flag初始化,所以可以自行去設定flag,由於和之前內容共用就可以試圖去污染內容。
而這個漏洞一開始會隨機發生的原因是page cache並不會寫回硬碟,除非他認為這個page是被汙染的。所以污染回去的前提是,必須有其他程序讓page被認為是dirty才會覆寫回去,而且只要重開機,或是kernel要重新宣告記憶體有拋棄cache等行為,就可以不在硬碟留下痕跡的被刪除掉。
漏洞執行手法:
1、創建新的pipe
2、用資料填滿pipe且加入PIPE_BUF_FLAG_CAN_MERGE flag
3、把想寫入的檔案資料利用O_RDONLY開啟並拼接到pipe
4、寫攻擊payload到pipe,這些資料會覆寫page cache造成汙染
常見攻擊手法(https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit):目的是去修改/etc/passwd,修改root密碼,讓攻擊者可以使用root帳號登入。
1、準備pipe
2、任意資料填入pipe且加入PIPE_BUF_FLAG_CAN_MERGE flag
3、把/etc/passwd利用O_RDONLY開啟並拼接到pipe
4、因為有PIPE_BUF_FLAG_CAN_MERGE flag,所以會從剛剛開啟的pipe繼續寫,根據前面算好的offset把想插入的內容覆寫到讀取的內容造成汙染
把code裡的這段const char *const data = “:$1$aaron$pIwpJwMMcozsUxAtRa85w.:0:0:test:/root:/bin/sh\n”;
執行成功之後會去修改/etc/passwd,把這段插入裡面造成root的密碼被更改成aaron,於是就能取得root權限。
Max Kellermann發現Dirty pipe的心路歷程有很詳盡的寫在網站(https://dirtypipe.cm4all.com/)裡,建議大家都能去看一下。而這個漏洞因為出現在kernel中,因此修補方式就是更新到Linux 5.16.11、5.15.25、 5.10.102以上。
參考資料
https://man7.org/linux/man-pages/man2/splice.2.html
https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit