mcpField
W
wp-plugin-cve-hunt

wp-plugin-cve-hunt

github.com/uphiago安全1.3k41 次安装8 周前更新
代码仓库

关于 wp-plugin-cve-hunt

wp-plugin-cve-hunt 是用于已知 WordPress 目标插件 CVE 研究的安全技能,结合多源版本提取、漏洞数据库交叉查询、人工验证规划和误报检查。

主要功能

  1. 01从多个来源提取版本
  2. 02交叉查询 WPScan、Patchstack 和 NVD
  3. 03将版本与受影响范围比较
  4. 04规划候选漏洞验证
  5. 05检查误报

适用场景

  1. 01研究已知 WordPress 目标上的插件 CVE
  2. 02测试前验证疑似漏洞
  3. 03调查 CVE 数据库中未收录的插件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/uphiago/recon-skills --skill wp-plugin-cve-hunt

安装后在 Claude Code 中输入/wp-plugin-cve-hunt确认已加载。

详细介绍

WP-PLUGIN-CVE-HUNT — WordPress 插件 CVE 系统化发现与利用

使用时机

在 WordPress 检测侦察已识别出一批装有已知插件的 WP 目标后使用。此技能不止于简单检查 readme.txt 版本,还会从多个来源提取版本信息、交叉查询 CVE 数据库、比较版本、评估漏洞并生成 PoC。适合手上有 10 个以上 WP 域名,并需要系统性地找出哪些特定插件 CVE 可被利用的场景。

与 wp-plugin-automation 的区别:此技能侧重于人工引导的 CVE 研究流程,包括集成 WPScan API、查询 Patchstack 数据库、交叉查询 NVD、调查 CVE 详情以及手动验证 PoC。wp-plugin-automation 则负责在数百个域名上运行批量扫描流程。

快速参考

# Quick CVE scan for a single target
TARGET="example.com"

# 1. List plugins via readme.txt
for p in elementskit revslider elementor woocommerce gravityforms jetpack wp-file-manager wordpress-seo give contact-form-7; do
  v=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-content/plugins/$p/readme.txt" 2>/dev/null | grep -i "stable tag\|version" | head -1)
  [ -n "$v" ] && echo "PLUGIN: $p -> $v"
done

# 2. WPScan API query (requires API token)
wpscan --url "https://$TARGET" --api-token "$WPSCAN_TOKEN" --enumerate vp

