01 noviembre 2010

Tuenti y las redes locales inseguras - 2/2

Antes de empezar voy a hacer un pequeño resumen de la entrega anterior para que nos ubiquemos en ésta con mayor facilidad.

Como vimos en la primera entrega, podemos aprovechar que el TuentiChat no está cifrado para monitorizar las conversaciones de cualquier usuario que se encuentre en nuestra red local y al que le hayamos realizado previamente el ataque MITM.

A pesar de lo interesante que pueda ser la monitorización de las conversaciones (y las acciones que podamos realizar sobre ellas) creo que es más importante destacar que indirectamente obtenemos el sessionID (de ahora en adelante SID) de la víctima, por lo que nos hacemos con el control total de su cuenta (en realidad casi total, porque algunas acciones requieren la introducción de la contraseña, la cual no obtenemos en ningún momento, por ahora...).

Como se comentó, para poder realizar peticiones en nombre de la víctima necesitaremos, además del SID, el CSFR y en ocasiones el ID (que habremos obtenido durante la monitorización del TuentiChat). Un breve esquema sobre su utilización en las peticiones:
  • Petición GET: SID, ID (a veces)
  • Petición POST: SID, CSFR, ID (a veces)

Bueno, como ya se dijo, en esta segunda entrega se va a hablar de algún ejemplo de peticiones sobre la cuenta de la víctima y sobre robo de sesiones (obligar a la víctima a generar un SID válido) y robo de credenciales (aprovechándonos de que la página de login no está cifrada).

¡Comencemos!

1. Tuenti, yo soy la víctima

Una vez obtenido el SID ya tendríamos control total sobre la cuenta, pues bastaría con abrir nuestro navegador y modificar la cookie SID añadiendo el contenido del de la víctima (abriéndose Tuenti con su sesión). Aun así, si queremos que sea un programa nuestro el que realice las peticiones, voy a dar alguna información sobre como el modificar la información personal de la víctima.

Cuando realicemos la petición no es necesario que enviemos todos los parámetros pero sí todos los relacionados entre sí (por ejemplo los que tienen que ver con el número de teléfono) y, lo más importante, si alguno falla la petición no se procesará, independientemente de que otros datos fueran correctos.

Con respecto a la ciudad, lo importante es el código de la misma (location_hidden) y no su nombre (que no se valida), al contrario que con el barrio (neighborhood_autofill) el cual tiene que tener el nombre exacto o no validará.

Para obtener el código de la ciudad o el nombre del barrio basta con realizar las siguientes peticiones:

http://www.tuenti.com/?m=Dmz&func=get_cities_for_data_source
search=CIUDAD
http://www.tuenti.com/?m=Dmz&func=get_neighborhoods_for_data_source
search=BARRIO&city_id=IDCIUDAD

Obteniendo como respuesta:

{"search_string":"","results":[{"id":ID,"string":"CIUDAD","info":{"location":"CIUDAD"}}]}
{"search_string":"","results":[{"id":ID,"string":"BARRIO","info":null}]}

Como apunte final, simplemente decir que en todas las peticiones que modifican información (todos los ‘POST’) ha de enviarse el CSFR.

¿Qué medida va a tomar Tuenti al respecto?

Pues Tuenti pretende introducir un sistema de firmado de peticiones a través de un token secreto intercambiado por SSL en el inicio de sesión y que no saldría del navegador (incrustado en la página o en una cookie que solo se enviaría en conexiones cifradas).

De ésta forma, junto con un timestamp que se enviaría para darle caducidad a las peticiones y evitar su duplicado, se evitaría que se pudiesen hacer peticiones al servidor sin dicho token.

¿Cómo podríamos obtener ese token secreto?

En principio, bastaría con modificar el HTML que le llega al usuario y hacer que en cualquiera de los formularios del mismo se envíe el mismo token que se utiliza para firmar. Aun así, habría que ver la implantación del mismo.

En la aplicación que se adjunta al artículo podéis ver otras acciones como cerrar la sesión, cambiar el estado, modificar la página web y números de teléfono (los demás campos de la información personal), etc.

2. Robando una sesión

