Kali Docker + Vulhub 靶场搭建完整指南
Author: 枷锁
适用环境 :macOS Apple Silicon (M1/M2/M3/M4) + VMware Fusion + Kali 2026.2 ARM64
目的:在 Kali 虚拟机中安装 Docker,克隆 Vulhub 漏洞仓库,启动/关闭靶场环境
Vulhub 是什么?
Vulhub 是一个开源漏洞靶场集合,基于 Docker 和 Docker Compose 构建。它为每个已知漏洞提供了预配置的容器化环境,一行命令就能启动一个包含特定漏洞的服务,无需手动搭建复杂的环境。
为什么用 Vulhub?
传统漏洞复现需要自己搭环境:找对应版本、配置数据库、改配置文件......一个漏洞环境折腾半天。Vulhub 把这一切打包成了 Docker 容器:
| 传统方式 | Vulhub |
|---|---|
| 找对应软件版本 → 手动安装 | docker compose up -d 一键启动 |
| 环境残留、系统污染 | 容器隔离,用完即删 |
| 只能用一次,换漏洞重装系统 | 随时启停,多个环境并存 |
| 依赖冲突(Java 版本、Python 版本等) | 每个容器独立依赖 |
| 文档分散,不知怎么搭建 | 每个漏洞自带 README,含复现步骤 |
Vulhub 覆盖了哪些漏洞?
截至 2026 年,Vulhub 收录了 180+ 个漏洞环境,涵盖:
- Java 中间件:Weblogic、Tomcat、Spring、Struts2、Fastjson、Shiro、Log4j 等
- CMS / Web 应用:Confluence、Django、Drupal、WordPress、Discuz 等
- 大数据组件:Apache Druid、Airflow、Flink、Solr、Elasticsearch 等
- 基础设施:Redis、Docker、Kubernetes、GitLab、Jenkins 等
- 常见漏洞类型:RCE、反序列化、SSRF、认证绕过、文件上传、SQL 注入等
项目地址
- 官网:https://vulhub.org
- GitHub:https://github.com/vulhub/vulhub
- 许可证:MIT(开源免费)
前置知识:为什么需要这些东西?
Docker 是什么?
Docker 是一个容器引擎,你可以把它理解成一个轻量级虚拟机。每个漏洞环境跑在一个独立的容器里,互不干扰,用完就删,不会搞脏系统。
为什么需要 QEMU?
你的 Mac 是 Apple Silicon(ARM64 架构),Kali 虚拟机也是 ARM64 的。但很多 Vulhub 的 Docker 镜像是 x86_64(amd64)架构的,不能直接在 ARM64 上运行。
QEMU 就是一个翻译器,让 ARM64 的 CPU 能执行 x86_64 的指令。装了 qemu-user-static 之后,Docker 会自动调用 QEMU 来模拟运行 x86 镜像。
┌─────────────────────────────────────────┐
│ Mac (Apple Silicon ARM64) │
│ ┌───────────────────────────────────┐ │
│ │ VMware Fusion │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ Kali VM (ARM64) │ │ │
│ │ │ ┌───────────────────────┐ │ │ │
│ │ │ │ Docker 容器 (x86_64) │ │ │ │
│ │ │ │ 通过 QEMU 模拟运行 │ │ │ │
│ │ │ └───────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
网络是怎么通的?
Mac 浏览器 ──> 172.16.25.139:8080 ──> Kali ──> Docker 容器 :8080
Kali 用的是 VMware NAT 网络,IP 固定为 172.16.25.139。Docker 启动容器时把容器的 8080 端口映射到 Kali 的 8080 端口,所以 Mac 访问 Kali 的 8080 就等于访问容器里的漏洞服务。
第一步:安装 Docker
以下所有命令在 Kali 终端中执行。
1.1 更新软件包列表
bash
sudo apt update
解释 :从软件源拉取最新的软件包索引。sudo 表示以 root 权限执行。每次安装新软件前都应该先跑这条。

