本文还有配套的精品资源,点击获取
简介:专为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 hash658f2dae9b937b062341635881c216dcfc887f68),它比当前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 enabledwpscan会自动将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访问受限或需快速部署扫描能力的渗透测试场景。
本文还有配套的精品资源,点击获取