Kali Docker + Vulhub 靶场搭建完整指南

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 注入等

项目地址

前置知识:为什么需要这些东西?

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 psNAMES 列获取。


第六步:从 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 -dexec 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 pspermission 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