Todo lo que se ha contado es aplicable siempre y cuando el usuario no decida cerrar la sesión, pues entonces el SID quedaría invalidado y no podríamos realizar ninguna acción sobre su cuenta, pero... ¿qué ocurriría si pudiésemos obtener una sesión, de forma transparente al usuario, y que éste no pueda cerrarla? Pues en ese caso tendríamos acceso completo a la cuenta y el usuario no podría hacer nada.

Es cierto que Tuenti establece un límite máximo de cinco SIDs válidos por cuenta/servicio (es decir, la versión normal y la móvil son independientes) y si la víctima abriese cinco cuentas al mismo tiempo nuestro SID quedaría invalidado pero es poco probable pues no es un dato que se conozca además de que el ataque se habría realizado de forma (casi) transparente.

¿Cuál sería el procedimiento?

Este ataque es muy fácil de llevar a cabo. Bastaría con bloquear el envío del SID de la víctima al servidor, de ésta forma éste creería que el usuario no está autenticado y le enviaría la página de login. La víctima se reautenticaría (sería extraño que se diera cuenta de que está siendo atacada pues tampoco es una situación anómala) y generaría un nuevo SID en el servidor. Si tras la reautenticación levantamos el bloqueo y le dejamos seguir operando con el SID antiguo, es decir, modificamos en la cabecera (en Set-Cookie) del paquete de respuesta el contenido de la cookie SID introduciendo el antiguo y nosotros nos quedamos con el nuevo, tendremos acceso a la cuenta de la víctima (tenemos un SID válido) sin que ésta pueda actuar al respecto.

Para realizar el bloqueo, podemos utilizar los filtros de Ettercap. Bastaría con modificar el contenido de la cookie SID. El filtro podría ser así.

if (ip.proto == TCP && tcp.dst == 80) {
    if (search(DATA.data, "sid=")) { replace("sid=", "sid=0"); }
}

A pesar de que podríamos utilizar el Ettercap, yo recomendaría realizar una aplicación propia para el MITM para poder tener mayor control del tráfico antes de que éste se envíe a la víctima. De ésta forma podríamos crear un filtro más personalizado y no estar atados a las opciones que nos da el Ettercap. En el código adjunto al artículo se puede consultar la clase MITM para realizar el ataque desde Java.

¿Qué medida va a tomar Tuenti al respecto?

La medida que va a tomar Tuenti al respecto es el implantar un sistema de control de sesiones (similar al que tenemos, por ejemplo, en Gmail). Es verdad que si el atacante tiene acceso a la cuenta puede monitorizar este servicio y cerrar cada sesión generada por el usuario (bloqueándole el acceso a su cuenta), por lo que la idea es solicitar la contraseña cada vez que se vaya a cerrar una sesión (en todo el ataque no hemos obtenido los credenciales de usuario pues la idea es que el proceso sea lo más transparente posible y, a pesar de que la mayoría aceptaría un certificado falso sin fijarse, es demasiado “cantoso”).

3. Obteniendo los credenciales

Por desgracia es extremadamente sencillo. Bastaría con aprovechar que el “login page” no se cifra, para modificar el formulario de autenticación para que realice la petición sin SSL, obteniendo los credenciales en texto plano.

¿Cómo podríamos modificar el “login page”?

Como estamos realizando un ataque MITM y el tráfico no está cifrado, no sólo podemos monitorizarlo sino también alterarlo, por lo que podríamos utilizar un filtro de Ettercap que se encargue de realizar el proceso, bastando con reemplazar ‘https’ por ‘http’ en el action del formulario. El filtro podría ser así:

if (ip.proto == TCP && tcp.src == 80) {
    replace("action=\"https", "action=\"http");
}

Otra opción podría ser la utilización de la aplicación SSLStrip.

¿Qué medida va a tomar Tuenti al respecto?

Para evitar el robo de credenciales Tuenti tiene previsto cifrar por completo (no solo el envió de los credenciales) el ‘login page’ para evitar su manipulación.

Aun así, es necesario concienciar al usuario de que el login ha de hacerse siempre por medio de una conexión segura, es decir, fijarse si estamos a través de SSL y que además el certificado es de Tuenti. Esto es importante porque sino el atacante, por ejemplo, puede obtener el ‘login page’ por SSL y brindárselo a la víctima sin cifrar, obteniendo los credenciales en texto plano.

