New vectors added: - 22: SSRF Proof — cloud metadata exfiltration (CRITICAL) - 23: Prototype Pollution — Node.js client/server (HIGH) - 24: WebSocket Hijack — WS origin bypass + injection (HIGH) - 25: Mass Assignment — protected field modification (HIGH) - 26: HTTP Parameter Pollution — WAF bypass (HIGH) - 27: Insecure Deserialization — PHP/Java/Node (CRITICAL) - 28: OAuth Takeover — redirect_uri / state / CSRF (CRITICAL) - 29: Web Cache Poisoning — unkeyed header injection (HIGH) - 30: CRLF Injection — HTTP response splitting (CRITICAL) All vectors PROVE exploitation by dumping data/credentials, not just detecting config issues.
318 lines
8.8 KiB
Bash
Executable File
318 lines
8.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ============================================================
|
|
# HUNTER — Mass Vulnerability Discovery Engine
|
|
# Part of The Analyzer
|
|
# Finds vulnerable websites at scale using OSINT + nuclei
|
|
# ============================================================
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ANALYZER_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
REPORTS_DIR="$ANALYZER_DIR/reports"
|
|
TARGETS_DIR="$ANALYZER_DIR/targets"
|
|
WORK_DIR="/tmp/analyzer-hunter"
|
|
NUCLEI_TEMPLATES="${NUCLEI_TEMPLATES:-$HOME/nuclei-templates}"
|
|
HTTPS="$HOME/go/bin/httpx"
|
|
|
|
mkdir -p "$WORK_DIR" "$REPORTS_DIR" "$TARGETS_DIR"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'; NC='\033[0m'
|
|
|
|
log() { echo -e "${BLUE}[*]${NC} $1"; }
|
|
ok() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
warn(){ echo -e "${YELLOW}[!]${NC} $1"; }
|
|
err() { echo -e "${RED}[✗]${NC} $1"; }
|
|
|
|
# ============================================================
|
|
# PHASE 1: TARGET DISCOVERY
|
|
# ============================================================
|
|
|
|
discover_from_tranco() {
|
|
local count="${1:-500}"
|
|
local output="$TARGETS_DIR/hunt_tranco.txt"
|
|
|
|
log "Fetching top $count sites from Tranco..."
|
|
curl -skL "https://tranco-list.eu/top-1m.csv.zip" -o "$WORK_DIR/top1m.zip" 2>/dev/null
|
|
|
|
if unzip -o "$WORK_DIR/top1m.zip" -d "$WORK_DIR" 2>/dev/null; then
|
|
head -"$count" "$WORK_DIR"/top-1m.csv 2>/dev/null | cut -d, -f2 > "$output"
|
|
ok "$(wc -l < "$output") domains from Tranco"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
discover_from_analyzer() {
|
|
local output="$TARGETS_DIR/hunt_analyzer.txt"
|
|
if [ -f "$TARGETS_DIR/top50.txt" ]; then
|
|
cp "$TARGETS_DIR/top50.txt" "$output"
|
|
ok "$(wc -l < "$output") from Analyzer target list"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
discover_vulnerable_software() {
|
|
local output="$WORK_DIR/vuln_software_targets.txt"
|
|
log "Building vulnerable software target list..."
|
|
|
|
# Sites running known-vulnerable software
|
|
cat > "$WORK_DIR/vuln_sites.txt" << 'VULNSITES'
|
|
# Known software vendors/instances that may have vulnerable versions
|
|
wordpress.org
|
|
joomla.org
|
|
drupal.org
|
|
magento.com
|
|
prestashop.com
|
|
opencart.com
|
|
phpmyadmin.net
|
|
roundcube.net
|
|
cpanel.net
|
|
php.net
|
|
apache.org
|
|
nginx.org
|
|
mysql.com
|
|
postgresql.org
|
|
mongodb.com
|
|
nodejs.org
|
|
laravel.com
|
|
symfony.com
|
|
rails.org
|
|
docker.com
|
|
kubernetes.io
|
|
jenkins.io
|
|
gitlab.com
|
|
sonarqube.org
|
|
grafana.com
|
|
prometheus.io
|
|
elastic.co
|
|
redis.io
|
|
tomcat.apache.org
|
|
jira.atlassian.com
|
|
confluence.atlassian.com
|
|
vbforum.com
|
|
simplemachines.org
|
|
phpbb.com
|
|
mediawiki.org
|
|
VULNSITES
|
|
|
|
# Also add common CMS plugin repositories
|
|
echo "woocommerce.com" >> "$WORK_DIR/vuln_sites.txt"
|
|
echo "easy-digital-downloads.com" >> "$WORK_DIR/vuln_sites.txt"
|
|
|
|
httpx -l "$WORK_DIR/vuln_sites.txt" -rl 20 -silent -timeout 5 \
|
|
-o "$output" 2>/dev/null
|
|
|
|
if [ -s "$output" ]; then
|
|
ok "$(wc -l < "$output") live software targets"
|
|
fi
|
|
}
|
|
|
|
# ============================================================
|
|
# PHASE 2: TECH DETECTION & TARGETED CVE SCANNING
|
|
# ============================================================
|
|
|
|
detect_technologies() {
|
|
local targets_file="$1"
|
|
local output="$WORK_DIR/tech_detected.json"
|
|
|
|
log "Detecting technologies on $(wc -l < "$targets_file") targets..."
|
|
httpx -l "$targets_file" -tech-detect -j -rl 20 -silent -timeout 5 \
|
|
-o "$output" 2>/dev/null
|
|
|
|
local count=$(wc -l < "$output" 2>/dev/null || echo 0)
|
|
ok "Tech detected on $count hosts"
|
|
|
|
# Summary
|
|
python3 -c "
|
|
import json, sys
|
|
from collections import Counter
|
|
techs = Counter()
|
|
with open('$output') as f:
|
|
for line in f:
|
|
try:
|
|
d = json.loads(line)
|
|
for t in d.get('tech', []):
|
|
techs[t] += 1
|
|
except: pass
|
|
print('Top technologies detected:')
|
|
for tech, cnt in techs.most_common(20):
|
|
print(f' {tech}: {cnt}')
|
|
" 2>/dev/null
|
|
|
|
echo "$output"
|
|
}
|
|
|
|
run_focused_cve_scan() {
|
|
local targets_file="$1"
|
|
local tech_file="$2"
|
|
local output="$REPORTS_DIR/hunter_cve_$(date +%Y%m%d_%H%M%S).json"
|
|
|
|
# Map technologies to specific CVE template categories
|
|
log "Running focused CVE scan..."
|
|
|
|
# Scan ALL targets with general CVE templates (faster than all 4k)
|
|
nuclei -l "$targets_file" \
|
|
-j \
|
|
-rl 30 \
|
|
-c 15 \
|
|
-t "$NUCLEI_TEMPLATES/http/cves/" \
|
|
-o "$output" \
|
|
-severity critical,high \
|
|
-silent \
|
|
-stats \
|
|
2>/dev/null
|
|
|
|
if [ -s "$output" ]; then
|
|
ok "$(wc -l < "$output") critical/high findings"
|
|
else
|
|
warn "No critical/high findings in mass scan"
|
|
fi
|
|
|
|
# Also run medium + exploitation templates for more depth
|
|
local output2="$REPORTS_DIR/hunter_cve_medium_$(date +%s).json"
|
|
nuclei -l "$targets_file" \
|
|
-j \
|
|
-rl 20 \
|
|
-c 10 \
|
|
-t "$NUCLEI_TEMPLATES/http/cves/" \
|
|
-o "$output2" \
|
|
-severity medium \
|
|
-silent \
|
|
2>/dev/null
|
|
|
|
echo "$output"
|
|
}
|
|
|
|
# ============================================================
|
|
# PHASE 3: THE ANALYZER INTEGRATION
|
|
# ============================================================
|
|
|
|
analyze_findings() {
|
|
local findings_file="$1"
|
|
local output="$REPORTS_DIR/hunter_report_$(date +%Y%m%d_%H%M).md"
|
|
|
|
log "Generating report..."
|
|
|
|
python3 -c "
|
|
import json, sys
|
|
from collections import Counter
|
|
from datetime import datetime
|
|
|
|
findings = []
|
|
cves = Counter()
|
|
severities = Counter()
|
|
|
|
with open('$findings_file') as f:
|
|
for line in f:
|
|
try:
|
|
d = json.loads(line)
|
|
sev = d.get('info',{}).get('severity','unknown')
|
|
severities[sev] += 1
|
|
|
|
# Extract CVE IDs
|
|
cve_list = []
|
|
for ref in d.get('info',{}).get('classification',{}).get('cve',[]):
|
|
cve_list.append(ref.get('id',''))
|
|
if not cve_list:
|
|
# Try alternative CVE sources
|
|
for ref in d.get('info',{}).get('reference',[]):
|
|
if 'cve' in ref.lower() or 'CVE' in ref:
|
|
cve_list.append(ref.split('/')[-1])
|
|
|
|
cve_id = cve_list[0] if cve_list else 'N/A'
|
|
for c in cve_list:
|
|
cves[c] += 1
|
|
|
|
findings.append({
|
|
'url': d.get('matched-at', d.get('host', '?')),
|
|
'cve': cve_id,
|
|
'severity': sev,
|
|
'name': d.get('info',{}).get('name', '?'),
|
|
'template': d.get('template-id', ''),
|
|
'extracted': d.get('extracted-results', []),
|
|
})
|
|
except: pass
|
|
|
|
# Summary
|
|
icons = {'critical':'🔴','high':'🟠','medium':'🟡','low':'🔵','unknown':'⚪'}
|
|
print('# Mass Vulnerability Hunter Report')
|
|
print(f'Generated: {datetime.now().strftime(\"%Y-%m-%d %H:%M\")}')
|
|
print()
|
|
print('## Summary')
|
|
print('| Metric | Value |')
|
|
print('|--------|-------|')
|
|
print(f'| Total Findings | {len(findings)} |')
|
|
for sev in ['critical','high','medium','low']:
|
|
if severities[sev]:
|
|
print(f'| {icons.get(sev,\"?\")} {sev.capitalize()} | {severities[sev]} |')
|
|
|
|
if cves:
|
|
print()
|
|
print('## CVEs Detected')
|
|
for cve, cnt in cves.most_common(30):
|
|
print(f'- [{cve}](https://nvd.nist.gov/vuln/detail/{cve}): {cnt} occurrences')
|
|
|
|
print()
|
|
print('## All Findings')
|
|
for f in findings:
|
|
icon = icons.get(f['severity'], '?')
|
|
print(f'- {icon} [{f[\"cve\"]}] {f[\"name\"]} @ {f[\"url\"]}')
|
|
" > "$output" 2>/dev/null
|
|
|
|
ok "Report: $output"
|
|
cat "$output"
|
|
}
|
|
|
|
# ============================================================
|
|
# MAIN ENTRY POINT
|
|
# ============================================================
|
|
|
|
hunter_main() {
|
|
local target_count="${1:-500}"
|
|
local mode="${2:-auto}" # auto|quick|deep
|
|
|
|
echo ""
|
|
echo "╔═══════════════════════════════════════════╗"
|
|
echo "║ MASS VULNERABILITY HUNTER ║"
|
|
echo "╚═══════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# Phase 1: Build target list
|
|
log "PHASE 1: Target Discovery"
|
|
discover_from_tranco "$target_count"
|
|
discover_vulnerable_software
|
|
discover_from_analyzer
|
|
|
|
# Merge targets
|
|
cat "$TARGETS_DIR"/hunt_*.txt "$WORK_DIR"/vuln_software_targets.txt 2>/dev/null | \
|
|
sort -u > "$WORK_DIR/all_targets.txt"
|
|
ok "Total unique targets: $(wc -l < "$WORK_DIR/all_targets.txt")"
|
|
|
|
# Phase 2: Tech Detection + CVE Scan
|
|
echo ""
|
|
log "PHASE 2: Scanning"
|
|
|
|
local tech_file="$WORK_DIR/tech_detected.json"
|
|
detect_technologies "$WORK_DIR/all_targets.txt" "$tech_file"
|
|
|
|
echo ""
|
|
local findings_file=$(run_focused_cve_scan "$WORK_DIR/all_targets.txt" "$tech_file")
|
|
|
|
# Phase 3: Analyze + Report
|
|
echo ""
|
|
log "PHASE 3: Analysis"
|
|
analyze_findings "$findings_file"
|
|
|
|
echo ""
|
|
ok "Hunt complete!"
|
|
echo " Targets scanned: $(wc -l < "$WORK_DIR/all_targets.txt")"
|
|
echo " Findings: $(wc -l < "$findings_file" 2>/dev/null || echo 0)"
|
|
echo " Report: $REPORTS_DIR/hunter_report_*.md"
|
|
}
|
|
|
|
# Run if executed directly
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
hunter_main "$@"
|
|
fi
|