Cómo evadir la protección SSRF
Supongamos que has encontrado una función en una aplicación web que obtiene recursos externos. Puedes extraer contenido de todo tipo de sitios externos. No parece haber ninguna restricción sobre el tipo de archivo que puedes solicitar … La aplicación muestra todo de inmediato.
¡Todo en este punto final te está anunciando que estás listo para SSRF! Entonces comienzas a escribir los dígitos mágicos: 127.0.0.1. Pero apenas un segundo después, el servidor regresa con una respuesta inesperada:
Error. Requests to this address are not allowed. Please try again.
Bueno. ¿Qué haces ahora?
Mecanismos de protección de SSRF
Las empresas realmente se han dado cuenta del riesgo de ataques de SSRF. Como resultado, la mayoría ha implementado alguna forma de protección SSRF en sus aplicaciones web. Existen dos tipos principales de mecanismos de protección de SSRF: listas negras y listas blancas.
Las listas negras se refieren a la práctica de no permitir ciertas direcciones y bloquear la solicitud si se recibió un registro en la lista negra. La mayoría de las protecciones SSRF toman la forma de listas negras de bloques de direcciones de red interna.
Por otro lado, las listas blancas significan que un servidor solo permite las solicitudes que contengan una URL en una lista previamente especificada. No aceptarían todas las demás solicitudes.
Evadiendo las listas blancas
Las listas blancas son generalmente más difíciles de evadir porque son, por defecto, más estrictas que las listas negras. Pero es posible si hay una vulnerabilidad de redireccionamiento abierto dentro de los dominios incluidos en la lista blanca.
Si puedes encontrar una redirección abierta, puedes solicitar una URL en la lista blanca que redirija a una URL interna.
Si la lista blanca no se implementa correctamente (por ejemplo, a través de expresiones regulares mal diseñadas), también se puede evadir. Esto mediante la creación de un subdominio o directorio como el nombre de dominio en la lista blanca (por ejemplo, victim.com.attacker.com o attacker.com/victim.com).
Evadiendo las listas negras
Empero, debido a los requisitos de la aplicación (buscar recursos externos), la mayoría de los mecanismos de protección SSRF vienen en forma de lista negra. Si te enfrentas a una lista negra, existen numerosas formas de engañar al servidor:
Engañando con redirecciones
Haz que el servidor solicite una URL que controles que redirija a la dirección de la lista negra. Por ejemplo, puedes alojar un archivo con el siguiente contenido en tu servidor web:
<?php header(“location: http://127.0.0.1″); ?>
Digamos que este archivo está alojado en http://attacker.com/redirect.php. De esta manera, cuando realizas la solicitud del servidor de destino http://attacker.com/redirect.php, el servidor de destino se redirige a http://127.0.0.1, una dirección interna restringida.
Engañándolo con DNS
Puedes modificar el registro A/AAAA de un dominio que controlas y has que apunte a las direcciones internas de la red de la víctima. Por ejemplo, digamos que http://attacker.com es un subdominio de tu propiedad. Puedes crear un nombre de host personalizado para la asignación de direcciones IP y hacer que http://subdomain.attacker.com resuelva a 127.0.0.1. Ahora, cuando el servidor de destino solicita http://attacker.com, ¡pensaría que tu dominio se encuentra en 127.0.0.1 y solicitaría datos de esa dirección!
Usar direcciones IPv6
Intenta usar direcciones IPv6 en lugar de IPv4. Es posible que los mecanismos de protección implementados para IPv4 no se hayan implementado para IPv6.
Cambiar la codificación
Hay muchas formas diferentes de codificar una URL o una dirección que no cambia la forma en que un servidor interpreta su ubicación. No obstante, podría dejarla pasar desapercibida en una lista negra. Estos incluyen codificación hexadecimal, codificación octal, codificación dword, codificación URL y codificación mixta.
- Codificación hexadecimal
La codificación hexadecimal es una forma de representar caracteres en el formato base 16 (el rango de caracteres es de 0 a F). Esto en lugar de la base 10 (decimal, el rango de caracteres es de 0 a 9).
Resulta que los servidores pueden entender las direcciones IP cuando están codificadas en hexadecimal. Para traducir una dirección IP con formato decimal a hexadecimal, debes calcular cada sección de la dirección IP en su equivalente hexadecimal. (O tal vez solo uses una calculadora …) Aquí hay un ejemplo:
127.0.0.1 traducida a 0x7f.0x0.0x0.0x1
El “0x” al comienzo de cada sección lo designa como un número hexadecimal.
- Codificación octal
La codificación octal es una forma de representar caracteres en el formato base 8. De forma similar a cómo traduciría una dirección al formato hexadecimal, traduce una dirección IP a forma octal recalculando cada sección de la dirección IP. Por ejemplo:
127.0.0.1 traducida a 0177.0.0.01
En este caso, los ceros iniciales son necesarios para transmitir que esa sección es un número octal.
-
Codificación Dword
“Dword” significa “palabra doble“, que es un entero de 32 bits. Una dirección IP es básicamente un número de 32 bits, dividido en cuatro octetos (grupos de ocho bits) y escrito en formato decimal. Por ejemplo, 127.0.0.1 es en realidad la representación decimal de 01111111.00000000.00000000.00000001. Y cuando traducimos el número entero (01111111000000000000000000000001) en un solo número decimal, ¡obtenemos la dirección IP en formato dword!
Entonces, ¿qué es 127.0.0.1 en dword? Es la respuesta para 127 * 256³ + 0 * 256² + 0 * 256¹ + 1 * 256⁰, que es 2130706433. (¡Debes sacar esa calculadora científica! O simplemente usar una calculadora decimal a binaria). Esto significa que si escribes http://2130706433 en lugar de http://127.0.0.1, ¡aún se entendería! Muy bien, ¿verdad?
- Codificación de URL
Cada carácter individual en una URL puede representarse por su número hexadecimal designado, si están precedidos por un símbolo%. Por ejemplo, la palabra “localhost” puede representarse con su equivalente codificado en URL, “% 6c% 6f% 63% 61% 6c% 68% 6f% 73% 74”. Por lo tanto, cuando un servidor está bloqueando solicitudes a nombres de host internos como “localhost”, ¡prueba su equivalente codificado en URL!
- Codificación Mixta
¡Es tiempo de mezclar y combinar! También podrías usar una combinación de técnicas de codificación para tratar de engañar al servidor: ¿tal vez esto funcionaría?
127.0.0.1 traducida a 0177.0.0.0×1
Conclusión
Esta es solo una pequeña muestra como evadir y como un atacante podría tener en su arsenal esta opción. Estoy bastante seguro de que hay muchas más formas creativas para evadir la protección SSRF.
Cuando no puedes encontrar una evasión que funcione, es útil cambiar tu perspectiva y pensar: ¿cómo implementaría los mecanismos de protección SSRF para esta función?
Debes diseñar y escribir cómo crees que sería la lógica de protección. Luego, intenta evadir el mecanismo de protección que has diseñado. ¿Es posible? ¿Te perdiste algo al implementar la protección? ¿Es posible que el desarrollador de la aplicación también haya perdido algo?