预期输出:
已下载 72.5 MB,耗时 14秒 (5,068 kB/s)
正在读取软件包列表...
正在分析软件包的依赖关系树...
正在读取状态信息...
所有软件包均为最新。
1.2 安装 Docker 引擎和 Docker Compose
bash
sudo apt install -y docker.io docker-compose

解释:
apt install= 安装软件包-y= 自动回答 yes,不用手动确认docker.io= Docker 引擎本身docker-compose= 编排工具,用 yml 配置文件一键启动整个环境
预期输出:会列出所有要安装的依赖包,最后显示安装完成。大约需要 1-2 分钟。
1.3 启动 Docker 服务并设为开机自启
bash
sudo systemctl enable docker --now
解释:
systemctl enable= 设置服务开机自动启动--now= 现在就启动(等同于enable+start两条命令)- 服务名是
docker,不是docker.io
1.4 把 kali 用户加入 docker 组
bash
sudo usermod -aG docker kali
解释:
usermod= 修改用户属性-aG docker= 将用户追加(append)到 docker 组- 默认情况下只有 root 能操作 Docker,把 kali 加入 docker 组后,kali 用户也能直接跑
docker命令,不需要每次加sudo
注意 :这条命令执行后不会立即生效,需要重新加载用户组。
1.5 刷新当前终端的用户组(不需要注销)
bash
newgrp docker
解释 :newgrp docker 会在当前 shell 中开启一个子 shell,使用新的组权限。执行完后当前终端就可以不用 sudo 直接操作 Docker 了。
替代方案:直接注销 Kali 再重新登录,组权限会自动加载。
第二步:安装跨架构模拟器 QEMU
2.1 安装
bash
sudo apt install -y qemu-user-static binfmt-support
解释:
qemu-user-static= QEMU 用户模式静态二进制,让 ARM64 系统能运行 x86_64 程序binfmt-support= 二进制格式支持,告诉 Linux 内核遇到 x86_64 程序时自动调用 QEMU
2.2 验证 QEMU 已生效
bash
ls /proc/sys/fs/binfmt_misc/
预期输出 :看到 qemu-x86_64 字样的条目,说明 x86 模拟已注册。

第三步:验证 Docker 安装
3.1 查看 Docker 版本
bash
docker --version
解释:如果 Docker 装好了,这条命令会输出版本号。

预期输出:
Docker version 28.5.2+dfsg4, build 9cc6dea35e9a
3.2 查看 Docker 服务运行状态
bash
sudo systemctl status docker
解释 :检查 Docker 守护进程是否在运行。active (running) 表示正常运行。
预期输出(关键行):
Active: active (running) since ...
按 q 退出状态查看。

第四步:克隆 Vulhub 到 Kali 桌面
4.1 安装 git(如果还没装)
bash
sudo apt install -y git

4.2 浅克隆 Vulhub 仓库
bash
git clone --depth 1 https://github.com/vulhub/vulhub.git ~/桌面/vulhub
逐词解释:
git clone= 从远程仓库下载代码--depth 1= 只下载最新版本,不下载历史提交记录。Vulhub 仓库很大,完整克隆会很慢,浅克隆体积小、速度快https://github.com/vulhub/vulhub.git= 仓库地址~/桌面/vulhub= 保存到 Kali 桌面上的vulhub文件夹(~是当前用户的家目录)
预期输出:
正克隆到 '/home/kali/桌面/vulhub'...
remote: Enumerating objects: ...
...
大约 1-2 分钟克隆完成。
4.3 查看克隆结果
bash
ls ~/桌面/vulhub/
预期输出:150+ 个文件夹,每个文件夹对应一个应用或中间件。

1panel apache-druid confluence django ...
activemq apisix couchdb discuz ...
adminer cacti craftcms flink ...
...
每个文件夹里面有具体的漏洞编号子文件夹,比如 tomcat/CVE-2017-12615。
4.4 快速浏览某个漏洞目录
bash
ls ~/桌面/vulhub/tomcat/
预期输出:

