iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0

Day 15 與 Day 16 介紹了容器錯誤設定可能造成的權限提升與主機存取風險。當容器由 K8S 管理時,類似的設定仍可能破壞隔離。今天透過兩個實驗,觀察 hostPath 掛載,以及 privileged 與 hostPID 的組合,如何讓容器接觸 Node 的資源。

HostPath:Pod 在 Node 上面建立檔案。

先看一下 K8S 的文件讓我們知道是什麼參數可以讓它把目錄掛在容器裡面的:
lab-01

從這邊我們也可以證明 K8S 裡面也會有掛載根目錄的風險,在 Day 23 的 Lab 中刻意將 hostPath.path 設為 /,並讓測試 Pod 執行於 Worker .183,我們用實作來觀察 HostPath 的風險性:

先用 mount 觀察掛載資訊,找出 /host 這個掛載點,再進一步檢查其來源與內容。
lab-02

1. 確認掛進來的是 node 的根目錄:

用以下指令確認掛載進來的根目錄屬於哪一台 Node?

ls /host                 
cat /host/etc/hostname 

lab-03

/host 下的目錄結構符合 Linux 系統根目錄,且 /host/etc/hostname 的內容與 Worker .183 相符,可以簡單推敲出這個根目錄是 Worker .183 的。

2. 使用 chroot 切換根目錄,驗證 Node 檔案寫入能力

Lab 已將 Node 的根目錄以可讀寫方式掛載到 /host,且容器行程具備對應的檔案存取權限。接著使用 chroot /host 切換根目錄,並建立檔案,驗證對 Node 檔案系統的寫入能力。

chroot /host id
chroot /host touch /root/abc.txt

lab-04

可以看到我們很輕鬆地在 183 上面建立了一個 txt 檔案,因此即便在 K8S 上面依然會碰到掛載根目錄的風險。

privileged + hostPID 跳到 Node

接下來改用另一個測試 Pod,啟用 spec.hostPID: true,並在容器的 securityContext 中設定 privileged: true。

1. 檢查 Pod 的執行環境與權限?

這次使用 privileged + hostPID 的組合搭配 nsenter 來達成容器逃逸,我們先沿用 Day 16 的檢查方式先檢查我們的權限:

grep CapEff /proc/self/status 
ls /dev | grep -E '^(sd|vd|nvme|dm-)' 
ps | head -3

lab-05

根據截圖顯示,容器行程具有廣泛的有效 capabilities,/dev 中也出現多個磁碟與 device-mapper 裝置節點。此外,ps 可見主機的 systemd 與啟用 hostPID: true 的設定相符。

2. 使用 nsenter 進入 Node 的指定 namespace

接著以 Node 的 PID 1 為目標,使用 nsenter 在指定的 namespace 中執行指令,觀察主機名稱、執行身分與可存取的檔案:

nsenter -t 1 -m -u -i -n -p -- hostname
nsenter -t 1 -m -u -i -n -p -- id
nsenter -t 1 -m -u -i -n -p -- ls -l /root

lab-06

這邊解釋一下甚麼是 nsenter ?我們可以依據 Linux manual page 看到官方是這樣說明的:
lab-07
nsenter(1) — Linux manual page

nsenter 的常見用途之一,是讓管理者或除錯工具在目標行程的 namespace 中檢查問題。

官方手冊也提到 nsenter 會在你指定的 Linux namespace 裡執行程式;如果沒有指定程式,就啟動一個 shell。

這邊補充一下幾個基本的 nsenter 會用到的參數。

nsenter -m -u -i -n -p -t "pid" bash ; 

-a, --all 進入目標行程的所有可用 namespace
-m, --mount[=<file>] 進入目標行程的 mount namespace
-u, --uts[=<file>] 進入目標行程的 UTS namespace
-i, --ipc[=<file>] 進入目標行程的 IPC namespace
-n, --net[=<file>] 進入目標行程的 network namespace
-p, --pid[=<file>] 在目標 PID namespace 中執行後續程式
-t, --target <pid> 指定用來取得 namespace 等資訊的目標行程 PID。

回到指令面,透過參數我們可以進入 host 主機的 PID 1 這個 Process 的 namespace 裡面,因為容器行程原本就以 UID 0 執行,並具備進入目標 namespace 所需的權限。nsenter 讓新執行的程式使用 Node PID 1 的指定 namespace;執行後仍呈現 root 身分:

 nsenter -m -u -i -n -p -t 1 bash ;

lab-08


以上就是今天的內容,會發現即使容器由 K8S 管理,掛載主機根目錄或過度授予特權,仍可能破壞容器與 Node 之間的隔離。不論是開發還是維運團隊都應該知道資訊安全的重要性,否則建立起來的 K8S 很容易被駭客攻擊。

感謝大家的收看,我們明天見!


上一篇
Day 22|Kubernetes Secret 真的有 Secret 嗎?從 Pod 尋找敏感資訊
系列文
我以前被社會打穿,現在輪到我研究怎麼把系統打穿:資安工程師的 30 天紅隊轉職實驗 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言