标注的博客| 安全研究| 渗透测试| APT

首页

安全圈发布docker remote api未授权访问漏洞

作者 boch 时间 2020-02-27
漏洞安全圈
来源:安全圈 - https://www.anquanquan.org/archives/172/ 虽然是个老洞了,但是前几天工作中又遇到了,所以拿出来研究回顾一下,并附上一些自己的理解。 0x00 安装 参考官方文档即可:官方文档测试环境为Ubuntu 16.04 + Docker 17.03 0x01 配置Docker Remote API 修改/lib/systemd/system/docker.service文件中的dockerd启动参数,使其绑定在0.0.0.0上,导致未授权任意访问。 /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。 获取images列表http://192.168.198.130:8888/v1.25/images/json可以获取到所有的images列表我们选取ubuntu:latest创建新的container。 ubuntu:latest 创建新的container并挂载宿主机的/root/目录 创建新的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发现返回了错误信息: 运行并查看结果先把刚刚的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 mkdir -p /tmp/.ssh SSH连接可以看到宿主机的/root/.ssh目录下面确实出现了我们的公钥,SSH连接一下试试。 直接登录 通过这种方式其实有弊端,可能有些服务器被配置成不允许root用户登录,利用起来就会稍显繁琐,就不能这么轻松的拿到root shell了。 0x04 修复建议 可能有些人会认为,开在内网并无大碍,但实际上并非如此,一些类似SSRF之类的漏洞就可以轻易突破网络边界,再加上很多开发人员照搬文档教程,导致开放在2375默认端口,则为攻击者的内网探测减少了工作量。除了攻击者可以轻易获取root shell之外,内部的“内鬼”也可能对此漏洞加以利用,所以危害不容小觑。 那么如何修复这种漏洞呢,有几种方法: built in HTTPS encrypted socket 在docker api服务器前面加一个代理,例如nginx,设置401认证 设置iptables,只允许受信的机器访问该API接口