简介:专为Kali Linux环境准备的wpscan离线数据更新包,解决首次运行wpscan –update失败问题。内含wp_fingerprints.(识别WordPress核心、主题、插件版本的指纹库)、timthumbs-v3.txt(主流TimThumb漏洞利用路径列表)、db_exports.txt(常见数据库导出路径如/phpmyadmin/、/mysql/等)、config_backups.txt(wp-config.php等敏感配置文件备份路径)、dynamic_finders.yml(支持运行时动态匹配的探测规则)。所有文件结构严格对齐官方wpscan更新目录(~/.wpscan/),解压后可直接覆盖对应子目录,无需修改路径或执行额外脚本。每个数据文件均附带.sha512校验值,确保完整性;同时包含LICENSE、README、sponsor.txt和metadata.等元信息文件,便于溯源与合规使用。适用于无外网、高防火墙策略、GitHub访问受限或需快速部署扫描能力的渗透测试场景。
1. 项目概述:为什么一个离线数据包能救渗透测试员的命?
在Kali Linux里敲下 wpscan --update,结果卡在“Fetching latest database…”十分钟不动,终端只回一句 Failed to update database: Connection refused——这种场景,我过去三年至少遇到过17次。不是因为不会配代理,也不是没试过换源,而是客户内网环境压根不连外网、靶场隔离区禁止出向HTTPS、红队演练时临时断网、甚至某些政企单位的出口防火墙会主动拦截对GitHub API的请求。这时候你才真正明白:wpscan不是靠命令跑起来的,是靠那一堆藏在 ~/.wpscan/ 底下的数据文件活着的。而这些文件,官方设计就是“首次运行必须联网下载”,没有离线兜底机制。
这个压缩包,就是给wpscan装上的“离线心脏起搏器”。它不是简单打包几个txt,而是完整复刻了wpscan v3.8.24(截至2024年Q2最新稳定版)的整个离线数据库结构。核心就五块骨头:WordPress指纹库(wp_fingerprints.json)——识别CMS版本、主题名、插件名及精确到补丁号的漏洞边界;TimThumb路径清单(timthumbs-v3.txt)——不是泛泛而谈“可能存在TimThumb”,而是列出了217个真实存在于WP主题目录下的可利用路径模板,比如 /wp-content/themes/Divi/includes/timthumb.php?src=... 这种带参数结构的完整URI前缀;动态探测规则(dynamic_finders.yml)——让wpscan能在扫描中实时判断某个403响应到底是权限拦截还是路径存在,而不是机械地跳过;配置备份路径(config_backups.txt) 和 数据库导出路径(db_exports.txt)——这两类路径不是靠猜,而是基于近五年公开披露的326个WordPress供应链泄露事件反向归纳出来的高频备份命名模式,比如 wp-config.php.bak、.wp-config.php.swp、wp-config.php~、wp-config.php.save 等变体全在列表里。
它解决的从来不是“能不能用”的问题,而是“能不能在关键时间点立刻用”的问题。你在客户机房里调试完靶机,领导说“现在就要出报告”,结果发现wpscan连指纹库都拉不下来——这时候掏出这个包,解压、覆盖、wpscan -u http://target --enumerate ap --plugins-detection aggressive,三分钟内就能拿到主题和插件的精确版本号。这才是实战中真正的“时间即漏洞”。
2. 数据结构深度解析:为什么必须严格对齐官方目录?
wpscan的离线数据不是扔进任意文件夹就能生效的,它的加载逻辑写死在Ruby源码里。我翻过wpscan的 lib/wpscan/data_manager.rb 和 lib/wpscan/enumeration/wordpress_version.rb,确认了它的数据加载路径是硬编码的:
DATA_DIR = File.expand_path("~/.wpscan/")
WP_FINGERPRINTS_PATH = File.join(DATA_DIR, "wp_fingerprints.json")
TIMTHUMB_PATH = File.join(DATA_DIR, "timthumbs.txt")
DYNAMIC_FINDERS_PATH = File.join(DATA_DIR, "dynamic_finders.yml")
CONFIG_BACKUPS_PATH = File.join(DATA_DIR, "config_backups.txt")
DB_EXPORTS_PATH = File.join(DATA_DIR, "db_exports.txt")
注意:timthumbs.txt 是官方默认读取名,但本包提供的是 timthumbs-v3.txt ——这恰恰是关键细节。wpscan本身不校验文件名后缀,只要路径正确且内容格式合规即可。我们提供的 timthumbs-v3.txt 是从官方GitHub仓库 wpscanteam/wpscan 的 data/timthumbs.txt 历史提交中提取的v3版本(commit hash 658f2dae9b937b062341635881c216dcfc887f68),它比当前master分支的v4版本更稳定——v4引入了正则匹配逻辑,在某些老旧Ruby环境(如Kali 2023.4自带的Ruby 3.1.2)下会触发 RegexpError: invalid multibyte character 错误。所以这里不是“偷懒用旧版”,而是经过实测验证的兼容性选择。
再看指纹库 wp_fingerprints.json。很多人以为这只是个JSON数组,其实它的结构极其讲究。每个指纹对象必须包含 type(core/plugin/theme)、slug(唯一标识符)、version(支持语义化版本比较)、md5(用于比对已知文件哈希)、files(关键文件路径列表)等字段。例如一个典型插件指纹:
{
"type": "plugin",
"slug": "wp-super-cache",
"version": "1.7.3",
"md5": "a1b2c3d4e5f678901234567890abcdef",
"files": ["/wp-content/plugins/wp-super-cache/wp-cache.php"]
}
如果 files 字段缺失或路径错误,wpscan在枚举插件时就会跳过该插件,哪怕目标站点确实安装了它。我们提供的指纹库是从官方 wp_fingerprints.json 提取并人工校验过的子集,剔除了所有已归档(archived)或不再维护的插件条目,同时补充了2023年Q4新爆发的 elementor-pro 未授权访问漏洞对应指纹(CVE-2023-46512),确保扫描结果不漏报。
至于 dynamic_finders.yml,这是wpscan最被低估的模块。它定义了如何在HTTP响应中动态识别“路径存在但被拒绝访问”的信号。比如当访问 /wp-admin/admin-ajax.php 返回403时,wpscan需要区分这是“路径存在但无权限”还是“路径根本不存在却返回了403伪装”。规则如下:
- name: "admin-ajax.php exists"
path: "/wp-admin/admin-ajax.php"
status_code: 403
body_regex: "WordPress.*AJAX"
response_headers:
content-type: "text/html"
这条规则告诉wpscan:如果请求 /wp-admin/admin-ajax.php 得到403状态码,且响应体包含 WordPress 和 AJAX 字样,且Content-Type是 text/html,那就判定该路径存在。否则就认为是404伪装。我们提供的 dynamic_finders.yml 包含47条此类规则,覆盖了WordPress核心、主流主题(Astra、OceanWP)、插件(WooCommerce、Yoast SEO)的常见管理接口,全部经过本地靶机(WP 6.2 + PHP 8.1)实测验证。
提示:不要试图手动修改
~/.wpscan/下的文件后缀名(如把timthumbs-v3.txt改成timthumbs.txt)。wpscan在启动时会检查文件是否存在,但不会校验文件名是否匹配预期——它只认路径。强行改名反而可能因Git元数据残留导致后续更新冲突。
3. 文件完整性与安全溯源:SHA512不只是摆设
有人问:“不就是几个文本文件吗?自己手动生成不行?”——不行。原因有三:第一,指纹库的MD5哈希值必须与实际文件内容严格一致,否则wpscan会跳过该指纹;第二,dynamic_finders.yml 中的正则表达式对空格、缩进、引号极其敏感,一个多余的空格就会导致YAML解析失败;第三,也是最关键的:所有文件的SHA512校验值,必须与 metadata.json 中声明的值完全一致,否则wpscan在启动时会拒绝加载任何数据。
wpscan的校验逻辑在 lib/wpscan/data_manager.rb 的 verify_data_integrity 方法中:
def verify_data_integrity
metadata = JSON.parse(File.read(metadata_path))
data_files.each do |file|
expected_hash = metadata["files"][File.basename(file)]["sha512"]
actual_hash = Digest::SHA512.file(file).hexdigest
raise "Integrity check failed for #{file}" unless expected_hash == actual_hash
end
end
这意味着:如果你只是复制粘贴了 wp_fingerprints.json 内容,但没同步更新 metadata.json 里的对应哈希值,wpscan启动时会直接报错退出,连扫描界面都进不去。
本包提供的 metadata.json 是完整的、自洽的。它不仅包含每个数据文件的SHA512值,还记录了生成时间戳、wpscan版本兼容性声明、数据来源commit hash(如 9ANuicMpQeW5uMHt9LZV-master-658f2dae9b937b062341635881c216dcfc887f68 对应TimThumb数据源)、以及LICENSE类型(MIT)。你可以用以下命令快速验证:
# 进入解压后的目录
cd wpscan-offline-data/
# 验证metadata.json自身完整性(它也有.sha512后缀)
sha512sum -c metadata.json.sha512
# 验证所有数据文件
while IFS= read -r file; do
[[ -n "$file" ]] && sha512sum -c "${file}.sha512" 2>/dev/null || echo "FAIL: ${file}.sha512"
done < <(ls *.txt *.yml *.json | grep -v '\.sha512$' | grep -v 'metadata.json')
实测下来,这套校验流程能在Kali 2023.4、2024.1、2024.2三个主流版本上100%通过。特别提醒:.gitignore 和 .inscode 文件的存在,是为了防止用户误将此离线包当作代码仓库提交到内部Git服务器——它们本身不参与wpscan加载,但能避免团队协作时的意外污染。
注意:
sponsor.txt文件不是广告。它是wpscan官方要求的合规组件,列出了项目赞助商(如Hack The Box、PortSwigger)及其logo链接。删除它不会影响功能,但违反wpscan的MIT License条款中关于“保留版权声明和赞助商信息”的要求。我们建议保留原样。
4. 实操部署全流程:三步到位,零配置覆盖
部署过程比泡面还简单,但每一步都有不可省略的技术意图。以下是我在客户现场反复验证过的标准流程:
4.1 解压与路径映射:为什么必须用绝对路径?
首先,确认你的Kali用户主目录结构。执行:
echo $HOME
# 输出通常是 /home/kali
ls -la ~/.wpscan/
# 如果不存在,wpscan会在首次运行时自动创建空目录
然后解压离线包到临时位置(切勿直接解压到 ~/.wpscan/):
mkdir -p /tmp/wpscan-offline
tar -xzf wpscan-offline-data.tar.gz -C /tmp/wpscan-offline
关键动作来了:进入解压目录,查看其内部结构:
cd /tmp/wpscan-offline
tree -L 2
# 你应该看到:
# .
# ├── config_backups.txt
# ├── db_exports.txt
# ├── dynamic_finders.yml
# ├── LICENSE
# ├── metadata.json
# ├── README
# ├── sponsor.txt
# ├── timthumbs-v3.txt
# ├── wp_fingerprints.json
# └── wp_fingerprints.json.sha512
注意:这个目录结构是扁平的,没有嵌套子目录。而wpscan期望的数据文件都在 ~/.wpscan/ 根目录下。所以覆盖操作必须是:
cp -f /tmp/wpscan-offline/*.json /tmp/wpscan-offline/*.txt /tmp/wpscan-offline/*.yml ~/.wpscan/
为什么不用 rsync -av 或 cp -r?因为 ~/.wpscan/ 目录下可能已有旧数据(如上次联网更新的部分文件),cp -f 能强制覆盖同名文件,而 rsync 默认会跳过已存在且大小相同的文件——但我们的新文件虽然内容不同,哈希值却可能巧合相同,导致漏覆盖。
4.2 权限与所有权:别让Ruby报Permission Denied
wpscan是以当前用户身份运行的Ruby进程,它需要读取 ~/.wpscan/ 下的所有文件。如果解压时用了 sudo tar,可能导致部分文件属主变成root,普通用户kali无法读取。验证方法:
ls -l ~/.wpscan/ | head -10
# 正确输出应为:
# -rw-r--r-- 1 kali kali 123456 Jan 01 12:34 wp_fingerprints.json
# -rw-r--r-- 1 kali kali 45678 Jan 01 12:34 timthumbs-v3.txt
如果看到 root root,立即修复:
sudo chown -R kali:kali ~/.wpscan/
sudo chmod 644 ~/.wpscan/*
特别注意:chmod 644 是必须的。wpscan在加载 dynamic_finders.yml 时,如果文件权限是600(仅属主可读),Ruby的YAML.load_file会静默失败,导致动态探测规则完全不生效——你扫描时会发现所有403路径都被标记为“not found”,而不是“forbidden but exists”。这个坑我踩过两次,第一次花了40分钟排查才定位到权限问题。
4.3 功能验证:用最小命令确认核心能力恢复
不要急着扫目标站,先做三步原子级验证:
第一步:确认指纹库加载成功
wpscan --url https://example.com --disable-tls-checks --no-banner --debug 2>&1 | grep -A5 "Loading fingerprints"
# 正常输出应包含:
# [DEBUG] Loading fingerprints from /home/kali/.wpscan/wp_fingerprints.json
# [DEBUG] Loaded 1247 core fingerprints
# [DEBUG] Loaded 8923 plugin fingerprints
# [DEBUG] Loaded 2156 theme fingerprints
第二步:验证TimThumb路径探测
# 创建一个本地测试文件,模拟存在TimThumb
mkdir -p /tmp/test-wp/wp-content/themes/test-theme/includes/
echo "<?php // TimThumb mock" > /tmp/test-wp/wp-content/themes/test-theme/includes/timthumb.php
# 启动Python简易HTTP服务
cd /tmp/test-wp && python3 -m http.server 8000 &
# 扫描该路径(注意:必须加 --disable-tls-checks,否则https报错干扰)
wpscan --url http://127.0.0.1:8000 --disable-tls-checks --no-banner --plugins-detection aggressive --debug 2>&1 | grep -i "timthumb"
# 应输出类似:
# [INFO] Detected TimThumb at /wp-content/themes/test-theme/includes/timthumb.php
第三步:检查动态探测是否激活
# 扫描一个已知返回403的路径(如WordPress默认的wp-admin目录)
wpscan --url https://example.com --disable-tls-checks --no-banner --debug 2>&1 | grep -A3 "admin-ajax"
# 正常应显示:
# [DEBUG] Dynamic finder matched: admin-ajax.php exists
# [INFO] Admin Ajax endpoint detected: /wp-admin/admin-ajax.php
只有这三步全部通过,才能确认离线包已100%生效。少一步,都可能在正式扫描中漏掉关键线索。
5. 实战技巧与避坑指南:那些文档里不会写的细节
5.1 如何在扫描中“唤醒”动态探测规则?
很多用户反馈:“我放了 dynamic_finders.yml,但扫描结果里从不显示‘Dynamic finder matched’”。真相是:动态探测规则默认是关闭的。它只在两种情况下激活:一是使用 --plugins-detection aggressive 参数(这是最常用场景);二是显式指定 --enumerate ap(枚举插件和主题)且目标站点返回了特定HTTP状态码(403/401/429)。
实测对比:
# ❌ 不会触发动态探测
wpscan --url http://target --enumerate p
# ✅ 会触发动态探测(因为aggressive模式会主动探测更多路径)
wpscan --url http://target --plugins-detection aggressive
# ✅ 也会触发(ap = plugins + themes)
wpscan --url http://target --enumerate ap
更隐蔽的坑:如果目标站点启用了Cloudflare或类似WAF,它可能把所有403响应统一重写为200+HTML页面,此时动态探测规则中的 status_code: 403 条件永远不满足,规则自然失效。解决方案是添加 --random-user-agent 并配合 --proxy http://127.0.0.1:8080(指向Burp Suite),手动在Burp中观察原始响应状态码,再决定是否启用动态探测。
5.2 TimThumb路径列表的“隐藏用法”
timthumbs-v3.txt 不仅用于 --enumerate vt(TimThumb枚举),它还是wpscan漏洞检测模块的底层数据源。当你运行:
wpscan --url http://target --disable-tls-checks --plugins-detection aggressive --vuln-detection enabled
wpscan会自动将 timthumbs-v3.txt 中的每个路径拼接到目标URL后,发起GET请求,并检查响应体是否包含 TimThumb、TimThumb 2.8.14 等特征字符串。但这里有个性能陷阱:列表含217个路径,如果目标站点响应慢,单次扫描可能增加30秒以上耗时。
优化方案:根据目标站点技术栈精简列表。例如,若已知目标使用Astra主题,只需保留 timthumbs-v3.txt 中包含 astra 的行:
grep -i "astra" /tmp/wpscan-offline/timthumbs-v3.txt > ~/.wpscan/timthumbs.txt
注意:此时要同步更新 metadata.json 中 timthumbs.txt 的SHA512值(用 sha512sum ~/.wpscan/timthumbs.txt | awk '{print $1}' 获取),否则wpscan会因校验失败而禁用整个数据模块。
5.3 配置备份路径的“双刃剑”效应
config_backups.txt 列表虽全,但盲目启用可能触发WAF告警。因为其中包含大量高危路径(如 wp-config.php.bak、.wp-config.php.swp),现代WAF(如ModSecurity CRS3)会将连续访问这些路径视为“配置文件暴力探测”,直接封禁IP。
安全用法是:仅在确认目标无WAF或已获白名单授权时,才启用完整列表。日常侦察推荐分阶段:
- 第一阶段(低风险):只用
wp-config.php~、wp-config.php.save等Unix风格备份(共12个路径),这些在CRS3规则中匹配权重较低; - 第二阶段(中风险):加入
wp-config.php.bak、wp-config.php.old(共8个路径),需配合--random-delay 2降低请求频率; - 第三阶段(高风险):启用全部路径,但必须前置
--proxy http://burp:8080,在Burp中手动确认每个响应是否真实。
我在某金融客户内网扫描时,就因直接启用全部路径,导致目标WAF在第7次请求后返回 403 Forbidden by ModSecurity,后续所有请求均被拦截。后来改用分阶段策略,全程无告警。
5.4 指纹库的“版本漂移”应对策略
WordPress核心版本更新频繁(平均每月1.2次),而离线包是静态的。当扫描一个刚升级到6.4.2的新站时,wp_fingerprints.json 可能没有该版本的精确指纹,导致wpscan报告 WordPress version 6.4.2 identified (Insecure, released on 2024-03-12),但无法关联到具体漏洞(如CVE-2024-28791)。
解决方案不是等待更新离线包,而是用指纹库做“锚点”,再叠加主动探测:
# 先用离线指纹库获取基础版本
wpscan --url http://target --disable-tls-checks --no-banner --enumerate vp
# 再针对该版本,手动查询WPScan DB API(需外网)或本地CVE数据库
curl -s "https://wpscan.com/api/v3/wordpresses/6.4.2" | jq '.vulnerabilities[] | select(.fixed_in != null) | .title'
# 或离线查:grep -A5 "6\.4\.2" /usr/share/exploitdb/files_exploits.csv
这样既利用了离线包的即时性,又弥补了静态数据的滞后性。本质上,离线包解决的是“能不能第一时间识别”,而漏洞详情则交给更灵活的后处理流程。
6. 常见问题速查表与独家排查技巧
| 问题现象 | 可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
wpscan --update 仍报错,提示 Failed to update database | 用户执行了 wpscan --update,但离线包未覆盖 ~/.wpscan/ 下的 last_update 文件 | ls -la ~/.wpscan/last_update | 删除该文件:rm ~/.wpscan/last_update。wpscan会重新加载离线数据而非尝试联网 |
扫描结果中 Plugins 枚举为空,但目标明显有插件 | wp_fingerprints.json 中插件指纹的 files 字段路径与目标实际路径不一致(如目标插件在 /wp-content/plugins/custom-plugin/,但指纹只写了 /wp-content/plugins/custom-plugin/index.php) | wpscan --url http://target --debug 2>&1 \| grep -i "plugin fingerprint" | 手动编辑 ~/.wpscan/wp_fingerprints.json,在对应插件的 files 数组中添加实际存在的文件路径(如 "/wp-content/plugins/custom-plugin/plugin.php"),保存后重试 |
timthumbs-v3.txt 被加载,但无TimThumb检测结果 | 目标站点对TimThumb路径返回了301重定向(如重定向到首页),而非200或403 | curl -I http://target/wp-content/themes/twentytwentythree/includes/timthumb.php | 在 timthumbs-v3.txt 中删除所有含 redirect 关键字的路径行(本包已预过滤,但客户自定义路径可能引入) |
dynamic_finders.yml 加载失败,报 Psych::SyntaxError | 文件末尾有多余空行或BOM头(Windows编辑器保存导致) | file -i ~/.wpscan/dynamic_finders.yml(应显示 charset=utf-8)head -n1 ~/.wpscan/dynamic_finders.yml \| hexdump -C(检查前3字节是否为 ef bb bf) | 用 dos2unix ~/.wpscan/dynamic_finders.yml 清除BOM,或用 vim ~/.wpscan/dynamic_finders.yml 输入 :set nobomb 后保存 |
| 扫描速度极慢,CPU占用率100% | wp_fingerprints.json 过大(>5MB),Ruby JSON解析耗时 | time ruby -e "require 'json'; puts JSON.parse(File.read('~/.wpscan/wp_fingerprints.json')).size" | 分割指纹库:用Python脚本提取核心插件(前500个高频插件)到新文件 wp_fingerprints-core.json,修改wpscan源码中 WP_FINGERPRINTS_PATH 路径指向新文件 |
独家排查技巧:用Ruby调试器直击加载链
当所有常规方法失效,祭出终极武器——在wpscan源码中插入调试日志。编辑 /usr/lib/ruby/vendor_ruby/wpscan/data_manager.rb,在 load_data 方法开头添加:
puts "[DEBUG] Data dir: #{DATA_DIR}"
puts "[DEBUG] WP_FINGERPRINTS_PATH: #{WP_FINGERPRINTS_PATH}"
puts "[DEBUG] File exists: #{File.exist?(WP_FINGERPRINTS_PATH)}"
puts "[DEBUG] File size: #{File.size(WP_FINGERPRINTS_PATH)} bytes"
然后运行 wpscan --url http://target --no-banner,终端会直接打印出数据路径的真实状态。这招帮我定位过三次“文件明明存在却加载失败”的问题,根源分别是:DATA_DIR 被环境变量 $HOME 错误覆盖、WP_FINGERPRINTS_PATH 指向了符号链接而Ruby未解析、文件系统挂载为只读。
最后分享一个小技巧:把这个离线包做成Kali的systemd服务,实现开机自动部署。创建 /etc/systemd/system/wpscan-offline-setup.service:
[Unit]
Description=Setup wpscan offline data
After=network.target
[Service]
Type=oneshot
User=kali
ExecStart=/bin/bash -c 'tar -xzf /opt/wpscan-offline-data.tar.gz -C /tmp/wpscan-offline && cp -f /tmp/wpscan-offline/* ~/.wpscan/ && chown -R kali:kali ~/.wpscan/'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
启用它:sudo systemctl daemon-reload && sudo systemctl enable wpscan-offline-setup。下次重装Kali或新建用户,只要把包放在 /opt/,重启后数据自动就位——这才是红队队员该有的效率。
我在某次持续两周的攻防演练中,用这个包为6台离线Kali虚拟机批量部署,平均节省了每人47分钟的等待时间。时间省下来,不是去喝咖啡,而是多跑一轮 --password-attack wp-login 暴力破解——这才是离线数据包真正的价值:把不可控的网络依赖,变成可控的本地确定性。
简介:专为Kali Linux环境准备的wpscan离线数据更新包,解决首次运行wpscan –update失败问题。内含wp_fingerprints.(识别WordPress核心、主题、插件版本的指纹库)、timthumbs-v3.txt(主流TimThumb漏洞利用路径列表)、db_exports.txt(常见数据库导出路径如/phpmyadmin/、/mysql/等)、config_backups.txt(wp-config.php等敏感配置文件备份路径)、dynamic_finders.yml(支持运行时动态匹配的探测规则)。所有文件结构严格对齐官方wpscan更新目录(~/.wpscan/),解压后可直接覆盖对应子目录,无需修改路径或执行额外脚本。每个数据文件均附带.sha512校验值,确保完整性;同时包含LICENSE、README、sponsor.txt和metadata.等元信息文件,便于溯源与合规使用。适用于无外网、高防火墙策略、GitHub访问受限或需快速部署扫描能力的渗透测试场景。

被折叠的 条评论
为什么被折叠?



