miércoles, 9 de diciembre de 2015

Robando credenciales de Sony mediante redirección abierta

Las vulnerabilidades de redirección abierta (Open redirection) suelen ser consideradas de baja importancia. Sin embargo, uno de los factores que elevan la criticidad de este tipo de fallos es su presencia en procesos de registro o de autenticación, ya que el usuario parte de una predisposición para facilitar sus credenciales de acceso. En este post veremos la protección que implementaba Sony contra este tipo de ataques y cómo fue posible evadirla con un vector que puede ser muy útil en diversas situaciones, no necesariamente relacionadas con la explotación de una redirección abierta.

Este fallo fue reportado a Sony en mayo de 2015 y solucionado cuatro meses más tarde. Finalmente, fui añadido en agradecimiento a su "Hall of Thanks".

Si intentamos registrarnos en cualquiera de las webs oficiales de Sony (www.sony.es, www.sony.de, www.sony.fr, etc.) veremos que, tras pulsar el botón correspondiente para crear una cuenta, somos redirigidos a una URL de este tipo:

https://www.sony.es/mysony/register?email=email%40dominio.com&check=true&returnUri=%2Fmysony

Examinando el código HTML de la página se puede apreciar cómo el valor del parámetro "returnUri" se refleja en un campo oculto del formulario:

Figura 1. Campo oculto "returnUri" en formulario de registro
Tras completar toda la información requerida y enviarla, recibimos en nuestro email el típico correo electrónico para confirmar el registro con un enlace parametrizado que incluye un token aleatorio y la ruta facilitada en el parámetro "returnUri". Finalmente, tras pulsar en este enlace somos redirigidos a la página que nos confirma la activación de la cuenta:

Figura 2. Página de confirmación de activación de la cuenta y código HTML

En la imagen anterior podemos apreciar dos cosas interesantes. La primera es que Sony invita a iniciar sesión con la cuenta recién creada, por lo que el usuario estará predispuesto a introducir sus credenciales de acceso en el siguiente paso. La segunda es que el botón "Continuar" contiene un enlace a la dirección que se introdujo inicialmente en el parámetro "returnUri". Por tanto, si este parámetro aceptara cualquier URL sería un escenario ideal para un ataque de redirección abierta con el cual enviar un enlace de registro manipulado y conseguir que una víctima introdujera sus credenciales en un dominio controlado por el atacante.

El primer intento básico fue introducir en el parámetro "returnUri" distintas URL del tipo http://dominio.atacante.com, https://..., HtTp://..., HttPs://..., data:, javascript:, etc. Sin embargo, cualquier valor que no empezara por un caracter "/" (%2F codificado en URL) hacía que el parámetro oculto del formulario HTML de la "Figura 1" fuera eliminado automáticamente, asignándose posteriormente el valor por defecto %2F en el enlace recibido en el email de confirmación.

El segundo intento, como algunos estaréis pensando, fue probar con una doble barra una URL del tipo //dominio.atacante.com, ya que esto sería equivalente a https://dominio.atacante.com. El resultado era el mismo que en el caso anterior.

Llegados a este punto, ¿existe alguna manera de reflejar una URL absoluta en el código HTML comenzando con un y solo un caracter "/" (%2F)? Sorprendentemente, se puede conseguir esto utilizando cadenas del tipo:

 %2F%09%2Fdominio.atacante.com

Los caracteres %09, %10 y %13 (tabulador, nueva línea y retorno de carro respectivamente) pueden ser introducidos en medio de los dos caracteres "/" y el resultado es equivalente a //dominio.atacante.com y, por tanto en este caso, a https://dominio.atacante.com. Utilizando este método el ataque no era detectado por Sony y el parámetro "returnUri" no era eliminado del formulario, con lo que nuestra redirección abierta funcionó perfectamente:


Este vector suele resultar muy efectivo en cualquier contexto web en el que deseamos romper la "jaula" que nos impone un path relativo. Si por otro lado estás en el bando defensivo como programador, conviene recordar que para evitar el uso de URL externas no será suficiente comprobar que la cadena introducida por el usuario comience por una sola barra, ya que habrá que tener en cuenta la posible presencia de los caracteres de separación mencionados anteriormente.

¡Un saludo!