# Detecting Container Escape Attempts

> 容器逃逸是一种严重攻击技术，攻击者突破容器隔离以访问主机系统或其他容器。检测涉及使用 Falco、Sysdig 和自定义 seccomp/审计规则监控逃逸指标，包括命名空间操纵、能力滥用、内核漏洞利用、敏感路径挂载和异常系统调用模式。

- Skill: `killvxk/detecting-container-escape-attempts` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/detecting-container-escape-attempts`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/detecting-container-escape-attempts/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/detecting-container-escape-attempts

---

# 检测容器逃逸尝试

## 概述

容器逃逸是一种严重攻击技术，攻击者突破容器隔离以访问主机系统或其他容器。检测涉及使用 Falco、Sysdig 和自定义 seccomp/审计规则监控逃逸指标，包括命名空间操纵、能力滥用、内核漏洞利用、挂载敏感路径和异常系统调用模式。

## 前提条件

- 内核 5.10+ 的 Linux 主机（支持 eBPF）
- Falco 0.37+ 已安装（内核模块或 eBPF 探针）
- Docker Engine 或 containerd 运行时
- auditd 已配置
- 加载 eBPF/内核模块需要 Root 访问权限

## 核心概念

### 常见容器逃逸向量

| 向量 | 技术 | MITRE ID |
|------|------|----------|
| 特权容器 | 挂载主机文件系统，加载内核模块 | T1611 |
| Docker socket 挂载 | 从内部创建特权容器 | T1610 |
| 内核漏洞利用 | CVE-2022-0185 (fsconfig), Dirty Pipe, runc CVEs | T1068 |
| 能力滥用 | CAP_SYS_ADMIN, CAP_SYS_PTRACE, CAP_NET_ADMIN | T1548 |
| 敏感挂载 | /proc/sysrq-trigger, /proc/kcore, cgroup release_agent | T1611 |
| 命名空间逃逸 | nsenter, unshare 到主机命名空间 | T1611 |
| 符号链接/绑定挂载 | 通过 /proc/self/root 逃逸 | T1611 |

### 检测层次

1. **系统调用监控** - eBPF/内核模块实时捕获系统调用
2. **文件完整性** - 检测对逃逸相关路径的修改
3. **进程监控** - 跟踪进程创建、命名空间变化
4. **网络监控** - 检测容器到主机的连接
5. **审计日志** - Linux auditd 用于能力和挂载操作

## 实施步骤

### 步骤 1：部署 Falco 进行运行时检测

```yaml
# Helm 部署的 falco-values.yaml
falco:
  driver:
    kind: ebpf   # 或 modern_ebpf（内核 5.8+）
  rules_files:
    - /etc/falco/falco_rules.yaml
    - /etc/falco/falco_rules.local.yaml
    - /etc/falco/rules.d
  json_output: true
  json_include_output_property: true
  http_output:
    enabled: true
    url: "http://falcosidekick:2801"
  grpc:
    enabled: true
  priority: warning
```

```bash
# 通过 Helm 安装 Falco
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
  --namespace falco-system --create-namespace \
  -f falco-values.yaml
```

### 步骤 2：自定义 Falco 逃逸检测规则

```yaml
# /etc/falco/rules.d/container_escape.yaml

# 检测通过特权容器的容器逃逸
- rule: Container Escape via Privileged Mode
  desc: 检测使用特权能力尝试逃逸容器
  condition: >
    spawned_process and container and
    (proc.name in (nsenter, unshare, mount, umount, modprobe, insmod) or
     (proc.name = chroot and proc.args contains "/host"))
  output: >
    通过特权操作尝试容器逃逸
    (user=%user.name container=%container.name image=%container.image.repository
     command=%proc.cmdline pid=%proc.pid %container.info)
  priority: CRITICAL
  tags: [container, escape, T1611]

# 检测从容器访问 Docker socket
- rule: Container Access to Docker Socket
  desc: 检测容器读/写 Docker socket
  condition: >
    (open_read or open_write) and container and
    fd.name = /var/run/docker.sock
  output: >
    从容器访问了 Docker socket
    (user=%user.name container=%container.name image=%container.image.repository
     fd=%fd.name command=%proc.cmdline %container.info)
  priority: CRITICAL
  tags: [container, escape, docker_socket]

# 检测对敏感 proc 文件系统的访问
- rule: Container Access to Sensitive Proc Paths
  desc: 检测容器访问主机敏感的 proc 路径
  condition: >
    open_read and container and
    (fd.name startswith /proc/sysrq-trigger or
     fd.name startswith /proc/kcore or
     fd.name startswith /proc/kmsg or
     fd.name startswith /proc/kallsyms or
     fd.name startswith /sys/kernel)
  output: >
    从容器访问了敏感的 proc/sys 路径
    (user=%user.name container=%container.name path=%fd.name
     command=%proc.cmdline %container.info)
  priority: CRITICAL
  tags: [container, escape, proc_access]

# 检测 cgroup 逃逸技术
- rule: Container Cgroup Escape Attempt
  desc: 检测写入 cgroup release_agent（逃逸技术）
  condition: >
    open_write and container and
    (fd.name contains release_agent or
     fd.name contains notify_on_release)
  output: >
    检测到 cgroup 逃逸尝试
    (user=%user.name container=%container.name path=%fd.name
     command=%proc.cmdline %container.info)
  priority: CRITICAL
  tags: [container, escape, cgroup]

