--- name: web2-recon description: Web2 recon pipeline category: security risk: offensive source: https://github.com/elementalsouls/Claude-BugHunter source_repo: elementalsouls/Claude-BugHunter source_type: community date_added: '2026-09-20' license: MIT license_source: https://github.com/elementalsouls/Claude-BugHunter/blob/main/LICENSE compatibility: Requires explicit written authorization for a target scope plus the relevant testing tools for this technique. Docs-only; helper scripts and commands not bundled. sources: community, public_research --- > **⚠️ AUTHORIZED USE ONLY** > This skill is for educational purposes or authorized security assessments only. > You must have explicit, written permission from the system owner before using this tool. > Misuse of this tool is illegal and strictly prohibited. > **Mandatory confirmation gate** > Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target: > 1. Ask the user to state the exact target URL, IP, account, or resource. > 2. Ask the user to confirm written authorization and the permitted scope. > 3. Show the exact command(s) and explain their expected effect. > 4. Wait for explicit confirmation in the current conversation. > > Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab. # WEB2 RECON PIPELINE Full asset discovery from nothing to a prioritized URL list ready for hunting. --- ## SETUP (one-time) ```bash # 1. Set your Chaos API key (get free key at chaos.projectdiscovery.io) export CHAOS_API_KEY # then set your ProjectDiscovery Chaos API key as the value # Add to ~/.zshrc or ~/.bashrc for persistence: echo 'export CHAOS_API_KEY # then set your ProjectDiscovery Chaos API key as the value' >> ~/.zshrc # 2. Update nuclei templates (run weekly) nuclei -update-templates # 3. Configure subfinder with API keys for more sources mkdir -p ~/.config/subfinder cat > ~/.config/subfinder/config.yaml << 'EOF' # Get free keys at: virustotal.com, securitytrails.com, censys.io, shodan.io virustotal: [YOUR_VT_KEY] securitytrails: [YOUR_ST_KEY] censys_apiid: YOUR_CENSYS_ID censys_secret: YOUR_CENSYS_SECRET shodan: [YOUR_SHODAN_KEY] EOF # 4. Verify all tools installed which subfinder httpx dnsx nuclei katana waybackurls gau dalfox ffuf anew gf interactsh-client ``` --- ## THE 5-MINUTE RULE > If a target shows nothing interesting after 5 minutes of recon, move on. Don't burn hours on dead surface. **5-minute kill signals:** - All subdomains return 403 or static marketing pages - No API endpoints visible in URLs - No JavaScript bundles with interesting endpoint paths - nuclei returns 0 medium/high findings - No forms, no authentication, no user data --- ## STANDARD RECON PIPELINE ### Pre-Hunt: Always Run First ```bash TARGET="target.com" # Step 0: Passive — crt.sh certificate transparency (no API key needed) curl -s "https://crt.sh/?q=%.${TARGET}&output=json" \ | jq -r '.[].name_value' \ | sed 's/\*\.//g' \ | sort -u > /tmp/subs.txt echo "[+] crt.sh: $(wc -l < /tmp/subs.txt) subdomains" # Step 1: Chaos API (ProjectDiscovery — most comprehensive source) curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains" \ -H "Authorization: $CHAOS_API_KEY" \ | jq -r '.[]' >> /tmp/subs.txt echo "[+] Chaos returned $(wc -l < /tmp/subs.txt) subdomains" # Step 2: subfinder (passive multi-source) subfinder -d $TARGET -silent | anew /tmp/subs.txt assetfinder --subs-only $TARGET | anew /tmp/subs.txt echo "[+] Total subdomains after all sources: $(wc -l < /tmp/subs.txt)" # Step 3: DNS resolution + live host check cat /tmp/subs.txt | dnsx -silent | httpx -silent -status-code -title -tech-detect | tee /tmp/live.txt echo "[+] Live hosts: $(wc -l < /tmp/live.txt)" # Step 4: URL crawl cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -jc -kf all -silent | anew /tmp/urls.txt # Step 5: Historical URLs echo $TARGET | waybackurls | anew /tmp/urls.txt gau $TARGET --subs | anew /tmp/urls.txt echo "[+] Total URLs: $(wc -l < /tmp/urls.txt)" # Step 6: Nuclei scan nuclei -l /tmp/live.txt -t ~/nuclei-templates/ -severity critical,high,medium -o /tmp/nuclei.txt ``` ### Output to Organized Directory ```bash TARGET="target.com" RECON_DIR="recon/$TARGET" mkdir -p $RECON_DIR # All outputs go here: /tmp/subs.txt → $RECON_DIR/subdomains.txt /tmp/live.txt → $RECON_DIR/live-hosts.txt /tmp/urls.txt → $RECON_DIR/urls.txt /tmp/nuclei.txt → $RECON_DIR/nuclei.txt ``` --- ## ATTACK SURFACE TRIAGE ### Find Interesting Targets in URL List ```bash # Parameters worth testing cat /tmp/urls.txt | grep -E "[?&] (id|user|file|path|url|redirect|next|src|token|key|api_key)=" | tee /tmp/interesting-params.txt # API endpoints cat /tmp/urls.txt | grep -E "/api/|/v1/|/v2/|/v3/|/graphql|/rest/|/gql" | tee /tmp/api-endpoints.txt # File upload endpoints cat /tmp/urls.txt | grep -E "upload|file|attachment|document|image|avatar|photo|media" | tee /tmp/uploads.txt # Admin/internal paths cat /tmp/urls.txt | grep -E "/admin|/internal|/debug|/test|/staging|/dev|/management|/console" | tee /tmp/admin-paths.txt # Authentication endpoints cat /tmp/urls.txt | grep -E "/oauth|/login|/auth|/sso|/saml|/oidc|/callback|/token" | tee /tmp/auth-paths.txt ``` ### gf Patterns (Quick Classification) ```bash # Install gf patterns: https://github.com/tomnomnom/gf cat /tmp/urls.txt | gf xss | tee /tmp/xss-candidates.txt cat /tmp/urls.txt | gf ssrf | tee /tmp/ssrf-candidates.txt cat /tmp/urls.txt | gf idor | tee /tmp/idor-candidates.txt cat /tmp/urls.txt | gf sqli | tee /tmp/sqli-candidates.txt cat /tmp/urls.txt | gf redirect | tee /tmp/redirect-candidates.txt cat /tmp/urls.txt | gf lfi | tee /tmp/lfi-candidates.txt cat /tmp/urls.txt | gf rce | tee /tmp/rce-candidates.txt ``` --- ## JS ANALYSIS ### SecretFinder (API keys, tokens in JS bundles) ```bash # Activate venv source ~/tools/SecretFinder/.venv/bin/activate # Scan a single JS file python3 ~/tools/SecretFinder/SecretFinder.py -i "https://target.com/static/js/main.js" -o cli # Scan all JS URLs found in recon cat /tmp/urls.txt | grep "\.js$" | head -50 | while read url; do echo "=== $url ===" python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null done deactivate ``` ### LinkFinder (Endpoints hidden in JS) ```bash source ~/tools/LinkFinder/.venv/bin/activate # Single JS file python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com/app.js" -o cli # All pages (crawls JS from HTML) python3 ~/tools/LinkFinder/linkfinder.py -i "https://target.com" -d -o cli deactivate ``` --- ## DIRECTORY FUZZING ### ffuf — Standard Fuzzing ```bash # Directory discovery on a live host ffuf -u "https://target.com/FUZZ" \ -w ~/wordlists/common.txt \ -mc 200,201,204,301,302,307,401,403 \ -ac \ -t 40 \ -o /tmp/ffuf-dirs.json # API endpoint discovery ffuf -u "https://target.com/api/FUZZ" \ -w ~/wordlists/api-endpoints.txt \ -mc 200,201,204,301,302 \ -ac \ -t 20 # IDOR fuzzing with authenticated request # Create req.txt with Authorization: Bearer TOKEN ffuf -request /tmp/req.txt \ -request-proto https \ -w <(seq 1 10000) \ -fc 404 \ -ac \ -t 10 ``` --- ## TARGET SCORING — GO / NO-GO Score before spending time. Skip if score < 4. | Criterion | Points | |---|---| | Max bounty >= $5K | +2 | | Large user base (>100K) or handles money | +2 | | Program launched < 60 days ago | +2 | | Complex features: API, OAuth, file upload, GraphQL | +1 | | Recent code/feature changes (GitHub, changelog) | +1 | | Private program (less competition) | +1 | | Tech stack you know | +1 | | Source code available | +1 | | Prior disclosed reports to study | +1 | **< 4:** Skip **4-5:** Only if nothing better available **6-8:** Good — spend 1-3 days **>= 9:** Excellent — spend up to 1 week ### Pre-Dive Hard Kill Signals 1. Max bounty < $500 → not worth your time 2. All recent reports are N/A or duplicate → hunters saturated it 3. Scope is only a static marketing page → no attack surface 4. Company < 5 employees with no revenue → won't pay 5. Explicitly excludes your planned bug class in rules --- ## TECH STACK DETECTION (2 min) ```bash # Response headers reveal backend curl -sI https://target.com | grep -iE "server|x-powered-by|x-aspnet|x-runtime|x-generator" # Common signals: # Server: nginx + X-Powered-By: PHP/7.4 → PHP backend # Server: gunicorn OR X-Powered-By: Express → Python/Node.js # X-Powered-By: ASP.NET → .NET # Server: Apache Tomcat → Java # X-Runtime: Ruby → Ruby on Rails # Framework from JS bundle paths: # /_next/static/ → Next.js # /static/js/main.chunk.js → CRA (React) # /packs/ → Ruby on Rails + Webpacker # /__nuxt/ → Nuxt.js (Vue) ``` ### Stack → Primary Bug Class Map | Stack | Hunt First | Hunt Second | |---|---|---| | Ruby on Rails | Mass assignment | IDOR (`:id` routes) | | Django | IDOR (ModelViewSet, no object perms) | SSTI (mark_safe) | | Flask | SSTI (render_template_string) | SSRF (requests lib) | | Laravel | Mass assignment ($fillable) | IDOR (Eloquent, no ownership) | | Express (Node.js) | Prototype pollution | Path traversal | | Spring Boot | Actuator endpoints (/actuator/env) | SSTI (Thymeleaf) | | ASP.NET | ViewState deserialization | Open redirect (ReturnUrl) | | Next.js | SSRF via Server Actions | Open redirect via redirect() | | GraphQL | Introspection → auth bypass on mutations | IDOR via node(id:) | | WordPress | Plugin SQLi | REST API auth bypass | --- ## CONTINUOUS MONITORING SETUP Set up once per target. Alerts you before other hunters. ### New Subdomain Alerts (daily cron) ```bash #!/bin/bash TARGET="target.com" KNOWN="/tmp/$TARGET-subs-known.txt" subfinder -d $TARGET -silent > /tmp/$TARGET-subs-fresh.txt curl -s "https://dns.projectdiscovery.io/dns/$TARGET/subdomains" \ -H "Authorization: $CHAOS_API_KEY" \ | jq -r '.[]' >> /tmp/$TARGET-subs-fresh.txt # Diff against known NEW=$(comm -23 <(sort /tmp/$TARGET-subs-fresh.txt) <(sort $KNOWN 2>/dev/null)) if [ -n "$NEW" ]; then echo "NEW SUBDOMAINS: $NEW" echo "$NEW" >> $KNOWN fi # Schedule: crontab -e → 0 8 * * * /bin/bash ~/monitors/subs-watch.sh ``` ### GitHub Commit Watch ```bash #!/bin/bash REPO="TargetOrg/target-app" LAST_SHA="/tmp/$REPO-last-sha.txt" CURRENT=$(curl -s "https://api.github.com/repos/$REPO/commits?per_page=1" | jq -r '.[0].sha') KNOWN=$(cat $LAST_SHA 2>/dev/null) if [ "$CURRENT" != "$KNOWN" ]; then echo "New commit on $REPO: $CURRENT" echo $CURRENT > $LAST_SHA # Get changed files curl -s "https://api.github.com/repos/$REPO/commits/$CURRENT" \ | jq -r '.files[].filename' | grep -E "auth|middleware|route|permission|role|admin" fi # Schedule: */30 * * * * /bin/bash ~/monitors/github-watch.sh ``` --- ## PORT SCANNING (often skipped — don't skip) ```bash # naabu — fast port scanner from ProjectDiscovery # Finds non-standard ports: 8080, 8443, 3000, 8888, 9000, etc. cat /tmp/live.txt | awk '{print $1}' | naabu -port 80,443,8080,8443,3000,4000,5000,8000,8888,9000,9090,9200,6379 -silent | tee /tmp/open-ports.txt # Why this matters: admin panels, debug services, internal APIs often run on alt ports # Example wins: :8080/actuator/env (Spring Boot), :9200/_cat/indices (Elasticsearch), :6379 (Redis) ``` ## SECRET SCANNING IN JS BUNDLES ```bash # trufflehog — high-signal secret detection with entropy analysis # Scans JS files and git repos pip install trufflehog3 2>/dev/null || true trufflehog filesystem --only-verified recon/$TARGET/ 2>/dev/null # SecretFinder — manual JS bundle scan (already in tools/) source ~/tools/SecretFinder/.venv/bin/activate cat /tmp/urls.txt | grep "\.js$" | head -100 | while read url; do python3 ~/tools/SecretFinder/SecretFinder.py -i "$url" -o cli 2>/dev/null done deactivate # Quick grep for common patterns in downloaded JS wget -q -r -l 1 -A "*.js" -P /tmp/js-files/ "https://$TARGET" 2>/dev/null grep -rn "api_key\|apiKey\|client_secret\|access_token\|private_key\|AWS_SECRET\|AKIA" /tmp/js-files/ 2>/dev/null ``` ## GITHUB DORKING FOR TARGET ```bash # Search GitHub for hardcoded secrets before hunting the app TARGET_ORG="TargetOrgName" # Check their GitHub org # Useful dorks (search on github.com): # org:TARGET_ORG password # org:TARGET_ORG api_key # org:TARGET_ORG "Authorization: Bearer" # org:TARGET_ORG .env # org:TARGET_ORG "BEGIN RSA PRIVATE KEY" # CLI with gh (GitHub CLI): gh search code "api_key" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | jq '.' gh search code "password" --owner "$TARGET_ORG" --json path,repository 2>/dev/null | head -20 # GitDorker (if installed): python3 ~/tools/GitDorker/GitDorker.py -t GITHUB_TOKEN -d ~/tools/GitDorker/Dorks/alldorksv3 -q "$TARGET" -org ``` ## Contents - [30-MINUTE RECON PROTOCOL](references/details.md) - [Toolchain fallback (when `dnsx` / `httpx` crash)](references/details.md) - [API Spec / Swagger / OpenAPI Discovery (2024-2026 surface)](references/details.md) - [Related Skills & Chains](references/details.md) - [Operator Notes (Claude-BugHunter)](references/details.md) ## When to Use - You have explicit, written authorization to assess the target in scope, and the task matches this skill's vulnerability class or technique within a bug-bounty or penetration-test engagement. - You need the recon, exploitation, or validation workflow described below — executed strictly inside the approved scope. ## Limitations - Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command. - Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed. - Validate every finding (see `triage-validation`) before reporting; report via `report-writing`. Prefer a sandbox, disposable VM, or controlled lab. ### Example ```bash # Read-only first step; confirm scope before anything active. cat scope.txt # target list from the authorized engagement brief ``` > Adapted from [elementalsouls/Claude-BugHunter](https://github.com/elementalsouls/Claude-BugHunter) (MIT); frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.