jueves, septiembre 25, 2014

Un fallo de CSRF en Twitter para robarte la cuenta

Los ataques de CSRF (Cross-Site Request Forgery) son conocidos hace bastante tiempo. La idea de ellos es bastante sencilla, y el objetivo es conseguir que una víctima, que tiene una sesión con su cuenta en un sitio web, haga acciones involuntarias en esa sesión al abrir un enlace o cargar un contenido externo.

Figura 1: Un bug de CSRF para robare la cuenta de Twitter

A día de hoy es una de las técnicas de hacking más utilizadas, y en el proyecto OWASP TOP TEN, que recoge los diez ataques más utilizadas en ataques a aplicaciones web y donde siguen reinando las técnicas de SQL Injection y el resto de inyecciones de código, ocupa el octavo lugar. 

Una explicación sencilla de CSRF

Para que sea fácil de entender en que consiste el ataque, vamos a suponer una aplicación web para controlar las nóminas de los empleados de una empresa. A esa aplicación web solo puede entrar el administrador y es tan absurdamente sencilla como que hay una lista con los nombres de los empleados junto con dos enlaces a su lado. Uno es un enlace que poner "Subir Sueldo" y otro es un enlace que pone "Bajar Sueldo". Esa aplicación web es tan absurdamente sencilla, que si miramos el código de los enlaces son algo como:
- http://www.server.test/subir_sueldo.php?trabajador=chema
- http://www.server.text/bajar_sueldo.php?trabajador=chema
Cuando se llaman a esos enlaces, lo que sucede es que automáticamente se incrementa o decrementa el sueldo de ese trabajador, en este caso chema, en la base de datos del sistema. Por supuesto, por protección, para que nadie pueda hacer uso de esos procedimientos de incremento y decremento, las aplicaciones subir_sueldo.php y bajar_sueldo.php comprueban que la persona que está enviando esa petición está autenticado como administrador, para lo que es necesario tener una sesión abierta.

El ataque CSRF se aprovecha de esa construcción insegura de enlaces dentro de la aplicación de administración. Es cierto que solo el administrador puede invocarlos, pero si el administrador tiene abierta esa aplicación en una pestaña de su navegador, y en otra tiene abierto  su correo electrónico, bastará con enviar un enlace a http://www.server.test/subir_sueldo.php?trabajador=chema para que haga clic en él para que se ejecute la acción. Si el administrador lo pulsa dentro del correo electrónico, entonces se ejecutará la orden de subir el sueldo a chema.

Esa es una forma muy "burda" de conseguir explotar el ataque, pero lo cierto es que si trasladamos esto a enlaces enviados por Twitter o Facebook o simples mensajes de correo electrónico escritos en HTML que cargan la imagen haciendo uso de img src="http://www.server.test/subir_sueldo.php?trabajador=chema". 

Figura 2: En el año 2007, el propio Gmail fue víctima de un ataque CSRF que generó un gusano

O mucho peor, imaginad que yo sé que tenéis abierto el Twitter en otra pestaña mientras veis este artículo de El lado del mal y cargo un fichero JavaScript malicioso que, usando vuestra sesión de Twitter, empieza a obligaros a publicar cosas, hacer seguimiento a personas o peor, os cambia la contraseña. Esto no podría ser. Sería un desastre.

Protecciones Anti CSRF

Para solucionar esto, se crean las protecciones Anti-CSRF, que consisten en un control del servidor a la hora de controlar desde donde viene hecho el clic. Es decir, en cada enlace que se muestra en una web, o en cada formulario que se carga en una página para que el usuario puede pulsar se genera un token, que se asocia a ese, y solo ese enlace, de tal manera que cuando el usuario hace clic en él debe ser enviado a al servidor junto con el enlace. 

Figura 3: Ejemplo de protección anti-CSRF propuesta en OWASP

En el ejemplo de subir el sueldo, se debería poner algo como http://www.server.test/subir_sueldo.php?trabajador=chema&csrfToken=14123423234234. Esto ayudaría a que si el atacante envía un enlace malicioso deba conocer cuál es el valor del token CSRF válido para la ejecución de la aplicación subir_sueldo.php. Si no lo averigua, el servidor no ejecutará el comando. Por supuesto, la recomendación es no usar esos tokens CSRF en peticiones GET, ya que los tokens quedarán en historiales de navegación, servidores Proxy, Firewalls, sistemas de registro de eventos, etcétera, por lo que lo mejor es hacerlo cambiando el enlace por un formulario.

El bug de Twitter

Esto es algo que hacen casi todos los sitios webs, y entre ellos se encuentra Twitter. Pero... nada de esto vale, si en el servidor no se valida correctamente el token CSRF. Si se envíe el token que se envíe da lo mismo, entonces volvemos a tener ese problema de que cualquiera pueda hacer lo que le de la gana con tu cuenta si la tienes abierta en otra pestaña.

Figura 4: Token Anti-CSRF en el formulario de añadir número de teléfono a cuenta de Twitter

Este es el caso del formulario que permite añadir un número de teléfono a tu cuenta de Twitter como protección, que tal y como podéis ver en el código fuente, cuenta con un token de protección anti-CSRF llamado authentiticity_token, pero... que se olvidó de validar.  Este bug fue descubierto por el investigador colombiano Juan David Castro Dylan Irzi, y lo presentó en la pasada DragonJar Security Conference 2014, con una conferencia que puedes ver online sobre ataques CSRF en general. 


Figura 5: Conferencia de Juan David Castro sobre ataques CSRF

En el caso concreto del ataque de Twitter, para robar la cuenta, lo que hay que hacer es enviar un enlace a la víctima. Cuando ella lo abra, se ejecutará el envío del formulario para añadir un número de teléfono a la cuenta de la víctima, tal y como se puede ver en el exploit que publicó. En él, authenticity_token está a null, porque Twitter no lo estaba validando.

Figura 6: Exploit para añadir el número de teléfono sin token CSRF

A partir de ese momento, la cuenta de la víctima estará asociada al número de teléfono del atacante, que podrá robar vía formulario de recuperación de contraseña. Para ello, basta con que el atacante solicite que se le envíe un código de recuperación de cuenta por SMS al número que está asociado a la identidad - que acaba de poner con el exploit de CSRF -. El vídeo completo de la prueba de concepto de cómo se puede robar una cuenta de Twitter por medio de un bug CSRF está disponible en el siguiente vídeo.


Figura 7: Prueba de Concepto de cómo explotar CSRF en Twitter y robar la cuenta

Por supuesto, Juan David Castro lo reportó a Twitter, que lo solucionó y puso en el Hall of Fame por ayudar a que los usuarios no estuvieran expuestos con este bug que en malas manos podría haber hecho mucho daño. Un hacker que encuentra un bug y lo reporta para que los usuarios no estén expuestos sin esperar nada a cambio. Buen trabajo Juan David, tienes mis respetos.

Saludos Malignos!

3 comentarios:

NetVicious dijo...

Comprobar que el referer eres tu mismo también puede ser una solución. No tan idónea como el token pero sí más sencilla de implementar y también permite que un usuario navegue con dos o más pestañas diferentes por tu web.

guille dijo...

gran labor, enhorabuena al hacker, más entradas como estas

Anónimo dijo...

salvaje!
pedazo de bug!
ni en twiter hay seguridad!
donde menos te lo esperes aparece un CSRF!

Entrada destacada

Programa de Especialización "Inteligencia Artificial para Expertos en Ciberseguridad" 2ª Edición.

Hoy, en medio del verano, os traigo información de la 2ª Edición del   Programa de Especialización  de "Inteligencia Artificial para Ex...

Entradas populares