En este post voy a hablar de un vector de ataque de XSS que podemos explotar para obtener los credenciales de acceso a cualquier servicio del dominio vulnerable, esté el usuario autenticado o no en el mismo.
Como sabemos, la opción de los navegadores de autocompletar formularios de autenticación es muy cómoda y utilizada. Aprovecho para destacar que sólamente Mozilla Firefox tiene implementada la opción de contraseña maestra (aunque no venga activada por defecto) por lo que si usamos Internet Explorer, Google Chrome o Safari (los navegadores que utilizaré para realizar el ataque), nuestras contraseñas estarán almacenadas en texto plano.
Volviendo al tema del ataque, podréis intuir que podemos aprovecharnos de esta funcionalidad para inyectar en la página un formulario de autenticación oculto y obtener los credenciales que el navegador autocompleta.
Aun más interesante es la forma en que los navegadores guardan los credenciales, atendiendo únicamente al host (excepto Internet Explorer que lo hace correctamente), por lo que si hay un XSS en cualquier path podremos explotarlo para obtener los credenciales almacenados en el navegador del usuario de cualquiera de los servicios de ese mismo dominio.
Un ejemplo podría ser el siguiente dominio con los servicios de correo e intranet:
http://pagina.es/correo/login.php
http://pagina.es/intranet/access.php
http://pagina.es/index.php
Si existiera un XSS como http://pagina.es/index.php?msg=XSS podríamos utilizarlo para obtener los credenciales de ambos servicios (correo e intranet).
¿Qué ocurre si los usuarios son distintos?
Si el usuario no es el mismo para ambos servicios tenemos dos casos. Si el usuario está utilizando Firefox o Chrome el formulario no se autocompletará hasta que no especifiquemos con qué usuario nos vamos a autenticar y si, en cambio, está utilizando Safari nos autocompletará con el primero de ellos.
Para obtener los credenciales en el primer caso, o los restantes en el segundo, podríamos cargar la página oculta con AJAX y mediante un script irla recargando modificando el valor del parámetro 'value' del usuario en el formulario (por fuerza bruta o diccionario). En el momento en el que fuera correcto se obtendría la contraseña y se pasaría al siguiente caso.
En el caso de que el usuario estuviera autenticado todo se simplificaría porque bastaría con obtener el nombre de usuario/email (o lo correspondiente) y especificarlo en el parámetro 'value' del usuario en el formulario.
Podéis ver un ejemplo en el siguiente video:
Por lo tanto queda claro que almacenar los credenciales es cómodo pero puede suponer un serio problema, ya no sólo en aquellos navegadores que no ofrecen la opción de configurar una contraseña maestra, sino además si la página es vulnerable a un XSS, pues ya no sólo obtienen nuestro sessionID sino algo más importante, nuestros credenciales.
Aprovecho para hacer referencia a los programas IEPassView, ChromePass y PasswordFox de Nirsoft (en el caso de que no se haya configurado la contraseña maestra) que permiten obtener los credenciales almacenados en dichos navegadores.
---------------------
Contribución por Luis Delgado J.
2 comments :
Usando Chromium en KDE las contraseñas no se almacenan en plano, sino que las guarda en la cartera de Kwallet.
Según he entendido es sólo para rellenar el campo "usuario", el campo "password" ya se rellenará solo. No lo veo tan difícil, al fin y al cabo suelen ser nombres cortos.
Saludos!
Publicar un comentario