# 检测从容器加载内核模块
- rule: Container Loading Kernel Module
  desc: 检测容器尝试加载内核模块
  condition: >
    spawned_process and container and
    (proc.name in (modprobe, insmod, rmmod) or
     (evt.type = init_module or evt.type = finit_module))
  output: >
    从容器尝试加载内核模块
    (user=%user.name container=%container.name command=%proc.cmdline
     %container.info)
  priority: CRITICAL
  tags: [container, escape, kernel_module]

# 检测命名空间操纵
- rule: Container Namespace Manipulation
  desc: 检测来自容器的 setns/unshare 系统调用
  condition: >
    container and (evt.type = setns or evt.type = unshare) and
    not proc.name in (containerd-shim, runc)
  output: >
    来自容器的命名空间操纵
    (user=%user.name container=%container.name syscall=%evt.type
     command=%proc.cmdline %container.info)
  priority: CRITICAL
  tags: [container, escape, namespace]

# 检测来自容器的挂载操作
- rule: Container Mount Sensitive Filesystem
  desc: 检测容器挂载主机文件系统
  condition: >
    spawned_process and container and proc.name = mount and
    (proc.args contains "/dev/" or proc.args contains "proc" or
     proc.args contains "sysfs")
  output: >
    来自容器的敏感挂载操作
    (user=%user.name container=%container.name command=%proc.cmdline
     %container.info)
  priority: HIGH
  tags: [container, escape, mount]
```

### 步骤 3：配置 Seccomp Profile 防止逃逸

```json
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "archMap": [
    { "architecture": "SCMP_ARCH_X86_64", "subArchitectures": ["SCMP_ARCH_X86", "SCMP_ARCH_X32"] }
  ],
  "syscalls": [
    {
      "names": [
        "read", "write", "open", "close", "stat", "fstat", "lstat",
        "poll", "lseek", "mmap", "mprotect", "munmap", "brk",
        "rt_sigaction", "rt_sigprocmask", "ioctl", "access",
        "pipe", "select", "sched_yield", "dup", "dup2",
        "nanosleep", "getpid", "socket", "connect", "accept",
        "sendto", "recvfrom", "bind", "listen", "getsockname",
        "getpeername", "socketpair", "setsockopt", "getsockopt",
        "clone", "fork", "vfork", "execve", "exit", "wait4",
        "kill", "getuid", "getgid", "geteuid", "getegid",
        "epoll_create", "epoll_wait", "epoll_ctl", "epoll_create1",
        "futex", "set_tid_address", "set_robust_list",
        "openat", "newfstatat", "readlinkat", "fchownat",
        "clock_gettime", "clock_getres", "clock_nanosleep",
        "getrandom", "memfd_create", "statx", "rseq"
      ],
      "action": "SCMP_ACT_ALLOW"
    },
    {
      "names": ["unshare", "setns", "mount", "umount2", "pivot_root",
                "init_module", "finit_module", "delete_module",
                "kexec_load", "kexec_file_load", "ptrace",
                "reboot", "swapon", "swapoff", "sethostname",
                "setdomainname", "keyctl", "bpf"],
      "action": "SCMP_ACT_LOG",
      "comment": "记录逃逸相关系统调用用于检测"
    }
  ]
}
```

### 步骤 4：容器逃逸审计规则

```bash
# /etc/audit/rules.d/container-escape.rules

# 监控命名空间操作
-a always,exit -F arch=b64 -S setns -S unshare -k container_escape
-a always,exit -F arch=b64 -S mount -S umount2 -k container_mount
-a always,exit -F arch=b64 -S init_module -S finit_module -S delete_module -k kernel_module
-a always,exit -F arch=b64 -S ptrace -k process_trace

# 监控敏感路径
-w /var/run/docker.sock -p rwxa -k docker_socket
-w /proc/sysrq-trigger -p w -k sysrq
-w /proc/kcore -p r -k kcore_read

# 监控容器运行时
-w /usr/bin/runc -p x -k container_runtime
-w /usr/bin/containerd -p x -k container_runtime
-w /usr/bin/docker -p x -k container_runtime
```

### 步骤 5：实时告警流水线

```yaml
# 用于告警路由的 Falcosidekick 配置
config:
  slack:
    webhookurl: "https://hooks.slack.com/services/xxx"
    minimumpriority: "critical"
    messageformat: |
      *容器逃逸告警*
      规则: {{ .Rule }}
      优先级: {{ .Priority }}
      输出: {{ .Output }}

  elasticsearch:
    hostport: "https://elasticsearch:9200"
    index: "falco-alerts"
    minimumpriority: "warning"

  pagerduty:
    routingkey: "xxxx"
    minimumpriority: "critical"
```

## 验证命令

```bash
# 使用事件生成器测试 Falco 规则
kubectl run falco-event-generator \
  --image=falcosecurity/event-generator \
  --restart=Never \
  -- run syscall --action PtraceAttachContainer

# 检查 Falco 告警
kubectl logs -n falco-system -l app.kubernetes.io/name=falco --tail=50

# 验证 seccomp profile 已加载
docker inspect --format '{{.HostConfig.SecurityOpt}}' <container-id>

# 检查审计日志中的逃逸相关事件
ausearch -k container_escape --interpret
```

## 参考资料

- [Falco 运行时安全](https://falco.org/docs/)
- [容器逃逸技术 - HackTricks](https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation)
- [MITRE ATT&CK T1611 - 逃逸到主机](https://attack.mitre.org/techniques/T1611/)
- [Sysdig 容器安全](https://sysdig.com/products/secure/)

