Kate Li (Taiwan)的部落格

首頁

髒牛

作者 zindani 時間 2020-03-30
all

Dirty COW是一個漏洞的名稱,該漏洞源於競爭條件,當觸發寫時拷貝情况時,Linux內核的記憶體子系統處理只讀私有映射的管道。寫時拷貝允許共亯資源,而不是複製資源。如果資源重複但未修改,則無需創建新資源-只有在對共亯資源進行修改時才會觸發副本,只有在資源實際不同時才會創建唯一版本。在這種競爭條件觸發的某些情况下,使用此漏洞的攻擊者有可能修改原始副本,而不是自己的副本。

有一個很好的視頻,做了一個偉大的工作,通過詳細的錯誤和初步利用你。

但是,對我來說,比本地許可權提升更有趣的是,這是Linux內核中的一個bug,Docker這樣的容器不會拯救我們。

為了利用這個bug,我們需要跨所有行程共亯資源。在這裡,找到一個可能做有趣事情的候選人成為了前進的方向。Linux有一個特性“vDSO”(虛擬動態共亯對象),它是一個小型的共亯庫,內核會自動映射到所有用戶空間應用程序的地址空間。聽起來有用嗎?它之所以存在,是因為某些系統調用使用得太頻繁,以至於以正常管道調用它們最終會顯著影響系統的整體效能,但它也非常適合我們的邪惡需求。

所以,我們在所有行程中都有一些共用記憶體(庫),其中包含將要執行的程式碼。。。怎麼辦。。。

scumjr綜合了一個POC,該POC使用Dirty COW修改vDSO記憶體空間中的clock_ghtime()函數。該漏洞修改了所有調用方(而不僅僅是正在運行的行程)執行此函數的過程。一旦觸發race條件並執行外殼程式碼,它將向您發送一個根外殼。

我在AWS中建立了一個測試環境,你也可以。在us-west-2區域,使用amazon ami創建一個實例,id為ami-7172b611,在我的示例中,我運行的是kernel 4.4.19-29.55.amzn1.x86ʂ,但是任何易受攻擊的內核都應該足够了。

在github上可以找到Docker檔案等來創建容器和部署scumjr的漏洞。

我創建了一個視頻,連結在下麵,它可以引導您完成攻擊。首先在EC2實例上顯示作業系統版本和docker版本。

然後它啟動一個運行shell的容器。進入容器後,我編輯有效負載,將shell發送回容器的IP,編譯並觸發攻擊。

一旦我得到一個連接,我將證明我是根用戶,並且我在主機上看到容器上那些檔案之外的檔案。

或youtube上的[視頻](https://youtu.be/BwUfHJXgYg0)。

我特別感興趣的是演示如何逃離docker,因為我認為很多人高估了需要什麼。內核攻擊比用戶空間陞級更為罕見,但它們並非沒有示例,並且理解即使內核功能提供了分離功能,使容器成為可能,也有可能通過內核攻擊繞過它們。

有更多的POC漏洞使用不同的策略值得關注。github正在構建一個全面的清單。

vDSO背景。。。

vDSO是一種性能優化。vDSO的手册頁調用gettimeofday作為一個例子,它經常被用戶空間應用程序和C庫調用。當一個行程需要知道它現在是什麼時間時,可以考慮時間戳記或計時迴圈,或者經常輪詢所有這些。這不是秘密資訊,囙此,它可以輕鬆安全地在所有行程中共亯。內核負責將時間放入任何行程可以訪問的記憶體位置,並且通過vDSO共亯對象中定義的函數,行程可以訪問這些資訊。這樣,gettimeofday從一個更昂貴的系統調用變為一個普通函數的調用。砰,一切都快了。

利用的詳細資訊

此漏洞利用了這樣一個事實,即存在映射到所有行程的共用記憶體範圍,這些行程包含經常調用的公共函數的程式碼。利用此漏洞可將負載寫入vDSO記憶體中的某些未使用空間,並在執行正常業務之前更改函數前導碼以調用此外殼程式碼。

外殼程式碼首先檢查其是否被根調用。如果是,則繼續,否則返回並執行常規時鐘。接下來,它檢查檔案“/tmp/.x”是否存在。如果它能得到這個檔,那麼在這一點上,它知道它是根目錄,它是唯一運行的線程。接下來,外殼程式碼打開一個反向TCP連接,為外殼提供到負載中硬編碼IP和埠的服務。默認情况下,這是localhost,但在容器的情况下,將其更改為實際運行利用漏洞的位置非常有用。payload.s原始檔案中的第17行和第18行設定反向shell的ip和埠,表示為小的endian值:

IP equ 0x0100007f埠equ 0xd204

IP equ 0x0100007f PORT equ 0xd204

更新:有一個補丁允許您在命令列上以“IP:port”的格式指定IP和埠,所以這比亂搞這些程式碼要好得多!

感謝scumjr强大的POC漏洞,LiveOverflow强大的walk through,當然還有Phil Oester發現漏洞。

安妮·斯普拉特攝