Docker Remote API未授权访问漏洞
虽然是个老洞了,但是前几天工作中又遇到了,所以拿出来研究回顾一下,并附上一些自己的理解。
0x00 安装
参考官方文档即可:官方文档
测试环境为Ubuntu 16.04 + Docker 17.03
0x01 配置Docker Remote API
修改/lib/systemd/system/docker.service
文件中的dockerd
启动参数,使其绑定在0.0.0.0
上,导致未授权任意访问。
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:8888
然后执行:
systemctl daemon-reload
systemctl restart docker.service
如果没有错误提示,则表示dockerd已经成功监听,可以通过如下命令进行验证:
curl "http://127.0.0.1:8888/v1.25/info"
这样的开启方法是非常危险的!请勿在生产环境中模仿!
0x02 攻击思路
通过docker client或者http直接请求就可以访问这个API,通过这个接口,我们可以新建container,删除已有container,甚至是获取宿主机的shell。
攻击方法很多,和Redis匿名访问的攻击思路大体一致,我这里列出来两点:
- 修改/root/.ssh/authorized_keys
- 修改/etc/crontab等计划任务文件
0x03 漏洞利用
获取images列表
http://192.168.198.130:8888/v1.25/images/json
可以获取到所有的images列表
我们选取ubuntu:latest
创建新的container。创建新的container并挂载宿主机的/root/目录
运行并查看结果
先把刚刚的container跑起来:
POST http://192.168.198.130:8888/v1.25/containers/{container_id}/start
其中container_id为刚刚创建时候返回的container id,注意是POST方法,不用传递任何数据。
查看一下有没有错误
GET http://192.168.198.130:8888/v1.25/containers/{container_id}/logs?stderr=True
发现返回了错误信息:
/bin/sh: 1: cannot create /tmp/.ssh/authorized_keys: Directory nonexistent
我们按照步骤2的方式再重新打一次,将命令改为mkdir -p /tmp/.ssh
,然后再重新echo一遍公钥。
- SSH连接
可以看到宿主机的/root/.ssh目录下面确实出现了我们的公钥,SSH连接一下试试。
直接登录
通过这种方式其实有弊端,可能有些服务器被配置成不允许root用户登录,利用起来就会稍显繁琐,就不能这么轻松的拿到root shell了。
0x04 修复建议
可能有些人会认为,开在内网并无大碍,但实际上并非如此,一些类似SSRF之类的漏洞就可以轻易突破网络边界,再加上很多开发人员照搬文档教程,导致开放在2375默认端口,则为攻击者的内网探测减少了工作量。除了攻击者可以轻易获取root shell之外,内部的“内鬼”也可能对此漏洞加以利用,所以危害不容小觑。
那么如何修复这种漏洞呢,有几种方法:
- built in HTTPS encrypted socket
- 在docker api服务器前面加一个代理,例如nginx,设置401认证
- 设置iptables,只允许受信的机器访问该API接口