p0's blog | 破 关注网络安全
Docker Remote API的安全配置
发表于: | 分类: 技术分享 | 评论:0 | 阅读: 2555

又是一年双十一,没有妹纸没有Money,还是写代码吧-.-
假期的时候写了个AWD的攻防平台,团队内部练习使用,部分靶机使用docker实现。前段时间进行了一次内部比赛测试,手工启动的docker,然后又往平台录入的docker信息,不够优雅(可以说相当麻烦)。最近空闲下来再去改进改进,准备使用Docker提供的API。不过大家都知道如果没进行安全配置,Docker Remote API有个未授权的问题,以前也没想着怎么去安全配置,看了官方文档,其实可以通过配置TLS保证API的安全。

0x01 Docker API

首先是怎么配置远程访问的API:

sudo vim /etc/default/docker

加入下面一行
DOCKER_OPTS="-H tcp://0.0.0.0:2375"

重启docker即可:
sudo service docker restart

PS:这是网上给的配置方法,也是这种简单配置让Docker Daemon把服务暴露在tcp的2375端口上,这样就可以在网络上操作Docker了。Docker本身没有身份认证的功能,只要网络上能访问到服务端口,就可以操作Docker。

客户端:

-H为连接目标主机docker服务

docker -H tcp://192.168.211.238:2375

查看docker版本

docker -H tcp://192.168.211.238:2375 version

0x02 漏洞利用方法

看到这可能会想,这样也只能获取到docker的操作权限,并不能获取到主机的权限。大家都知道docker可以挂载宿主文件夹,出问题的点就是volumes可外部挂载宿主文件的目录,并且docker默认使用root运行,这样就可以造成任意文件的读取和写入。

1. 写入公钥

可以挂载/root到docker,然后写入ssh公钥:

docker -H tcp://192.168.211.238:2375 run -id -v /root:/xxoo centos:7

然后进入容器:

docker -H tcp://192.168.211.238:2375 exec -it 容器id /bin/bash

写入公钥:

mkdir /xxoo/.ssh
vi /xxoo/.ssh/authorized_keys

写入自己的公钥即可:

2. 其他利用方法

可以挂载/var/spool/cron/目录,添加计划任务反弹shell,如果有其他服务可以结合其他服务进行测试。

这里不再介绍了,可以参考redis未授权访问的利用方法

redis未授权访问漏洞利用总结

0x03 安全配置

最简单的方法就是配置防火墙,设置ACL,仅允许信任的来源IP连接。不再敖述了,网上很多防火墙的配置方法。这里主要说一下怎么利用TLS进行安全配置。

PS:下文中的IP地址换成自己的Docker服务器IP地址

首先,在Docker守护进程的主机上,生成CA私有和公共密钥

openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem

现在我们有了一个CA,可以创建一个服务器密钥和证书签名请求(CSR)

openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=192.168.211.238" -sha256 -new -key server-key.pem -out server.csr

接下来,用CA来签署公共密钥:

vim extfile.cnf
加入下列内容:

subjectAltName = DNS:192.168.211.238,IP:192.168.211.238,IP:127.0.0.1
extendedKeyUsage = serverAuth

然后生成key:

openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf

创建客户端密钥和证书签名请求:

openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr

修改extfile.cnf

subjectAltName = DNS:192.168.211.238,IP:192.168.211.238,IP:127.0.0.1
extendedKeyUsage = clientAuth

生成签名私钥:

openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

现在client.csrserver.csr两个文件可以删除了。

将Docker服务停止了,然后:

sudo dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2375启动Docker守护进程,并将其挂载在2375端口。

现在再用docker -H tcp://123.123.123.123:2375 version去连接Docker服务器发现已经不能连接了。

使用证书连接:

复制ca.pem,cert.pem,key.pem三个文件到客户端

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=192.168.211.238:2375 version连接即可

如果想默认连接该Docker服务器,可以进行如下配置:

ca.pem,cert.pem,key.pem三个文件移动到 ~/.docker

设置环境变量:
export DOCKER_HOST=tcp://$HOST:2375 DOCKER_TLS_VERIFY=1

执行docker xxx即默认连接Docker服务器进行操作。

现在就可以愉悦的使用Docker Remote API了。

0x04 参考资料


著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:p0
链接:https://p0sec.net/index.php/archives/115/
来源:https://p0sec.net/

添加新评论

TOP