- 网络安全
- 漏洞扫描
- 渗透测试
- 应用安全
- CLI
【免费下载链接】wpscan
WPScan WordPress security scanner. Written for security professionals and blog maintainers to test the security of their WordPress websites. Contact us via contact@wpscan.com
本文以仓库根目录的 AGENTS.md 为骨架,面向需要在 WPScan 仓库中开发、调试与测试的 AI 编码 Agent 与 Ruby 开发者,系统梳理项目的架构分层、控制器链、Finders/Models 设计、开发命令、测试规范与 WPScan API 集成细节。读完本文,你将掌握如何在该仓库中安全地修改代码、运行测试、构建 Gem、本地启动扫描,并理解"动态 Finders"、Slug 分类、API 请求追踪等核心机制在源码中的真实实现。
项目概览:WPScan 是什么
WPScan 是一个用 Ruby 编写的 WordPress 安全扫描器,面向安全从业者与博客维护者,用于检测 WordPress 站点的漏洞、枚举资产并执行口令攻击。根据 AGENTS.md 与 wpscan.gemspec,它具备以下关键特征:
- Ruby Gem + CLI 工具:
wpscan.gemspec中声明了可执行文件wpscan,要求 Ruby 版本>= 3.3,依赖activesupport、typhoeus、nokogiri等核心库; - MVC 式架构:由 Controllers(编排)、Finders(检测策略)、Models(领域对象)三层构成;
- 本地数据库驱动:漏洞与指纹数据存放在本地(
$XDG_CACHE_HOME/wpscan/db、~/.cache/wpscan/db或旧版~/.wpscan/db),并通过wpscan --update与 WPScan API 同步; - 扫描框架与 WordPress 专用代码共存:通用扫描框架位于
lib/wpscan/(Target、Browser、Controller::Base、Scan、Finders、Formatter 等),WordPress 特定行为通过模块混入(mixin)实现,例如WPScan::Target::Platform::WordPress被 include 进WPScan::Target(见 lib/wpscan/target.rb)。
环境搭建与开发命令
安装依赖
bundle install运行测试
AGENTS.md 给出了完整的测试命令矩阵:
# 运行除慢测试外的全部测试(PR 默认) bundle exec rspec --tag ~slow # 运行完整测试套件(含慢测试,仅在 master 分支运行) bundle exec rspec # 运行指定测试文件 bundle exec rspec spec/path/to/file_spec.rb # 覆盖率默认开启(通过 .simplecov 配置) bundle exec rspec从 Rakefile 可以看到,rake spec任务本身也预设了--tag ~slow,与 PR 场景保持一致;完整套件只在 master 上执行。
代码质量检查(RuboCop)
项目使用 RuboCop 强制 Ruby 代码风格(配置见根目录.rubocop.yml):
# 运行 rubocop bundle exec rubocop # 自动修复 bundle exec rubocop -a # 仅对正在修改的文件执行(推荐) bundle exec rubocop -a path/to/file1.rb path/to/file2.rbAGENTS.md 特别强调:每次修改代码后必须运行 rubocop,这是合入 PR 的前置条件。
构建 Gem
# 构建 gem(会自动执行 rubocop 与 rspec) bundle exec rake build # 本地安装 gem install pkg/wpscan-*.gemRakefile 中的实现印证了这一点:task build: exec,而exec数组在安装了rubocop/rake_task与rspec/core/rake_task时分别追加:rubocop与:spec——即构建前强制质量门禁。
本地运行 WPScan
# 从源码运行(在 git 仓库外执行,避免加载路径冲突) ruby -Ilib bin/wpscan --url https://example.com # 或安装为 gem 后直接运行 wpscan --url https://example.com数据库操作
# 更新本地数据库 wpscan --update数据库默认存放位置见 lib/wpscan.rb 的实现逻辑:若旧版路径~/.wpscan/db存在则沿用,否则使用$XDG_CACHE_HOME/wpscan/db(未设置XDG_CACHE_HOME时回落到~/.cache/wpscan/db)。测试套件则通过redefine_constant将DB_DIR覆盖为spec/fixtures/db/,避免污染真实缓存。
架构深度解析
入口点:bin/wpscan 与控制器链
CLI 入口为 bin/wpscan,其核心逻辑是用<<操作符把各控制器串成链条,再调用s.run:
WPScan::Scan.new do |s| s.controllers << WPScan::Controller::VulnApi.new << WPScan::Controller::CustomDirectories.new << WPScan::Controller::InterestingFindings.new << WPScan::Controller::WpVersion.new << WPScan::Controller::AuthenticatedInventory.new << WPScan::Controller::MainTheme.new << WPScan::Controller::Enumeration.new << WPScan::Controller::PasswordAttack.new << WPScan::Controller::Aliases.new s.run end各控制器职责如下:
| 控制器 | 职责 |
|---|---|
VulnApi | 漏洞数据所需的 API Token 设置 |
CustomDirectories | 自定义 wp-content/plugins 目录检测 |
InterestingFindings | 响应头分析、robots.txt、readme 文件等 |
WpVersion | WordPress 版本检测 |
AuthenticatedInventory | 已认证资产盘点(登录态下可枚举的信息) |
MainTheme | 当前启用主题检测 |
Enumeration | 插件、主题、用户等枚举(见 CLI 选项) |
PasswordAttack | 暴力破解攻击 |
Aliases | 处理遗留 CLI 选项 |
注意:Core控制器并非显式加入链中,而是由 lib/wpscan/scan.rb 的Scan#initialize通过controllers << WPScan::Controller::Core.new隐式插入链首,在before_scan阶段负责 Banner 展示、数据库更新、WordPress 站点识别与目标可用性检查。从 app/controllers/core.rb 可以看到,before_scan依次执行:输出 banner/help/version → 校验 API Token 冲突 → 按需更新数据库 → 设置 HTTP 缓存 → 检查目标可达性 → 加载服务器模块 → 确认站点是否为 WordPress。
扫描编排:Scan 与 Controllers
lib/wpscan/scan.rb 是扫描编排的核心:
Scan#initialize记录起始内存、捕获并脱敏命令行参数(mask_sensitive_arguments会隐藏--api-token、--http-auth、--proxy-auth、--cookie-string、--wp-auth、--enterprise-db-token等敏感值,防止日志泄露密钥);Scan#run在ensure块中保证即使出错也会 abort 未完成的请求并逆序执行after_scan(见 lib/wpscan/controllers.rb),确保统计信息在任何情况下都能输出;exit_hook根据扫描结果返回进程退出码:检测到漏洞时退出VULNERABLE,否则OK;参数错误、中断、标准错误分别映射到不同的WPScan::ExitCode常量(lib/wpscan/scan.rb)。
Finders:检测策略层
Finders 位于app/finders/,为各类 WordPress 组件实现多种检测策略(passive / aggressive / mixed)。AGENTS.md 列出的主要 Finder 类型与仓库目录一一对应:
WpVersion— 版本检测(app/finders/wp_version/,含 RSS/Atom generator、readme、唯一指纹等策略);MainTheme— 活动主题检测(app/finders/main_theme/,含首页/404 页 CSS 样式与 URL 匹配);Plugins/Themes— 插件、主题枚举(app/finders/plugins/、app/finders/themes/,含已知位置、首页/404 页 URL、WP JSON API 等策略);Users— 用户枚举(app/finders/users/,含作者 ID 暴力枚举、oEmbed/RSS/WP JSON API、Yoast SEO 作者站点地图等);InterestingFindings— 备份文件、调试日志、XML-RPC、robots.txt 等(app/finders/interesting_findings/);ConfigBackups/DbExports/Medias/Timthumbs— wp-config 备份、数据库导出、附件暴力枚举、Timthumb 脚本检测(app/finders/config_backups/等);Passwords— 登录认证机制(app/finders/passwords/,含 wp-login 与 XML-RPC)。
扫描框架侧(lib/wpscan/finders/)提供了UniqueFinder、SameTypeFinder、IndependentFinder等抽象基类,分别对应"每个组件只匹配一个结果"、"同类多策略聚合"与"独立无依赖检测"三种模式,WordPress 专用 Finder 通过继承这些基类获得通用能力。
Models:领域对象层
app/models/定义了扫描中涉及的领域模型:
WpItem— 插件/主题的基类(app/models/wp_item.rb);Plugin、Theme— 具体 WordPress 组件;WpVersion— 携带漏洞信息的 WordPress 版本;InterestingFinding及其子类(ConfigBackup、DbExport、Media、Timthumb、XMLRPC、Headers、RobotsTxt等)。
模型还负责调用 WPScan API 获取漏洞数据:WpVersion#vulnerabilities等逻辑最终路由到WPScan::DB::VulnApi,并受VulnerabilityFilter的过滤逻辑约束。
数据库层(lib/wpscan/db/)
Updater(lib/wpscan/db/updater.rb):同步本地数据库与 WPScan API。FILES常量定义了常规同步文件(metadata.json、wp_fingerprints.json、timthumbs-v3.txt、config_backups.txt、db_exports.txt、backup_folders.txt、dynamic_finders.yml、LICENSE、sponsor.txt),并会自动清理OLD_FILES中已废弃的旧文件;当设置了--enterprise-db-token时,额外从enterprise-data.wpscan.org下载wordpresses.json.gz、plugins.json.gz、themes.json.gz企业漏洞库压缩包(通过X-DB-JSON-AUTH请求头鉴权);VulnApi(lib/wpscan/db/vuln_api.rb):API 客户端,uri指向https://wpscan.com/api/v4/,get方法对 404/429 静默返回空结果、对 HTTP 错误最多重试 3 次;启用local_db时直接读取本地 gzip 漏洞库而不再请求 API;DynamicFinders(lib/wpscan/db/dynamic_finders/):根据数据库元数据(dynamic_finders.yml)自动生成 Finder,使版本检测策略完全数据驱动;Fingerprints:版本检测指纹(lib/wpscan/db/fingerprints.rb),对应wp_fingerprints.json。
重要模式
Scanner Framework 单类混入模式。通用框架类(WPScan::Target、WPScan::Browser、WPScan::Controller::{Base,Core}、WPScan::ParsedCli、WPScan::Vulnerability、WPScan::Model::{InterestingFinding,XMLRPC}等)均为统一类,不按框架/WordPress 分层拆分;WordPress 专有行为通过模块混入注入。例如 lib/wpscan/target.rb 中class Target < WebSite之后include Server::Generic与include Platform::WordPress。参数解析则委托给外部的opt_parse_validatorGem(lib/opt_parse_validator/)。
动态 Finders。WPScan::DB::DynamicFinders::Base(lib/wpscan/db/dynamic_finders/base.rb)定义了允许的动态 Finder 类:Comment、Xpath、HeaderPattern、BodyPattern、JavascriptVar、QueryParameter、ConfigParser。以 lib/wpscan/db/dynamic_finders/plugin.rb 为例,finder_configs按 passive/aggressive 区分:passive 模式选用path为 nil 的配置(无需额外请求),aggressive 模式选用带path的配置(主动请求指定文件路径)。版本检测类动态 Finder(Finders::PluginVersion等)也由此系统驱动。
Slug 分类。WordPress 的插件/主题 slug 通过classify_slug助手(lib/wpscan/helper.rb)转换为 Ruby 类名,处理三类边界情况:
- 以数字开头的 slug 加
D_前缀(如123-plugin→D_123Plugin),因为 Ruby 类名不能以数字开头; - 特殊字符转为下划线;
- 全非拉丁字符的 slug 变成
HexSlug_加十六进制字节编码。
API 请求追踪。lib/wpscan.rb 通过全局Typhoeus.on_complete钩子统计total_requests、total_data_sent、total_data_received、cached_requests与api_requests(依据响应对象的from_vuln_api?判断),用于监控 WPScan API 使用量与限额,同时每次请求后调用WPScan::Browser.instance.trottle!进行请求节流。另外Typhoeus::Config.memoize = false用于规避 Hydra 的内存泄漏(对应 typhoeus#562)。
测试实践
测试结构
- 测试使用RSpec + WebMock做 HTTP 桩;
- Fixtures 位于
spec/fixtures/(包含动态 Finders、vuln_api、各 Finder 的响应样本、视图输出等); - 共享示例位于
spec/shared_examples/; - 覆盖率由 SimpleCov 提供(配置在
.simplecov)。
关键测试助手(spec/spec_helper.rb)
spec/spec_helper.rb 提供以下工具函数:
rspec_parsed_options(args)— 解析 CLI 参数(内部会实例化除Base外的全部控制器以收集选项,spec/spec_helper.rb#L74-L80);df_expected_all— 动态 Finder 测试期望(读取expected.yml);vuln_api_data_for(path)— 加载 vuln_api fixtures(spec/fixtures/db/vuln_api/下的 JSON);redefine_constant(constant, value)— 在测试中覆盖 WPScan 常量(如DB_DIR),实现隔离。
测试标签
--tag ~slow— 排除慢测试(CI 中 PR 默认);- 完整套件仅在 master 推送时运行。
WebMock 端口归一化
spec/spec_helper.rb中的 Typhoeus 适配器(约 spec/spec_helper.rb#L82-L96)对默认端口做了归一化处理:http 的 80 端口与 https 的 443 端口会被移除,以保证桩请求与实际请求 URL 一致——这是针对 WebMock/Typhoeus 兼容性的定制补丁(对应 bblimke/webmock#552)。
常见陷阱(Gotchas)
- Active Support 必须最先加载:
active_support/all必须在其他 Gem 之前 require,否则使用 JSON 格式时会出现编码问题,见 lib/wpscan.rb 顶部注释; - 源码运行要在 git 仓库外:
ruby -Ilib bin/wpscan时避免在仓库目录内执行,防止加载路径冲突; - 数据库位置:测试会通过
redefine_constant将DB_DIR覆盖为spec/fixtures/db/;生产环境按前述 XDG/legacy 规则决定; - API Token 冲突提前失败:
Core#before_scan在数据库更新前即调用VulnApi.validate_api_tokens!校验冲突 Token,避免在--update(不带--url)的场景下误下载企业漏洞库(见 app/controllers/core.rb)。
API 集成与配置
WPScan API
- 需要 API Token:通过
--api-token命令行参数、WPSCAN_API_TOKEN环境变量或配置文件提供; - 免费额度:25 次请求/天;
- 计费方式:每检测到一个 WordPress 版本、插件、主题消耗一次请求;
- 响应追踪:
Typhoeus.on_complete钩子统计请求量(lib/wpscan.rb),--vuln-api-status可查看剩余额度。
配置文件加载顺序
WPScan 按以下顺序加载选项(后者优先级更高,加载逻辑见 lib/wpscan/controllers.rb 的register_config_files):
$XDG_CONFIG_HOME/wpscan/scan.json或$XDG_CONFIG_HOME/wpscan/scan.yml(设置了XDG_CONFIG_HOME时);~/.config/wpscan/scan.json或~/.config/wpscan/scan.yml(未设置XDG_CONFIG_HOME时);~/.wpscan/scan.json或~/.wpscan/scan.yml;pwd/.wpscan/scan.json或pwd/.wpscan/scan.yml。
配置文件中 CLI 选项需使用snake_case命名,例如:
{ "api_token": "your-token", "max_threads": 10, "url": "https://example.com" }源码实现中option_parser.config_files.result_key = 'cli_options',且Controllers#run会先解析选项再按before_scan → run → after_scan顺序执行整个控制器链(lib/wpscan/controllers.rb)。
小结
AGENTS.md 是进入 WPScan 仓库协作开发的"操作手册":它定义了从依赖安装、测试、RuboCop、构建到架构认知的完整工作流。结合源码可以确认,仓库的扫描能力建立在一套清晰的 MVC 式分层(Controllers/Finders/Models)、数据驱动的动态 Finder 机制,以及"框架单类 + WordPress 模块混入"的设计之上。无论是人工维护者还是 AI Agent,遵循 AGENTS.md 中"改完必跑 rubocop、PR 默认跳过慢测试、注意加载顺序与数据库路径"等约定,即可安全高效地参与 WPScan 的迭代开发。
- 网络安全
- 漏洞扫描
- 渗透测试
- 应用安全
- CLI
【免费下载链接】wpscan
WPScan WordPress security scanner. Written for security professionals and blog maintainers to test the security of their WordPress websites. Contact us via contact@wpscan.com
相关推荐
Compiler Explorer 开发指南:面向 AI Agent 的仓库协作、构建测试与 SQS 编译工作线程架构解析
Compiler Explorer 开发指南:面向 AI Agent 的仓库协作、构建测试与 SQS 编译工作线程架构解析 本篇指南以仓库根目录 AGENTS.
后端前端开发工具Infer 仓库开发指南:面向 AI 编码代理的构建、测试与架构手册
Infer 仓库开发指南:面向 AI 编码代理的构建、测试与架构手册 本篇指南以仓库根目录的 AGENTS.md https://link.gitcode.co
静态分析代码质量开发工具Borg 2.x 仓库 AI 协作开发指南:分支策略、构建测试与架构速览(面向 Agent 与开发者)
Borg 2.x 仓库 AI 协作开发指南:分支策略、构建测试与架构速览(面向 Agent 与开发者) Borg 是采用压缩与认证加密的去重归档工具,本仓库当前
运维存储
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考