| name | detecting-container-escape-attempts |
| description | 容器逃逸是一种严重攻击技术,攻击者突破容器隔离以访问主机系统或其他容器。检测涉及使用 Falco、Sysdig 和自定义 seccomp/审计规则监控逃逸指标,包括命名空间操纵、能力滥用、内核漏洞利用、敏感路径挂载和异常系统调用模式。 |
| domain | cybersecurity |
| subdomain | container-security |
| tags | ["containers","kubernetes","docker","security","runtime-security","escape-detection"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
检测容器逃逸尝试
概述
容器逃逸是一种严重攻击技术,攻击者突破容器隔离以访问主机系统或其他容器。检测涉及使用 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 |
检测层次
- 系统调用监控 - eBPF/内核模块实时捕获系统调用
- 文件完整性 - 检测对逃逸相关路径的修改
- 进程监控 - 跟踪进程创建、命名空间变化
- 网络监控 - 检测容器到主机的连接
- 审计日志 - Linux auditd 用于能力和挂载操作
实施步骤
步骤 1:部署 Falco 进行运行时检测
falco:
driver:
kind: ebpf
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
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 逃逸检测规则
- 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]
- 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]
- rule: Container
[, , ]
[, , ]
[, , ]
[, , ]
[, , ]
步骤 3:配置 Seccomp Profile 防止逃逸
{
"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",
步骤 4:容器逃逸审计规则
-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:实时告警流水线
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"
验证命令
kubectl run falco-event-generator \
--image=falcosecurity/event-generator \
--restart=Never \
-- run syscall --action PtraceAttachContainer
kubectl logs -n falco-system -l app.kubernetes.io/name=falco --tail=50
docker inspect --format '{{.HostConfig.SecurityOpt}}' <container-id>
ausearch -k container_escape --interpret
参考资料