- 网络安全
- 漏洞扫描
- 渗透测试
- 应用安全
- 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
WPScan 通过"动态查找器"(dynamic finders)数据库从 WordPress 插件页面中自动提取版本号,而 spec/fixtures/dynamic_finders/plugin_version/monk/change_log/CHANGELOG.md 正是验证其中"ChangeLog"检测方式的典型测试固件:它是一份完整的 Monk 多语言插件更新日志。读完本文,你既能掌握 Monk 插件从 0.1.0 到 0.7.0 的完整版本演进脉络,又能理解 WPScan 是如何用一个正则表达式从 CHANGELOG 文件里解析出版本号并生成检测证据链的。
一、固件主体内容:Monk 插件 0.1.0 → 0.7.0 的完整版本史
该 CHANGELOG.md 记录了 WordPress 多语言插件 Monk(一款提供站点内容翻译、语言切换器、语言包自动下载等功能的多语言插件)的全部已知版本。以下按版本倒序完整继承原文档内容:
| 版本 | 主要变更 |
|---|---|
| 0.7.0 | 新增 hreflang 标签;新增后台按文章语言过滤评论功能;新增monk_get_translations函数,可用于自定义语言切换器;改写数据库查询以提升性能;修复静态首页 bug;修复自定义 meta 查询被覆盖的问题;修复旧版 PHP 激活插件时的语法错误;修复 terms 过滤按钮不显示的问题;修复打开"最后编辑"菜单时语言选项显示错误的问题 |
| 0.6.0 | 重构 Monk 设置页更新时的通知系统;改进 Language Switcher 组件的自定义器设置;新增 terms 语言过滤器;新增monk_custom_language_slug过滤器,允许用户自定义语言 slug |
| 0.5.2 | 修复文章从回收站恢复时的 bug;修复默认分类"english"翻译错误;修复文章/页面语言选择器选中"All languages"时的 bug |
| 0.5.1 | 修复媒体库更新流程中的 bug;改进后台控件的无障碍属性;修复某文章类型无文章时语言过滤器持续残留的问题 |
| 0.5.0 | 新增站点标题和描述翻译;新增获取翻译链接的 shortcode;新增"uncategorized"分类翻译;修复语言切换器中自定义分类法链接;修复文章编辑页媒体按语言过滤的问题 |
| 0.4.1 | 修复伪静态未启用时前端站点翻译的 bug;修复 Travis CI 警告;修复与get_current_screen函数调用的兼容性问题;修复 Language Switcher 组件中损坏的归档链接;修复日期归档链接 URL 中语言 slug 重复的问题;修复 term 编辑页链接携带错误分类法名称的问题 |
| 0.4.0 | 新增语言包自动下载;新增"默认语言 slug 是否出现在 URL 中"的选项;实现完整语言支持,可翻译到 100 多种语言;改进语言切换器 UI;修复"上一篇/下一篇"文章链接 |
| 0.3.1 | 优化整体链接结构;改进语言切换器组件;改进文本一致性;改进文章公共过滤器;修复日期和分类归档链接 |
| 0.3.0 | 新增菜单翻译支持;新增"Monk Love"致谢支持 |
| 0.2.0 | 改进后台和前台按语言过滤文章/terms 的查询;新增媒体翻译支持;将语言写入永久链接(permalinks) |
| 0.1.0 | 初始发布 |
从这份变更史可以看出几个与 WordPress 插件开发直接相关的技术细节:monk_custom_language_slug这类xxx_前缀命名是典型的 WordPress action/filter 钩子命名规范;monk_get_translations则是暴露给开发者用于构建自定义语言切换器的公共 API。0.4.0 版本引入"语言包自动下载 + 100 余种语言"是该插件功能跃升的分水岭。
需要强调的是:在 WPScan 仓库中,这份文件的身份并不是"产品文档",而是测试固件(fixture)——它模拟一个真实部署在wp-content/plugins/monk/CHANGELOG.md路径下的插件更新日志,用于验证 WPScan 的插件版本动态检测逻辑。
二、固件在仓库中的角色:monk 的动态查找器配置
WPScan 的动态查找器数据库位于 spec/fixtures/db/dynamic_finders.yml,其中monk条目(约第 79958 行起)声明了两种互补的版本检测策略:
monk: QueryParameter: files: - public/css/monk-public.css - public/css/monk-widget.css - admin/css/monk-flags.css - public/js/monk-public.js - public/js/monk-widget.js version: true ChangeLog: class: BodyPattern path: CHANGELOG.md pattern: !ruby/regexp /(?<v>\d+\.[\.\\d]+)/ version: true两条策略的分工是:
- QueryParameter(被动检测):不发出额外请求,只解析已抓取页面中插件静态资源 URL 的
?ver=x.y.z查询参数(如monk-public.css?ver=0.7.0); - ChangeLog(主动检测):使用
BodyPattern查找器类,主动请求CHANGELOG.md文件,并用正则/(?<v>\d+\.[\.\\d]+)/从响应体中提取第一个版本号。
对应的期望输出保存在 spec/fixtures/dynamic_finders/expected.yml(monk条目约在第 36630 行),测试运行时逐字段比对:
monk: QueryParameter: number: 0.7.0 found_by: Query Parameter (Passive Detection) interesting_entries: - http://wp.lab/wp-content/plugins/monk/public/css/monk-public.css?ver=0.7.0 # ... 其余 4 个带 ?ver=0.7.0 的资源 URL confidence: 50 ChangeLog: number: 0.7.0 found_by: Change Log (Aggressive Detection) interesting_entries: - 'http://wp.lab/wp-content/plugins/monk/CHANGELOG.md, Match: ''0.7.0'''两个查找器都收敛到同一个版本号0.7.0——这正是本固件中 Changelog 的第一个(最新)条目标题## [0.7.0]与?ver=0.7.0保持一致的原因:固件文件与期望输出必须互相吻合,测试才能通过。
三、源码原理:BodyPattern 查找器如何解析 CHANGELOG
真正执行"从 CHANGELOG 中抠版本号"动作的实现是 lib/wpscan/finders/dynamic_finder/version/body_pattern.rb:
# @param [ Typhoeus::Response ] response # @param [ Hash ] opts # @return [ Version ] def find(response, _opts = {}) return unless response.code != 404 && response.body =~ self.class::PATTERN create_version( Regexp.last_match[:v], interesting_entries: ["#{response.effective_url}, Match: '#{Regexp.last_match}'"] ) end逐行拆解这个流程,它解释了 expected.yml 中每一项输出的来源:
response.code != 404:目标文件必须真实存在,404 直接放弃检测;response.body =~ self.class::PATTERN:将响应体与配置中的命名捕获组正则/(?<v>\d+\.[\.\\d]+)/匹配。本固件第一行标题## Changelog之后首个符合\d+\.\d+...的串即0.7.0,命名组:v恰好捕获它,所以Regexp.last_match[:v]返回0.7.0;create_version(Regexp.last_match[:v], ...):用捕获的版本号构造Version模型(版本号语义校验由lib/wpscan/models/version.rb承担);interesting_entries:生成一条形如"<url>, Match: '<完整匹配文本>'"的证据字符串——这与 expected.yml 里'http://wp.lab/wp-content/plugins/monk/CHANGELOG.md, Match: ''0.7.0'''逐字对应。
插件场景下查找器类通过 lib/wpscan/finders/dynamic_finder/wp_item_version.rb 中的别名WpItemVersion::BodyPattern复用上述实现,即"查找器类名 + 目标项类型"决定了正则作用的对象是插件目录还是主题目录。此外,BodyPattern的默认置信度常量CONFIDENCE: 60(见 body_pattern.rb 第 12 行)会参与最终版本判定的置信度合并——同一插件多个查找器命中同一版本时,置信度会累加,因此 QueryParameter(默认基础置信度更低)与 ChangeLog 同时命中时,最终置信度显著高于单一来源。
四、这套固件与测试流程的实践价值
从源码结构看,这类固件的验证链路是:dynamic_finders.yml提供查找器配置(配置数据由 WPScan 社区维护并随版本更新)→ 扫描流程按配置对模拟站点wp.lab执行被动/主动检测 → 结果与expected.yml断言比对。这带来三点实战启示:
- 对安全评估者:理解"Passive Detection / Aggressive Detection"的区分——被动检测零额外请求、可在不增加站点负担的前提下完成;主动检测(如请求 CHANGELOG.md)覆盖面更广但会留下访问日志,扫描时应结合
--aggressive相关选项权衡; - 对插件开发者:若你的插件希望被 WPScan 正确识别版本,除
readme.txt外,保持 CHANGELOG 中版本号与静态资源?ver参数一致(如 monk 固件所做),能提高版本识别的准确性; - 对贡献者:新增或修正某插件的查找器配置时,需要在
spec/fixtures/db/dynamic_finders.yml声明查找器、在spec/fixtures/dynamic_finders/plugin_version/<slug>/下放置与配置匹配的固件内容,并同步更新expected.yml的期望输出,三者缺一不可。
五、小结
spec/fixtures/dynamic_finders/plugin_version/monk/change_log/CHANGELOG.md 是一份"双重身份"的文件:表面上是 Monk 多语言插件 0.1.0 至 0.7.0 的完整更新日志,实质上是 WPScan 动态查找器体系中"ChangeLog/BodyPattern"版本检测路径的标准测试固件。围绕它展开的三处仓库资产——查找器配置、期望输出 与 BodyPattern 实现——共同构成了一条从"正则匹配响应体"到"生成可审计证据链"的完整版本识别流水线,也是理解 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
相关推荐
WPScan 插件版本检测实战:以 get-the-image 的 changelog.md 为例解析 ChangeLog 动态查找机制
WPScan 插件版本检测实战:以 get the image 的 changelog.md 为例解析 ChangeLog 动态查找机制 导读 WordPres
网络安全漏洞扫描渗透测试应用安全CLIWPScan 插件版本检测实战:以 ACF Options for Polylang 的 CHANGELOG.md 为指纹案例
WPScan 插件版本检测实战:以 ACF Options for Polylang 的 CHANGELOG.md 为指纹案例 WPScan 作为 WordPr
网络安全漏洞扫描渗透测试应用安全CLI深度解析 WPScan ChangeLog 动态版本探测:以 adblock-notify-by-bweb 插件 CHANGELOG.md 为例
深度解析 WPScan ChangeLog 动态版本探测:以 adblock notify by bweb 插件 CHANGELOG.md 为例 WPScan
网络安全漏洞扫描渗透测试应用安全CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考