Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。但Docker也并非那么安全,比如:Remote api未授权访问漏洞。。。

漏洞介绍:

该未授权访问漏洞是因为docker remote api可以执行docker命令,从官方文档可以看出,该接口是目的是取代docker 命令界面,通过url操作docker。

docker swarm是docker下的分布化应用的本地集群,在开放2375监听集群容器时,会调用这个api

docker registery docker registry api未授权_Docker

url输入ip:2375/version就会列出基本信息,和docker version命令效果一样。

docker registery docker registry api未授权_服务器_02

同样,url为ip:2375/v1.23/containers/json会列出容器信息,和docker ps -a效果一样。

漏洞利用:

通过docker client执行目标服务器容器命令。

1.列出所有镜像。

docker registery docker registry api未授权_信息安全_03

2.列出所用容器

docker registery docker registry api未授权_服务器_04

 

3.进入容器两种方法:

  3.1.

    start 启动一个已经停止的容器

      attach 连接一个已经停止的容器

      当然这个容器默认entrypoint必须是/bin/bash,关于这点可以在json里看到,还有挂载,后面提权会用到,这个也可以在json文件里看到。

docker registery docker registry api未授权_服务器_05

 

  3.2.

  新运行一个容器并将entrypoint设置为/bin/bash,挂载点设置为服务器的根目录挂载至/mnt目录下

docker registery docker registry api未授权_docker_06

  注意:

  docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可。

  docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。


  wooyun上lijiejie是因为docker client版本不一致调用api去create重构一个容器,并在attach、start后捕获到输出

 

4.服务器提权的几种方法

  4.1

  启动一个容器,挂载宿主机的/root/目录,之后将攻击者的ssh公钥~/.ssh/id_rsa.pub的内容写到入宿主机的/root/.ssh/authorized_keys文件中,之后就可以用root账户直接登录了。

   本地获取ssh公钥

docker registery docker registry api未授权_docker_07

  将公钥复制到被攻击者的/root/.ssh/authorized_keys文件中

docker registery docker registry api未授权_Docker_08

  ssh连接远程服务器

docker registery docker registry api未授权_信息安全_09

  4.2

  启动一个容器,挂载宿主机的/etc/目录,之后将反弹shell的脚本写入到/etc/crontab中,攻击机nc -vv -l -p Port会得到一个反弹的shell

  因为没有公网IP,就不试了。

目标机上:

docker registery docker registry api未授权_信息安全_10

攻击机上:

docker registery docker registry api未授权_信息安全_11

 

  4.3

   也可以挂载var/spool/cron/目录,将反弹shell的脚本写入到/var/spool/cron/root(centos系统)或/var/spool/cron/crontabs/root(ubuntu系统)