iT邦幫忙

2026 iThome 鐵人賽

DAY 15
1

昨天我們透過操作 docker.sock ,建立一個掛入主機根目錄的新容器;即使沒有 Docker CLI,也能直接呼叫 API。那麼,如果容器裡連 docker.sock 都沒有,還有可能從容器存取主機檔案嗎?

今天換一個起點:容器內沒有 Docker CLI,也沒有掛載 docker.sock;但主機路徑已在容器啟動時掛入,這樣的掛載會如何影響主機安全?今天的主題是-Bind Mount。

bind-mounts 介紹

從 Docker 官方文件可以了解到為什麼需要使用 bind-mounts:
lab-01
參考來源:Bind mounts

官方文件列出了幾種適合使用 Bind Mount 的情境,例如:

  • 在 Host 開發環境與 Container 之間共享原始碼或建置產物。
  • 將 Container 產生的檔案保存到 Host 的檔案系統。
  • 將 Host 上的設定檔提供給 Container 使用。

因此,Bind Mount 最核心的功能可以理解成:讓 Container 直接存取 Host 上指定的檔案或目錄。

但就像刀子一樣,用得好生活便利,用不好就會傷到自己。有些使用者為了方便,索性直接把整個根目錄掛載到容器裡面。這時候就會出現一個尷尬的問題:

lab-03

在 Day 12 我們提過:若未另外指定使用者,Docker 容器預設以 root 身分執行;主機根目錄下也有許多由 root 擁有的關鍵檔案。不過,容器內的 root 不代表一定有權修改主機檔案。當主機根目錄以可寫方式掛入容器,且容器內程序對目標檔案具有寫入權限時,就可能修改主機檔案。下面用一個簡單的實驗,看看這種掛載方式帶來的風險。

實作改寫 Host 主機腳本:

進入容器之後我們需要尋找根目錄有沒有被掛載,我們會先用 mount 查看容器目前掛載的目錄有哪些?
lab-04

看到這些不用怕,我們把可疑的檔案路徑抓起來就好。整理好可疑的檔案路徑之後可以使用這個指令來查看 /host 對應的掛載資訊:

grep '檔案路徑' /proc/self/mountinfo

lab-05

從這筆 mountinfo 紀錄可以看到,第四欄的 / 表示掛載的是該檔案系統的根目錄,第五欄的 /host 則是它在容器內的掛載位置。接著執行 chroot /host,讓新啟動的 shell 以 /host 作為 / 來查找檔案;下圖再將容器與主機的 /root 檔案清單進行比對:
lab-06

上圖的左邊是容器環境而右邊是主機環境,左側是在容器內執行 chroot 後的 shell,右側是主機 shell;兩邊列出的 /root 檔案相互對應。

我們找到了裡面有一個 setup.sh 我們故意把腳本改寫成簡單的 Hello world。

echo 'echo "Hello world"' > /root/setup.sh

lab-07

可以看到,主機上的 setup.sh 已被容器內的操作改寫,主機端以 bash setup.sh 執行時,會輸出 Hello world。

這證明在掛載與檔案權限均允許寫入的條件下,容器能修改主機檔案。結合 Day 08 與 Day 10 提到的執行流程,且主機後續以高權限執行這支遭改寫的腳本,攻擊者就可能進一步取得主機上的程式執行能力。因此,將主機根目錄以可寫方式掛載進容器,會帶來嚴重的安全風險。

今天的內容主要是補足 Day 14 為什麼會一直用到掛載根目錄的方式來當作提權的手法,其實 docker 的官方文件也有說明在做
bind-mounts 的時候必須非常小心,否則會造成危險的資安問題。

感謝大家的收看,明天我們將會接續討論特權容器的提權方式。
我們明天見!


上一篇
Day 14|docker.sock 為什麼常被說等同於 Host Root?
下一篇
Day 16|Privileged Container:一個參數如何讓隔離邊界失效
系列文
我以前被社會打穿,現在輪到我研究怎麼把系統打穿:資安工程師的 30 天紅隊轉職實驗 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言