天天看點

Docker的一個安全漏洞

最近又翻譯了一篇關于Docker的文章,内容是Docker釋出的一個安全漏洞以及應對方法,位址在docker中文社群的《突破 DOCKER 容器的漏洞驗證代碼》

其實我十來年前做過一段時間的系統安全,還結識了安全圈裡一幫兄弟,後來我轉行做了存儲,也一直在關注安全領域。這一兩年安全行業迅猛發展,看得我有時候真是羨慕嫉妒恨啊......

回到技術話題,這個漏洞其實很容易了解。Linux上,每個程序除了根據運作者的uid進行權限識别,還有一組kernel capability,這一組在kernel代碼裡面以CAP_開頭的宏更細緻的定義了程序所擁有的權限。

而在容器也就是container内部,權限的設計就很複雜了。Container内運作的程序,本質上都直接運作在主機的核心空間中,和其他主機上的程序在核心中沒什麼差別,都有task_struct。是以為了限制container内程序的通路權限,讓他們感覺自己運作在自己獨立的空間中,就要在程序資料結構中設定特定的參數,在很多核心調用中,虛構傳回。比如最基本的chroot(),讓container程序隻能将指定的目錄當作根目錄進行通路。

而攻擊者(黑客)想要突破這個限制,要從container内部程序想辦法通路到宿主系統的各種資源。最早最粗糙的攻擊方式就是用各種特殊符号,比如“../../../../”。這種現在看起來搞笑的攻擊方法在30年前UNIX上可是很奏效的,後來慢慢的很多簡單的漏洞就被補上了。

具體到這個從docker的容器中通路到宿主系統的攻擊方法,是利用了kernel的CAP_DAC_READ_SEARCH這個capability配合open_by_handle_at()這個系統調用。Docker 0.12之前的版本,在建立新的container之前,放棄了很多kernel的capability,卻忘記了這一個,乃至于容器内的子程序都繼承了這個cap。而擁有這個cap以後,通過指定inode的值,可以通過open_by_handle_at()這個系統調用直接打開inode值對應的檔案,而不再是通過路徑打開。而通常來說,/根檔案系統的inode号是2.是以通過構造合理的參數,使用open_by_handle_at(),可以打開宿主系統的根目錄。打開了根目錄之後嘛,嘿嘿,就可以随意便利和打開下面的檔案咯。

這裡再貼個英文的關于該漏洞更詳細的說明 Docker breakout exploit analysis

值得欣慰的是,從0.12版本以後,docker在建立新容器程序的時候,會放棄所有的kernel capability。這個問題就不存在啦。

繼續閱讀