CVE-2017-12615 CVE-2020-1938 CVE-2025-24813 CVE-2026-34486 tomcat8
每个 CVE 编号文件夹里都有一个 docker-compose.yml 和一个 README.md。
第五步:启动靶场(完整演示)
下面以 Tomcat CVE-2017-12615(Tomcat 任意文件写入漏洞,可 getshell)为例,完整演示启动过程。
5.1 进入漏洞目录
bash
cd ~/桌面/vulhub/tomcat/CVE-2017-12615
解释 :所有 Docker Compose 命令都必须在包含 docker-compose.yml 的目录下执行。
5.2 查看目录里有什么
bash
ls -la
预期输出:

-rw-r--r-- 1 kali kali 374 6月 28 16:49 Dockerfile
-rw-r--r-- 1 kali kali 545 6月 28 16:49 docker-compose.yml
-rw-r--r-- 1 kali kali 1234 6月 28 16:49 README.md
docker-compose.yml= 编排文件,定义了用哪个镜像、开哪个端口Dockerfile= 描述了如何构建镜像README.md= 漏洞说明和利用方法
5.3 查看 docker-compose.yml 的内容
bash
cat docker-compose.yml
预期输出:

yaml
version: '2'
services:
tomcat:
build: .
ports:
- "8080:8080"
逐行解释:
version: '2'= Compose 文件格式版本services:= 定义服务列表tomcat:= 服务名称build: .= 从当前目录的 Dockerfile 构建镜像(而不是从仓库拉取)ports: "8080:8080"= 端口映射,把容器的 8080 端口映射到 Kali 的 8080 端口。左边是 Kali 端口,右边是容器端口
5.4 启动靶场
bash
sudo docker compose up -d
逐词解释:
sudo= Docker 组还没生效的话需要用 sudo(之前newgrp docker生效了的可以不加)docker compose= Docker Compose 命令up= 启动服务-d= detached 模式,后台运行。如果不加-d,终端会被日志占满,Ctrl+C 就会停止容器
预期输出:

[+] Building 23.3s
[+] Running 2/2
✔ Network cve-2017-12615_default Created
✔ Container cve-2017-12615-tomcat-1 Started
如果看到 exec format error,回到第二步安装 QEMU。
如果看到 platform (linux/amd64) does not match 的警告但容器仍然启动了,这是正常的------QEMU 正在模拟。
5.5 确认容器正在运行
bash
sudo docker ps
逐词解释:
docker ps= 列出所有正在运行的容器- 不加
sudo的前提是已经加入 docker 组且重新登录了
预期输出:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee4df86bbdd4 cve-2017-12615-tomcat "catalina.sh run" 10 seconds ago Up 10 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp cve-2017-12615-tomcat-1
各列解释:
CONTAINER ID= 容器唯一 ID(缩写)IMAGE= 使用的镜像名COMMAND= 容器启动时执行的命令CREATED= 容器创建时间STATUS= 运行状态,Up表示正在运行PORTS= 端口映射,0.0.0.0:8080->8080/tcp表示 Kali 的 8080 端口(所有网卡)转发到容器的 8080 端口NAMES= 容器名称
5.6 验证服务可访问(在 Kali 内测试)
bash
curl -I http://localhost:8080/
逐词解释:
curl= 命令行 HTTP 客户端-I= 只获取 HTTP 响应头(不下载页面内容)http://localhost:8080/= Kali 本机的 8080 端口
预期输出:

HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
...
看到 HTTP/1.1 200 说明 Tomcat 服务正常运行。
5.7 查看容器日志
bash
sudo docker logs cve-2017-12615-tomcat-1
解释 :docker logs 加上容器名可以查看该容器的标准输出。容器名从 docker ps 的 NAMES 列获取。
第六步:从 Mac 访问靶场
6.1 在 Mac 浏览器打开
Kali 静态 IP 是 172.16.25.139,容器映射的端口是 8080,所以在 Mac 浏览器地址栏输入:
http://172.16.25.139:8080
就能看到 Tomcat 的欢迎页面。

