iT邦幫忙

2022 iThome 鐵人賽

DAY 16
1
影片教學

從建立環境、驗證漏洞、感受漏洞來學習資安系列 第 18

Day16 - DirtyPipe - 如果有一個分頁,你可以提權,你會不會想要用?

  • 分享至 

  • xImage
  •  

如果有一個宇宙,你很幸福,你會不會想要去 - 奇異博士2:失控多元宇宙 (2022)

Yes

  • 第16天要針對 DirtyPipe 的漏洞原理做說明,順便也來看一下當初漏洞發現者的心路歷程/images/emoticon/emoticon18.gif

  • DirtyPipe 漏洞主要是因為當初發現者透過 zero-copy 的技術去傳輸資料時,發現傳輸的檔案有時候會發生檔案驗證碼驗證錯誤,疑似傳輸過程內容遭受竄改。在經過多方確認的情況下,他將問題指向了 Linux kernel 核心,那這算是一個很厲害的舉動,因為正常的開發者都不會覺得有 bug 是作業系統的問題。那他當時建立的驗證程式參考如下 :

  • 參考資料: The Dirty Pipe Vulnerability

  1. vim writer.c #建立驗證程式
    #include <unistd.h>
    int main(int argc, char **argv) {
    for (;;) write(1, "AAAA\n", 5);
    }
    // ./writer >foo
    
  2. vim splicer.c #建立驗證程式
    #define _GNU_SOURCE
    #include <unistd.h>
    #include <fcntl.h>
    int main(int argc, char **argv) {
    for (;;) {
        splice(0, 0, 1, 0, 2, 0);
        write(1, "BBBB\n", 5);
    }
    }
    // ./splicer <foo |cat >/dev/null
    
  3. gcc writer.c -o writer # 編譯程式
  4. gcc splicer.c -o splicer # 編譯程式
  5. 開啟兩個視窗,一個用普通帳號,一個用 root 帳號
  6. touch foo # 透過 root 帳號建立檔案
  7. ./splicer < foo | cat > /dev/null # 透過普通帳號執行
  8. ./writer > foo # 透過 root 帳號執行
  9. Ctrl + c 停止執行,並觀察 foo 檔案內容
  • 這邊稍微解釋一下 splice 的作用,其呼叫介面為 ssize_t splice(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, size_t len, unsigned int flags),它的用途是可以將來源的 file descriptor - fd_in 的內容寫到目的端的 file descriptor - fd_out。相關細節可以參考 splice(2) - Linux manual page 以及 Linux I/O 原理和 Zero-copy 技术全面揭秘。從上面程式分析後會發現理論上 foo 檔案應該只有 A 的字元寫入,但實際上讀取發現居然有 B 的字元混進來,代表著 Linux kernel 在實作上應該有缺陷導致其他來源資料混入。而且依照權限設定理論上普通帳號沒有權限去修改 foo 檔案,但寫入資料居然包含普通帳號的輸出資料,這也意味著 kernel 在透過 splice 以及 pipe 處理資料時並沒有考慮到寫入檔案的權限問題。

  • 但究竟是甚麼原因導致這個檔案本身透過 splice + pipe 時讓另一個程式有機會改變檔案呢? 原因在於 Linux kernel 於 8.5 時可透過一些手法讓 pipe 結構內的 pipe_buffer 開啟 PIPE_BUF_FLAG_CAN_MERGE 的機制,一旦開啟後對該 pipe_buffer 對到的分頁進行寫入時,會蓋掉該分頁的內容。而一旦分頁"髒"掉的情況下,作業系統就會認為該分頁被修改,因此會將結果回寫回該分頁的來源,以這個漏洞為例就是檔案系統。以下就以 pipe_buffer 結構為是意圖進行說明 :
    https://ithelp.ithome.com.tw/upload/images/20221001/201483081bvMUScZAn.png
    參考來源 : Linux I/O 原理和 Zero-copy 技术全面揭秘

  • 也因此大概就了解 DirtyPipe 的漏洞原理,當然細節部分還是很多,包含 splice 的設計原理、pipe 的運作機制也都還是要補完的地方,這邊就只是快速的帶過而已。如果對後續更深入的資訊有興趣的話,也可以參考 HITCON PEACE 2022 的演講議題 How we use Dirty Pipe to get reverse root shell on Android Emulator and Pixel 6,另外我之前的影片有針對 pipe 的用法比較詳細的說明 跪著講解 Dirty Pipe(骯髒管線)的漏洞原理 - CVE-2022-0847 也可以參考一下。/images/emoticon/emoticon13.gif

  • 最後提一下 Linux Dirty系列漏洞目前有三個,分別是 Dirty COW(CVE-2016-5195)、Dirty Pipe(CVE-2022-0847) 以及 DirtyCred (CVE-2022-2588)。 DirtyCred 的原理更加的困難,牽涉到 Use-After-Free 、 Double Free 的攻擊手法,有興趣的話也可以自己去研究看看。相關影片可參考 Linux 三髒之力 Assemble,先來了解一下 DirtyCred (CVE-2022-2588) 大概的攻擊原理!!! 以及 千呼萬喚髒出來~~~ 終於等到 DirtyCred (CVE-2022-2588) 攻擊程式惹!!!


上一篇
Day15 - DirtyPipe 只有在這個骯髒的管線,才能義正嚴詞的說那些分頁是無辜的。 (作業5解答)
下一篇
Day17 - 我最喜歡做的事之一,就是對認為 Python 供應鏈很安全的傢伙說 "NO" (作業6)
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言