# 3. Check specific CVE
curl --max-time 30 --connect-timeout 10 -sk "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2023-6853" | python3 -c "
import sys, json; d=json.load(sys.stdin)
vuln=d['vulnerabilities'][0]['cve']
print(f\"{vuln['id']}: {vuln['descriptions'][0]['value']}\")
print(f\"CVSS: {vuln['metrics']['cvssMetricV31'][0]['cvssData']['baseScore']}\")
"

分步操作

阶段 1 — 插件发现与多源版本提取

不要只依赖 readme.txt——插件可能会在多个位置隐藏版本信息:

#!/bin/bash
# multi-source-version.sh — Extract plugin version from multiple sources
TARGET="$1"
PLUGIN="$2"        # e.g., elementskit
PLUGIN_DIR="$3"    # e.g., elementskit-lite (can differ from slug)

# Source 1: readme.txt (most common)
v1=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-content/plugins/$PLUGIN_DIR/readme.txt" 2>/dev/null | \
  grep -i "stable tag\|version" | head -1 | grep -Eo '[\d.]+')
echo "Source 1 (readme.txt): $v1"

# Source 2: Main plugin PHP header
v2=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-content/plugins/$PLUGIN_DIR/$PLUGIN.php" 2>/dev/null | \
  grep -Eo 'Version:\s*\K[\d.]+')
echo "Source 2 (plugin header): $v2"

# Source 3: CSS/JS asset paths (many plugins version their assets)
v3=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/" 2>/dev/null | \
  grep -Eo "$PLUGIN_DIR/.*?ver=([\d.]+)" | grep -Eo '[\d.]+\b' | sort -uV | tail -1)
echo "Source 3 (asset version): $v3"

# Source 4: REST API namespace (some plugins include version in namespace)
v4=$(curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/" 2>/dev/null | \
  python3 -c "import sys,json; [print(n.split('/')[1]) for n in json.load(sys.stdin).get('namespaces',[]) if '$PLUGIN' in n and '/' in n]" 2>/dev/null)
echo "Source 4 (REST namespace): $v4"

# Deduplicate to most reliable version
echo "=== BEST VERSION ==="
for src in "$v1" "$v2" "$v3"; do
  if [ -n "$src" ]; then
    echo "$src"
    break
  fi
done
阶段 2 — 交叉查询 CVE 数据库
#!/bin/bash
# cve-lookup.sh — Query multiple CVE sources for a plugin

# Method 1: WPScan API (requires token)
curl --max-time 30 --connect-timeout 10 -sk "https://wpscan.com/api/v3/plugins/$PLUGIN" \
  -H "Authorization: Token token=$WPSCAN_TOKEN" | python3 -c "
import sys, json
d = json.load(sys.stdin)
for vuln in d.get('vulnerabilities', []):
    print(f\"{vuln.get('cve', 'no-cve')}: {vuln.get('title', '')} ({vuln.get('fixed_in', 'unpatched')})\")
" 2>/dev/null

# Method 2: NVD API (no token required)
curl --max-time 30 --connect-timeout 10 -sk "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=$PLUGIN&keywordExactMatch" | python3 -c "
import sys, json
d = json.load(sys.stdin)
for vuln in d.get('vulnerabilities', []):
    cve = vuln['cve']
    vid = cve['id']
    desc = cve['descriptions'][0]['value'][:200] if cve['descriptions'] else ''
    try:
        score = cve['metrics']['cvssMetricV31'][0]['cvssData']['baseScore']
    except:
        score = 'N/A'
    print(f'{vid} (CVSS:{score}): {desc}')
" 2>/dev/null

# Method 3: Patchstack database
curl --max-time 30 --connect-timeout 10 -sk "https://patchstack.com/database/search/?s=$PLUGIN" | \
  python3 -c "
import sys, re
content = sys.stdin.read()
cves = re.findall(r'CVE-\d{4}-\d{4,7}', content)
print(f'Patchstack CVEs: {cves}')
" 2>/dev/null
阶段 3 — 版本比较与漏洞评估
#!/bin/bash
# vuln-assess.sh — Compare installed version against known vulnerable ranges

compare_version() {
  local current="$1" fixed="$2" plugin_name="$3" cve="$4" severity="$5"
  if [ -n "$current" ] && [ -n "$fixed" ]; then
    if [ "$(printf '%s\n' "$fixed" "$current" | sort -V | head -1)" != "$fixed" ] && \
       [ "$current" != "$fixed" ]; then
      echo "[VULN] $plugin_name ($current) < $fixed → $cve ($severity)"
    elif [ "$current" = "$fixed" ]; then
      echo "[OK] $plugin_name ($current) = $fixed (patched for $cve)"
    else
      echo "[OK] $plugin_name ($current) >= $fixed (patched for $cve)"
    fi
  fi
}

# ElementsKit
compare_version "$ELEMENTS_KIT_VER" "2.9.4" "ElementsKit" "CVE-2023-6851/CVE-2023-6853" "CRITICAL"
compare_version "$ELEMENTS_KIT_VER" "2.9.8" "ElementsKit" "CVE-2024-2117" "MEDIUM"

# Slider Revolution
compare_version "$REVSLIDER_VER" "6.6.20" "Revslider" "CVE-2024-2534" "CRITICAL"
compare_version "$REVSLIDER_VER" "6.5.8" "Revslider" "CVE-2022-2944" "HIGH"
compare_version "$REVSLIDER_VER" "6.5.11" "Revslider" "CVE-2022-9821" "MEDIUM"

# WPDM
compare_version "$WPDM_VER" "3.3.00" "WPDM" "CVE-2023-49753" "CRITICAL"
compare_version "$WPDM_VER" "3.2.00" "WPDM" "CVE-2021-25069" "HIGH"

# Gravity Forms
compare_version "$GF_VER" "2.8.2" "GravityForms" "CVE-2024-6115" "HIGH"

# Jetpack
compare_version "$JETPACK_VER" "13.1" "Jetpack" "CVE-2024-1782" "HIGH"

# Contact Form 7
if [ -n "$CF7_VER" ] && [ "$(printf '%s\n' "5.6" "$CF7_VER" | sort -V | head -1)" != "$CF7_VER" ] && \
   [ "$CF7_VER" != "5.6" ]; then
  echo "[VULN] Contact Form 7 ($CF7_VER) < 5.6 — File upload bypass"
fi
阶段 4 — 候选项验证规划
cat <<'PLAN'
Before a plugin PoC:
1. Confirm the exact installed version from two signals.
2. Confirm the affected route and authentication prerequisite.
3. Read the vendor advisory and patch diff.
4. Obtain explicit authorization for any upload, write, delay, or execution.
5. Use a synthetic object or inert artifact and define cleanup.
6. Record a negative control on the patched or unauthorized path.
PLAN
阶段 5 — 排除误报
# Check 1: Does readme.txt version match actual deployed version?
# Sometimes readme.txt is not updated but plugin PHP is patched
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-content/plugins/elementskit/elementskit.php" | grep "Version:"

# Check 2: Is the REST endpoint actually available (not disabled by WAF)?
curl --max-time 30 --connect-timeout 10 -sk -I "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file"

# Check 3: Is the vulnerable code path actually reachable?
# Some CVEs require specific plugin features to be enabled
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/elementskit/v1/" | python3 -m json.tool 2>/dev/null

# Check 4: Test exploitation in safe mode first — verify endpoint exists before running destructive payload
curl --max-time 30 --connect-timeout 10 -sk -X OPTIONS "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file" | head -20

# Check 5: Version from JS/CSS assets vs readme.txt — if they differ, plugin may be partially updated
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/" | grep -Eo 'elementskit.*?ver=[0-9.]+'
阶段 6 — 自定义 CVE 发现(0-day/未披露漏洞)
# When no CVE exists for a plugin, test these common patterns:

# 1. REST API route enumeration (undocumented endpoints)
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/$PLUGIN/v1/" | python3 -c "
import sys, json
try:
    d = json.load(sys.stdin)
    for route in d.get('routes', {}):
        print(f'  {route}')
except: pass
"

# 2. AJAX handler testing
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-admin/admin-ajax.php" -d "action=$PLUGIN_ajax_function"

# 3. SQLi in plugin shortcode attributes
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/?$PLUGIN_param=1' AND SLEEP(5)--"

# 4. File upload in plugin media handlers
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/$PLUGIN/v1/upload" -F "[email protected]"

# 5. IDOR in plugin REST endpoints (iterate IDs)
for id in $(seq 1 100); do
  curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/$PLUGIN/v1/data/$id" | jq '. | {id}' 2>/dev/null
done

攻击面信号

  • 可访问位于 /wp-content/plugins//readme.txt 的插件 readme.txt
  • HTML 源代码中可见插件资源版本(ver= 参数)
  • REST API 命名空间包含插件版本
  • WPScan 输出显示已知漏洞
  • 页面源代码中的管理通知横幅表明插件版本

CVE 矩阵(精选)

插件CVE类型修复版本严重程度
ElementsKitCVE-2023-6851, CVE-2023-6853SQLi + 文件上传2.9.4严重
ElementsKitCVE-2024-2117XSS2.9.8中
RevsliderCVE-2024-2534RCE6.6.20严重
RevsliderCVE-2022-2944SQLi6.5.8高
RevsliderCVE-2022-9821CSRF->XSS6.5.11中
WPDMCVE-2023-49753SQLi3.3.00严重
WPDMCVE-2021-25069未授权下载3.2.00高
WPDMCVE-2021-34639已认证文件上传3.2.10高
Gravity FormsCVE-2024-6115PHP 对象注入2.8.2高
Contact Form 7—文件上传绕过5.6高
JetpackCVE-2024-1782SSRF13.1高
WP Super Cache—调试日志泄露所有版本中
GSpeechCVE-2025-10187XSS7.2中
WooCommerce多个各类不定不定
Wordfence—防火墙绕过不适用信息

常见根本原因

  1. 插件自动更新已禁用 — 管理员为避免破坏网站自定义内容而关闭更新
  2. 已停止维护的插件 — 开发者不再维护,CVE 不断累积且没有补丁
  3. 盗版/高级插件 — 预算有限的网站上安装了带后门的盗版插件
  4. 插件臃肿 — 安装了 50 个以上插件,无法手动跟踪 CVE
  5. WPScan 漏报 — WPScan 数据库可能没有最新的 CVE;务必交叉核查
  6. 代理机构管理疏忽 — 代理机构建好网站后,交付后没有更新插件
  7. readme.txt 未更新 — 插件已打补丁,但 readme.txt 仍显示旧版本(存在误报风险)

验证

  1. WPScan 漏洞数据库 — 确认 WPScan 可以检查 CVE:
    wpscan --version 2>/dev/null && echo "PASS: wpscan available" || echo "NOTE: wpscan not installed"
    
  2. CVE 格式 — 确认可识别 CVE 格式:
    echo "CVE-2024-12345" | grep -qE "CVE-[0-9]{4}-[0-9]+" && echo "PASS: CVE format recognized" || echo "FAIL"
    

所有测试均用于验证 WP CVE 搜寻就绪状态。


注意事项

  • CVE 与版本不匹配 — CVE-2024-XXXX 影响“低于 2.5.0 的版本”。安装了该插件并不意味着存在漏洞。请核实确切版本。
  • 更新日志中提及已修复的 CVE — 如果更新日志写着“Fixed: CVE-2024-XXXX”,已安装的版本可能已包含补丁。请核对发布日期与版本。
  • 需要身份验证的 CVE — 许多 WordPress 插件 CVE 需要管理员权限。默认情况下,这类漏洞发生在身份验证之后,严重性较低。
  • NVD 数据滞后 — NVD 有待处理积压。请查阅 WPScan、Patchstack 和 Wordfence,获取更新的 CVE 数据。
  • 存在插件 CVE,但插件未启用 — 已安装但已停用的插件无法通过 Web 请求利用。请确认插件处于启用状态。

相关技能

  • hunt-wordpress — WordPress 检测和常规侦察的主要技能
  • wp-plugin-automation — 覆盖数百个域名的批量扫描管道
  • recon-sector — 特定行业的侦察(教会的插件漏洞率最高)
  • hunt-rce — 插件 CVE 是远程代码执行(RCE)的主要途径
  • hunt-file-upload — 插件漏洞导致的文件上传 CVE
  • hunt-sqli — 插件 SQL 注入漏洞导致的 SQL 注入 CVE
  • hunt-xss — 插件注入漏洞导致的跨站脚本(XSS)CVE
  • hunt-source-leak — debug.log 会暴露插件版本信息

评论

支持 Markdown