miércoles, 9 de junio de 2010

Safari Same Domain Policy Bypass

Ayer por la mañana se publicó una vulnerabilidad en Safari en la manera en que se gestionan las URLs a la hora de verificar la Same Domain Policy.

Same Domain Policy es una protección de los navegadores que impide que un sitio web acceda a los objetos o métodos de otro sitio web, y es fundamental a la hora de proteger a los usuarios de gran cantidad de ataques. Según esta política, dos sitios web son el mismo, y por tanto deben poder acceder a los mismos objetos, cuando el protocolo, el nombre de host y el puerto al que se conecta son idénticos.

Explicado de una forma sencilla, una URL generalmente es de la siguiente forma:

http://banco.pentester.es/directorio/

Esta URL, al seguir los estándares, es gestionada de la misma forma por todo Safari, con "http" como protocolo, "banco.pentester.es" como host y "80" como puerto.

Sin embargo, se ha descubierto que una URL especialmente formada podría provocar errores al reconocer el host a la hora de verificar la Same Domain Policy:

http:banco.pentester.es/directorio/

Esta URL, al ser verificada por la Same Domain Policy, es reconocida como host cadena vacía (""), mientras que por contra es perfectamente usable a la hora de la navegación, y completamente equivalente a la que hemos visto anteriormente.

Por lo tanto, si tenemos una manera de formar URLs de tal forma que el navegador las reconozca como pertenecientes siempre a un host cadena vacía, podríamos construir varias URLs de diferentes sitios web de esta forma, y todos ellos serían reconocidos como pertenecientes al mismo dominio, con lo que podríamos acceder desde un sitio malicioso a los objetos y métodos de otros sitios web legítimos.

Veamos un pequeño ejemplo práctico.

Hemos creado un sitio web legítimo http://banco.pentester.es que contiene una vulnerabilidad que nos permite controlar el origen de un iframe de la web (para los puntillosos, también permite más cosas, pero vamos a centrarnos en el iframe). En realidad, este ataque a Safari podría realizarse simplemente con tener dos ventanas diferentes abiertas, sin necesidad de que exista ninguna otra vulnerabilidad en la web, pero nos parece un ejemplo interesante y real, así que vamos a ello:


Por otro lado, tenemos un sitio web malicioso http://test.sobreroblanco.es en el que tenemos un fichero que, a través de Javascript, pretende realizar modificaciones sobre el HTML de fuera del iframe. En este caso, cambiar el enlace "Contacto" de la web principal para que nos llegue a nosotros:


Tal cual está, si intentamos explotar la vulnerabilidad en el iframe, la web contenida dentro del iframe no va a ser capaz de alterar el contenido del resto de la web, ya que ambas webs se encuentran en dominios diferentes y el navegador no va a permitir que una acceda a los objetos de la otra:

http://banco.pentester.es/index.php?iframe=http://test.sombreroblanco.es


Como podemos ver, el enlace no ha cambiado, a pesar de que hemos intentado cambiarlo mediante Javascript, ya que la verificación del Same Domain Polocy ha fallado por tratarse de dominios diferentes.

Sin embargo, si formamos las URL de tal forma que hagamos que Safari crea que ambos dominios son cadena vacía (""), podríamos saltarnos esta restricción de seguridad:

http:banco.pentester.es/index.php?iframe=http:test.sombreroblanco.es


Como podemos ver en la parte inferior... AHORA SÍ, hemos conseguido cambiar el código HTML por medio de un código Javascript que se encuentra dentro del iframe y nos hemos saltado la Same Domain Policy.

Ya hemos explotado la vulnerabilidad, pero... no es tan fácil como parece, ya que si nos limitamos a escribir la URL maliciosa en el navegador no va a funcionar, ya que el navegador añadirá la doble barra (//) delante de los dos puntos (:) de forma automática para formar una URL correcta. Para que la explotación funcione correctamente, tenemos que conseguir que el usuario pinche sobre un enlace de la siguiente forma:


De esta manera, si conseguimos que un usuario pinche un enlace como este, es dirigido correctamente a la web que hemos visto antes y la vulnerabilidad es explotada.

Una de las maneras más evidentes de sacar provecho de este tipo de vulnerabilidades, además de cambiar el contenido de la web padre, es el robo de cookies de sesión. Sin embargo, tras realizar diversas pruebas, hemos llegado a la conclusión (o al menos nosotros no lo hemos conseguido) de que Safari no almacena correctamente las Cookies que provienen de un dominio cadena vacía, y por lo tanto no podemos utilizar esta técnica para forzar a que un usuario se autentique en la web legítima y robarle la Cookie desde el iframe, o incluso desde otra ventana del navegador. Para probarlo, hemos utilizado un sencillo código Javascript que crea una Cookie para posteriormente mostrarla con un alert:


Este código, accedido de la forma habitual (http://), nos muestra el valor nuevo que hemos introducido en al cookie:


Sin embargo, cuando lo llamamos mediante un "http:", no nos aparece en el alert ni la propia cookie que acabamos de configurar, sino que aparece completamente en blanco:


Este funcionamiento, por lo que hemos podido comprobar, inutilizaría la opción del robo de cookies, ya que estas simplemente nunca van a existir.

Sin embargo, que no exista la opción de robo de cookies no quiere decir que no exista la opción de robo de credenciales, ya que podríamos usar la misma técnica de cambio del código HTML para lanzar una web legítima con el formulario real de autenticación, y por otro lado nuestro sitio malicioso que altere el "action" de ese formulario para que las credenciales lleguen a un sitio controlado por el atacante.

Por lo tanto, se considera una vulnerabilidad de alto riesgo para los usuarios de Safari, por lo que recomendamos a todos ellos que apliquen los parches de seguridad publicados por Apple a la mayor brevedad posible.

4 comentarios :

Anónimo dijo...

Muy bueno!! genial como todos tus artículos!
Un saludo!

Adrián dijo...

Buena prueba de concepto :) Como disparo al aire, ¿no sería posible emular el dominio que quieres? Si fuera posible las cookies se generarían bien y podrías robarlas, es más, no tendrías que incitar al atacante a pinchar en un enlace para poder robarle credenciales.

Lo digo sin ver el código fuente, pero supongo que considerará que el host es lo que está comprendido entre // y /. En este caso puesto que no hay // devuelve "". Pero igual se podría construir la URL de alguna forma similar a esta:

http:example.com//fakedomain.com/directory/

Con un poco de suerte cogerá fakedomain.com como el host... Que no lo sé, igual busca lo que hay entre :// y /, poniéndolo más difícil. No tengo un mac a mano para hacer la prueba :P

Jose Selvi dijo...

Gracias @Edgar, nos alegra que te haya gustado ;)

Jose Selvi dijo...

@Adrian: Si el host lo está sacando como dices, sí, se podría hacer algo así, claro :)

Yo te haré la prueba, si es que las actualizaciones de esta mañana no me han corregido el fallo xDD

La verdad es que el descubridor de la vulnerabilidad no ha dado detalles de por qué lo coge como cadena vacía, y yo tampoco he intentado mirar el código ni nada.