Como apunte final, decir que actualmente la contraseña se envía tal cual, y como medida complementaria Tuenti pretende utilizar un token para la autenticación que se enviaría junto con el correo electrónico y cuya estructura sería:

token auth = token secreto + hash(contraseña)

¡Hasta aquí todo! Ya para terminar...

Simplemente decir que el artículo (comunicado hace meses) ha servido para que Tuenti implante (en principio se dijo a medio plazo, pero ahora me entra la duda de que vayan a tomar verdaderamente medidas al respecto) una serie de medidas de seguridad que nos benefician a todos los usuarios.

La mejor medida sería que toda la red social se ofreciera por SSL, opcionalmente al menos (independientemente de la complejidad que conllevara, hay que tener en cuenta los datos tan privados contenidos en la red social). Aun así al parecer (no lo digo yo ni significa que lo comparta) la infraestructura actual de Tuenti no lo soportaría (debido al sistema de balanceo que tienen implementado) además de que la experiencia de usuario se vería afectada en gran medida (ralentización).

Y con respecto a la aplicación...

Se han modificado muchas de las ideas que lancé al publicarlo. Por ejemplo, ahora ya podemos empezar a realizar acciones sobre la cuenta de la víctima esté ésta en el TuentiChat o no (como comentaba, lo importante es el SID). Además, se ha modificado el sistema de peticiones pues dejó de funcionar.

Además, se han realizado muchos cambios internos, por lo que os animo a echarle un vistazo al código (no solo compilarlo y ponerse a probar todo lo que se ha dicho en este artículo).

Muchas personas me han pedido que se publique, además del código, una versión ya compilada y lista para usarse. No lo voy a hacer pues es inmediato (puedes incluso abrir el proyecto desde un IDE y compilarlo con un click) y si uno no es capaz de hacer esa tarea tan sencilla es mejor no darle todo hecho...

Nombre: aplicacion_src.7z

Artículo cortesía de: Luis Delgado J.

9 comments :

dan1t0 dijo...

Muy bueno luis,
gracias y un saludo

darizotas dijo...

Hola Luis,

Me he descargado el fichero y los hashes me salen diferentes:

SHA-1: B70A 803F 2D7E 1197 68F2 D0DE 3AF4 66AB 93EB 7F8A
MD5: 3106 6523 EA8B E38A EF21 7026 DEAD 4229

Muy buen post!

Luis dijo...

@darizotas:
Me he descargado el fichero, los he comprobado y me siguen saliendo iguales...
Prueba a descargartelo de nuevo.
(Que raro)

darizotas dijo...

@luis:
Lo he vuelto a intentar y me salen los mismos. Lo he comprobado con GPG 1.4.10

¿No habrá sido un copy&paste?
:-(

Gracias de todos modos.

Luis dijo...

@darizotas:
Que raro, a mi me sigue saliendo bien (uso la extension HashCheck)... por si acaso se ha editado el post quitando esos datos.
¿A qué te refieres con copy&paste? No te entiendo.

darizotas dijo...

@Luis:

Disculpa que haya tardado en responderte. Pero me he instalado la extensión HashCheck y más de lo mismo que con GPG.

Con lo del copy&paste (escribo la mitad de lo que pienso) me refería a que pudieras haber copiado los hashes, sin darte cuenta, de otro fichero.

De todos modos muchas gracias por tu interés :-)

Luis dijo...

@darizotas:
No pasa nada, de vez en cuando me doy vuelta por artículos pasados por si hay alguna pregunta :)
Pues la verdad es que no me lo explico, a mi me sigue dando los mismos que en su día, quedará como misterio sin resolver :S!

Anónimo dijo...

Buenas, felicitaros por este magnífico blog y que sigais publicando entradas.
Tengo un problemilla, que no tiene nada que ver con la entrada pero sin con el programa que habéis puesto, que lo he importado a Netbeans, he añadido las librerías, lo compilo y tal, y a ejecutarlo me dice:

El archivo de configuraci?n no existe!La ruta del archivo ha de ser "null"

¿Cuál puede ser el problema?
Un saludo y gracias.

Luis dijo...

@Anonimo:
Tienes que copiar al directorio de ejecución el archivo "config.ini" que se incluía también con la aplicación. Acuerdate de modificarlo con tus datos.