【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用
0x00 概述
最近提交了一些关于 docker remote api 未授权访问导致代码泄露、获取服务器root权限的漏洞,造成的影响都比较严重,比如
因为之前关注这一块的人并不多,这个方法可以算是一个“新的姿势”,本文对漏洞产生的原因和利用过程进行简单的分析和说明,但因为时间和精力有限,可能会有错误,欢迎大家指出~
0x01 起因
先介绍一些东西~
docker swarm
docker swarm 是一个将docker集群变成单一虚拟的docker host工具,使用标准的Docker API,能够方便docker集群的管理和扩展,由docker官方提供,具体的大家可以看官网介绍。
漏洞发现的起因是,有一位同学在使用docker swarm的时候,发现了管理的docker 节点上会开放一个TCP端口2375,绑定在0.0.0.0上,http访问会返回 404 page not found
,然后他研究了下,发现这是 Docker Remote API ,可以执行docker命令,比如访问 http://host:2375/containers/json
会返回服务器当前运行的 container列表,和在docker CLI上执行 docker ps
的效果一样,其他操作比如创建/删除container,拉取image等操作也都可以通过API调用完成,然后他就开始吐槽了,这尼玛太不安全了。
然后我想了想 swarm是用来管理docker集群的,应该放在内网才对。问了之后发现,他是在公网上的几台机器上安装swarm的,并且2375端口的访问策略是开放的,所以可以直接访问。
尼玛这一想,问题来了:
- 他是按照官方文档弄的,难不成文档里写的有问题?
- 他这么干,会不会有其他人也这么干,然后端口就直接暴露在公网了,那岂不是谁可以随便操作了docker了?
因为这位同学刚好有其他事情要忙,没时间撸,我之前也用过docker,所以我就继续研究了,然后就走上了挖掘新姿势的不归路...
0x02 背锅侠
要查清楚是谁的锅,首先要复现下问题,那么只有一种方法,照的文档装一遍docker swarm。
官网给出创建Docker Swarm集群的方法有:
- 使用docker run 运行 swarm container(官方推荐,文档中都是使用该方法)
- 安装 swarm 二进制文件(executable swarm binary)
这里使用官方推荐方法,系统使用ubuntu14.04,按照 Build a Swarm cluster for production 这篇文档装了一遍。
这里简单描述下过程:
- 需要在每台机器上安装docker,并且运行Docker Swarm container
- 需要一个或多个Swarm manager(主从)来管理docker 节点
- 管理的docker节点上需要开放一个TCP端口(2375)来与Swarm manager通信
这里的第三点就是前面提到的暴露的docker端口,我们来看一下文档中docker 节点具体执行的命令
sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
-H参数指定docker daemon绑定在了 tcp://0.0.0.0:2375
上。
docker默认安装的时候只会监听在 unix:///var/run/docker.sock
,因此这里是端口暴露的原因所在。
那么能不能说这个是 docker swarm 的锅呢?
我们来看一下文档中的安装环境
Prerequisites An Amazon Web Services (AWS) account Familiarity with AWS features and tools, such as: Elastic Cloud (EC2) Dashboard Virtual Private Cloud (VPC) Dashboard VPC Security groups Connecting to an EC2 instance using SSH
是在AWS VPC上,默认的访问策略是
AWS uses a “security group” to allow specific types of network traffic on your VPC network. The default security group’s initial set of rules deny all inbound traffic, allow all outbound traffic, and allow all traffic between instances.
即禁止所有的外网端口访问,文档中之后的部分修改了策略允许22和80端口访问,也就说在文档的环境中,不会存在2375端口暴露的问题,且文档中也提到了不要让docker 的端口暴露在外,虽然没有加字体加粗高亮~
For a production environment, you would apply more restrictive security measures. Do not leave Docker Engine ports unprotected.
然而即使高亮了也没有软用,首先是使用者并不一定有类似AWS的VPC环境,再者不是每个使用者都会认真的看文档,所以最终的结论是,这锅docker官方和使用者都得背,谁背的多就不好说了~
0x03 漏洞利用
说如何利用之前,我们先整理下现在能做的事情
执行docker命令,比如操作container、image等
那么如果当前运行的container,或者image内有代码或者其他敏感信息,就可以继续深入了,比如果壳和蜻蜓fm的漏洞,就是深入后的结果。
还有的话,可以做内网代理,进一步渗透。
到目前为止,我们能做的事情都是在docker的环境内,无法直接控制宿主机。
那么怎么才能控制宿主机呢?莫慌,分析下
docker是以root权限运行的,但docker执行命令只能在container内部,与宿主机是隔离的,即使是反弹一个shell,控制的也是container,除非有0day,不然是无法逃逸的到宿主机的~
那么只能从docker命令本身下手,脑洞开了下,想到docker 运行 container的时候,可以将本地文件或目录作为volume挂载到container内,并且在container内部,这些文件和目录是可以修改的。
root权限进程,并且能够写文件,是不是似曾相识?
这里的场景和前段时间的 redis + ssh 漏洞很相似,那么这里需要看一下服务器是否有ssh服务,如果有的话,那么直接把/root/.ssh目录挂载到container内,比如/tmp/.ssh,然后修改/tmp/.ssh/authorized_keys 文件,把自己的public key写进去,修改权限为600,然后就可以以root用户登录了。
注:有些服务器会配置不允许root用户直接登录,可以通过挂载 /etc/ssh/sshd_config 查看配置。这个时候,你换一个用户目录写入就行,并且挂载修改 /etc/sudoers 文件,直接配置成免密码,sudo切换root即可。
如果没有运行ssh服务,那么也可以利用挂载写crontab定时任务,比如ubuntu root用户的crontab文件在 /var/spool/cron/crontabs/root,反弹一个shell~
这里利用方式可能还有很多种,大家可以开下脑洞想哈~
0x04 影响
影响总结:攻击者可以利用该漏洞执行docker命令,获取敏感信息,并获取服务器root权限
目前在公网上暴露的2375端口还有不少,测了一些基本都可以利用。
但docker swarm更多的情况是用在企业内部,虽然在内网,也不意味着绝对安全,当边界被突破,就嘿嘿嘿了~
0x05 修复方案
注:因为本小节内容是看了文档后的个人理解,并且部分内容未进行实际验证,可能会错误,仅供参考!
如果你的2375端口是暴露在公网的,那么最简单的方式就是禁止外网访问或者设置白名单,因为根据官网介绍,swarm本来就不应该在公网中使用。
以上方法仅仅防止了外网访问,但如果本身已经在内网,对于已经撸进内网的攻击者,端口仍然处于可以直接访问的状态,那么有没一些防护方案呢?
为了找到答案,特意看了下docker swarm的文档, Plan for Swarm in production这篇文章提到了两种方案
- 第一种方法是使用TLS认证: Overview Swarm with TLS 和 Configure Docker Swarm for TLS 这两篇文档,说的是配置好TLS后,Docker CLI 在发送命令到docker daemon之前,会首先发送它的证书,如果证书是由daemon信任的CA所签名的,才可以继续执行,官网图如下:
然而在我对公网中使用TLS的docker remote api(使用2376端口)测试中发现,即使没有证书,Docker CLI仍然可以正常访问,这里我也拿docker python api写了脚本,设置不验证证书有效性 ,也同样可以访问。
因为这我没有具体配置过TLS, 只能根据以上测试结果推测 ,走TLS认证,只能防止MITM 攻击,还是无法解决端口未授权访问的问题。
- 第二种方法是网络访问控制(Network access control):文档中列出了 Swarm manager , Swarm nodes 等用到的端口,告诉你要配置合理的访问规则。文档中还提到了这么一段话
For added security you can configure the ephemeral port rules to only allow connections from interfaces on known Swarm devices.
大概意思是只允许信任的swarm devices之间通信。
理想情况就是docker 节点的2375端口只允许swarm manager来访问,但因为swarm manager可能会有多个,就需要配置多条规则,维护起来可能会具有一定复杂度,但只要swarm manager所在机器不被撸,就可以保证docker 节点的2375端口不被未授权访问。当然,这里还需要结合TLS一起使用。
总结来说就是,不要将端口直接暴露在公网,内网中使用需要设置严格的访问规则,并使用TLS。
0x06 瞎扯
如果你仔细阅读了docker swarm的文档,你就会发现除了2375端口,还有其他一些端口也存在相同的问题,这里就不一一的列出了。
本文主要说的是docker swarm,但是只要是会导致端口暴露的,都会存在问题,也许有一些使用者会因为某些原因,把端口配置成功公网访问,或者有另一个"swarm"呢?
还有想说的是,一个新的东西出来,用户和开发者更多关注的是其功能和便利性,而忽略了存在的安全性问题,之后还会有更多的 “docker remote api” 出现,谁将会是下一个呢?
最后还要感谢一下发现这个问题的同学(转我10wb我就告诉你是谁),没他也不会有这个漏洞~
黑客,绝对是黑客!
==============
自己研究部分,目前网上可以的都是执行单挑命令,来去写POC等等
我当时在考虑执行命令反弹个SHELL回来或者怎么才能真正拿到服务器
于是研究了下docker
run -i -t debian /bin/bash
先去version,然后再bash下就好了
不需要反弹,直接拿到权限
唯一遗憾的是没有逃逸出去的办法,网上说SSH写KEY,然后挂载到宿主。
测试了几个都没发现有SSH 自己搭建了 但是没挂载上,需要再研究研究
【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用的更多相关文章
- [Shell]Docker remote api未授权访问漏洞(Port=2375)
0x01 简介 该未授权访问漏洞是因为docker remote api可以执行docker命令,从官方文档可以看出,该接口是目的是取代docker 命令界面,通过url操作docker. Docke ...
- 关于docker remote api未授权访问漏洞的学习与研究
漏洞介绍: 该未授权访问漏洞是因为docker remote api可以执行docker命令,从官方文档可以看出,该接口是目的是取代docker 命令界面,通过url操作docker. docker ...
- docker搭建redis未授权访问漏洞环境
这是redis未授权访问漏洞环境,可以使用该环境练习重置/etc/passwd文件从而重置root密码 环境我已经搭好放在了docker hub 可以使用命令docker search ju5ton1 ...
- Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用
关于Redis Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库 ...
- 验证docker的Redis镜像也存在未授权访问漏洞
看到了这篇老外的博客:Over 30% of Official Images in Docker Hub Contain High Priority Security Vulnerabilities于 ...
- [日常] 研究redis未授权访问漏洞利用过程
前提:redis允许远程连接,不需要密码 1522057495.583846 [0 123.206.24.121:50084] "set" "dUHkp" &q ...
- Docker入门教程(八)Docker Remote API
Docker入门教程(八)Docker Remote API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第八篇,重点介绍了Docker Remote ...
- Docker remote API简单配置使用
1.启动docker remote API的方式如下: docker -d -H uninx:///var/run/docker.sock -H tcp://0.0.0.0:5678 2.但是为了伴随 ...
- Docker remote API
Docker remote API 该教程基于Ubuntu或Debian环境,如果不是,请略过本文 Docker API 在Docker生态系统中一共有三种API Registry API:提供了与来 ...
随机推荐
- jquery ui和jquery easy ui的区别
jquery ui 是jquery开发团队 开发,适用于网站式的页面.jquery easyui 是第三方基于jquery开发,适用于应用程序式的页面. 两者的方法调用也略有不同:jquery ui ...
- SQL Server数据库的三种恢复模式:简单恢复模式、完整恢复模式和大容量日志恢复模式(转载)
SQL Server数据库有三种恢复模式:简单恢复模式.完整恢复模式和大容量日志恢复模式: 1.Simple 简单恢复模式, Simple模式的旧称叫”Checkpoint with truncate ...
- Android判断网络状态
package com.ch.services; import com.ch.utils.NetWorkUtils; import android.app.Service; import androi ...
- iOS 学习笔记 三 (2015.03.05)
服务和特征都是用UUID来唯一标识的,UUID的概念如果不清楚请自行google,国际蓝牙组织为一些很典型的设备(比如测量心跳和血压的设备)规定了标准的service UUID(特征的UUID比较多, ...
- DataGuard主备归档存在gap的处理办法
DataGuard主备之间可能由于网络等原因,造成备库和主库之间的归档日志不一致,这样就产生了gap. 解决gap的步骤: 1.在备库获得gap的详细信息 2.将需要的归档日志从主库拷贝到备库 3.备 ...
- PHP中关于 basename、dirname、pathinfo 详解
basename(url) 返回路径中的文件名部分. dirname(url) 返回路径中的目录名称部分. pathinfo(url) 返回关于文件路径的信息. bas ...
- [C++][代码库]Vector3空间向量类
本文用C++实现一个简单的Vector3类的功能,暂时有的功能是: 1 + - * /算术运算 2 向量的数量积,又叫:点乘 3 向量的向量积,又叫:叉乘 4 向量单位化(normalization) ...
- ACM题目————Subsequence
Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...
- 三种用于select 的选择器
<html lang="en"> <head> <meta charset="utf-8"> <title>选项 ...
- YTU 2986: 删除区间内的元素(线性表)
2986: 删除区间内的元素(线性表) 时间限制: 1 Sec 内存限制: 2 MB 提交: 8 解决: 3 题目描述 若一个线性表L采用顺序存储结构,其中元素都为整数.设计一个算法,删除元素值在 ...