、
6.2 通信路径图
┌──────────────────────────────────────────────────┐
│ 你的 Mac │
│ │
│ 浏览器输入 http://172.16.25.139:8080 ─────────┐ │
│ │ │
└────────────────────────────────────────────────│──┘
│
VMware NAT 网络 (vmnet8) │
│
┌────────────────────────────────────────────────│──┐
│ Kali VM (172.16.25.139) │ │
│ ▼ │
│ Docker 端口映射 (0.0.0.0:8080) │
│ │ │
│ ▼ │
│ Tomcat 容器 (内部 :8080) │
└────────────────────────────────────────────────────┘
第七步:关闭靶场
7.1 停止并删除容器
bash
cd ~/桌面/vulhub/tomcat/CVE-2017-12615
sudo docker compose down
逐词解释:
- 必须先
cd到包含docker-compose.yml的目录 docker compose down= 停止容器 + 删除容器 + 删除创建的网络。比docker stop清理得更彻底
预期输出:

[+] Running 2/2
✔ Container cve-2017-12615-tomcat-1 Removed
✔ Network cve-2017-12615_default Removed
7.2 验证容器已删除
bash
sudo docker ps
预期输出:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
表头下面什么都没有,说明没有运行中的容器。
7.3 查看所有容器(包括已停止的)
bash
sudo docker ps -a
解释 :-a = all,显示所有状态的容器。如果 down 执行正确,这里也看不到之前的 Tomcat 容器了。
7.4 彻底清理磁盘空间(可选)
bash
sudo docker system prune -a
逐词解释:
docker system prune= 清理未使用的 Docker 资源-a= 包括未使用的镜像(不仅仅是悬空镜像)
执行前会提示确认:
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N]
输入 y 确认。注意:这会删除所有已停止的容器和未使用的镜像,下次启动靶场时需要重新下载/构建镜像。
第八步:更多靶场示例
8.1 Weblogic CVE-2017-10271(反序列化 RCE)
bash
cd ~/桌面/vulhub/weblogic/CVE-2017-10271
sudo docker compose up -d
访问:http://172.16.25.139:7001
Weblogic 启动较慢(1-2 分钟),用 sudo docker logs -f <容器名> 查看实时日志,看到 Server started in RUNNING mode 就启动了。
8.2 Spring Cloud Gateway RCE(CVE-2022-22947)
bash
cd ~/桌面/vulhub/spring/CVE-2022-22947
sudo docker compose up -d
访问:http://172.16.25.139:8080
8.3 Confluence OGNL 注入 RCE(CVE-2022-26134)
bash
cd ~/桌面/vulhub/confluence/CVE-2022-26134
sudo docker compose up -d
访问:http://172.16.25.139:8090
8.4 同时跑多个靶场
不同漏洞环境用不同端口,可以同时启动:
bash
# 启动 Tomcat(8080)
cd ~/桌面/vulhub/tomcat/CVE-2017-12615 && sudo docker compose up -d
# 启动 Weblogic(7001)
cd ~/桌面/vulhub/weblogic/CVE-2017-10271 && sudo docker compose up -d
# 启动 Spring(8080 端口冲突!需要先改 docker-compose.yml)
cd ~/桌面/vulhub/spring/CVE-2022-22947
# 编辑 docker-compose.yml,把 8080:8080 改成 8081:8080
sudo docker compose up -d
查看所有正在运行的容器:
bash
sudo docker ps
第九步:常用 Docker 命令速查
容器管理
| 命令 | 作用 | 示例 |
|---|---|---|
docker ps |
列出运行中的容器 | sudo docker ps |
docker ps -a |
列出所有容器(含已停止) | sudo docker ps -a |
docker start <容器名> |
启动已停止的容器 | sudo docker start cve-xxx |
docker stop <容器名> |
停止运行中的容器 | sudo docker stop cve-xxx |
docker restart <容器名> |
重启容器 | sudo docker restart cve-xxx |
docker rm <容器名> |
删除已停止的容器 | sudo docker rm cve-xxx |
docker rm -f <容器名> |
强制删除容器(即使运行中) | sudo docker rm -f cve-xxx |
docker stop $(docker ps -q) |
停止所有运行中的容器 | sudo docker stop $(sudo docker ps -q) |
日志和调试
| 命令 | 作用 | 示例 |
|---|---|---|
docker logs <容器名> |
查看容器日志 | sudo docker logs cve-xxx |
docker logs -f <容器名> |
实时跟踪日志 | sudo docker logs -f cve-xxx |
docker logs --tail 50 <容器名> |
查看最近 50 行日志 | sudo docker logs --tail 50 cve-xxx |
docker exec -it <容器名> /bin/bash |
进入容器的 shell | sudo docker exec -it cve-xxx /bin/bash |
docker inspect <容器名> |
查看容器详细信息 | sudo docker inspect cve-xxx |
镜像管理
| 命令 | 作用 | 示例 |
|---|---|---|
docker images |
列出本地所有镜像 | sudo docker images |
docker rmi <镜像名> |
删除镜像 | sudo docker rmi cve-2017-12615-tomcat |
docker pull <镜像名> |
从仓库拉取镜像 | sudo docker pull tomcat:8.5.19 |
Compose 命令
| 命令 | 作用 | 示例 |
|---|---|---|
docker compose up -d |
后台启动服务 | sudo docker compose up -d |
docker compose down |
停止并删除服务 | sudo docker compose down |
docker compose ps |
查看 Compose 启动的容器 | sudo docker compose ps |
docker compose logs |
查看 Compose 服务日志 | sudo docker compose logs |
docker compose restart |
重启服务 | sudo docker compose restart |
docker compose up -d --build |
重新构建并启动 | sudo docker compose up -d --build |
空间管理
| 命令 | 作用 |
|---|---|
docker system df |
查看 Docker 占用的磁盘空间 |
docker system prune |
清理停止的容器、未使用的网络 |
docker system prune -a |
清理所有未使用的资源(含镜像) |
第十步:常见问题排查
Q1:docker compose up -d 报 exec format error
原因:镜像是 x86_64 架构,但没有安装 QEMU 模拟器。
解决:
bash
sudo apt install -y qemu-user-static binfmt-support
然后重新启动:
bash
sudo docker compose down
sudo docker compose up -d
Q2:docker ps 报 permission denied
原因:kali 用户不在 docker 组中。
解决:
bash
sudo usermod -aG docker kali
newgrp docker
或者每次命令前加 sudo。
Q3:docker compose up -d 报端口已被占用
原因:另一个容器或服务已经在使用同一个端口。
排查是哪个进程占用了端口:
bash
sudo ss -tlnp | grep 8080
解决方案一:停止占用端口的容器
bash
sudo docker ps # 找到占用端口的容器
sudo docker stop <容器名>
解决方案二:修改端口映射
bash
# 编辑 docker-compose.yml
vim docker-compose.yml
# 把 "8080:8080" 改成 "8081:8080"
# 然后重新启动
sudo docker compose up -d
Q4:容器启动后 curl 连不上
原因:服务可能还没完全启动。
排查步骤:
bash
# 1. 先确认容器确实在运行
sudo docker ps
# 2. 查看容器日志,看服务启动到哪一步了
sudo docker logs <容器名>
# 3. 等几秒再试
sleep 5 && curl -I http://localhost:8080/
Weblogic、Confluence 等重型应用可能需要 2-3 分钟才能完全启动。
Q5:从 Mac 浏览器打不开 http://172.16.25.139:8080
排查步骤:
bash
# 1. Mac 终端 ping Kali
ping 172.16.25.139
# 2. Kali 终端确认容器在运行
sudo docker ps
# 3. Kali 终端确认端口在监听
sudo ss -tlnp | grep 8080
# 4. Mac 终端测试端口
curl -I http://172.16.25.139:8080/
Q6:VMware Fusion 重启后 Docker 容器都没了
原因 :docker compose down 或系统重启会停止容器,但不会自动删除。
解决 :容器停止后可以用 docker compose up -d 重新启动(不需要重新下载镜像):
bash
cd ~/桌面/vulhub/tomcat/CVE-2017-12615
sudo docker compose up -d
如果想让容器在 Kali 开机时自动启动,在 docker-compose.yml 中添加 restart: always。
Q7:下载镜像很慢
原因:Docker Hub 默认从国外拉取。
解决:配置国内镜像加速:
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://mirror.ustc.edu.cn/dockerhub",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
sudo systemctl restart docker