martes, 6 de septiembre de 2011

WhatsApp Account Hijacking

Hace un par de meses tuve la oportunidad de dar una charla en la Universidad Europea de Madrid sobre auditoría de aplicaciones móviles. En esa charla, además de comentar de que manera podríamos auditar una aplicación para teléfonos móviles, con todas las peculiaridades que ellas tienen, hice una demostración sobre una conocida aplicación, la cual no publiqué en su momento para realizar un "Responsable Disclosure" e informar en primer lugar a la empresa desarrolladora. La vulnerabilidad permitía hacer un Account Hijacking de las cuentas de WhatsApp, y de esta manera poder suplantar a cualquier usuario. Las pruebas fueron realizadas sobre la versión en Android, aunque son perfectamente validas de forma analoga para otras plataformas.

Dicha vulnerabilidad fue notificada en su momento al equipo de desarrollo de WhatsApp y, según ellos mismos nos confirmaron, ha sido corregida en la versión actual. No obstante, no se ha realizado una auditoría profunda de la aplicación, más allá de la prueba de concepto que se realizó como demostración de la charla, por lo que es posible que otras vulnerabilidades similares (o de otro tipo) puedan existir en la aplicación.

La información proporcionada en este post, además de que la vulnerabilidad ha sido a priori corregida, es totalmente con fines educativos, con lo que no me hago responsable del mal uso que se haga de esta información.

La vulnerabilidad detectada tiene que ver con la manera en la que WhatsApp realiza la autenticación inicial para el registro. Cuando instalamos WhatsApp por primera vez en nuestro terminal éste nos solicita que le introduzcamos nuestro número de teléfono y, de alguna forma, él comprueba que el número es correcto y pasa a registrarnos como ese número. A partir de ese momento ya podemos hablar con nuestros contactos.

¿Cómo comprueba WhatsApp que somos realmente el número que decimos ser? Aquí viene el problema, ya que utiliza únicamente mecanismos en el propio terminal, los cuales podrían ser manipulados, como veremos a continuación.



En este video podemos ver en que consistía el proceso de validación de WhatsApp antes de la corrección de la vulnerabilidad. Para comprobar si el número introducido es correcto, la aplicación de WhatsApp genera un token alfanumérico y construye un SMS de la forma "WhatsApp [Código] WhatsApp internal use - safe to discard" y lo envía al número que el usuario le ha introducido. Si efectivamente es el propio número, el SMS irá hasta el centro de mensajes del operador correspondiente y este volverá al terminal. En ese momento la aplicación de WhatsApp recibe el SMS y comprueba que el Token recibido es el mismo que el enviado. Si esto es así, eso quiere decir que el número introducido por el usuario es el correcto, y por lo tanto envía una conexión a WhatsApp registrando el usuario, asignándole algún tipo de contraseña.

Ahora viene la pregunta: Dado que todo este proceso se realiza en el software instalado en nuestro terminal móvil, y como dueños de este tenemos total control sobre el software que instalamos... ¿podríamos modificar el software de WhatsApp para que simplemente aceptara cualquier número que le introduzcamos como válido?

La respuesta (al menos antes de la corrección de la vulnerabilidad) es SI.

Bucear por el código de WhatsApp resulta un poco complicado, ya que todo él ha sido ofuscado para intentar evitar técnicas de Ingeniería Inversa, pero aún así, podemos encontrar ciertos puntos claves en el código, como las llamadas a ciertas APIs, por ejemplo la de envío de SMS.


Si observamos las llamadas que hay en el código a los objetos SmsMessage y SmsManager, veremos un par de zonas del código en las que se contruye un SMS con el número de origen que hemos introducido por teclado y otra donde se lee el número de origen del SMS recibido. Teniendo localizadas estas zonas del código ahora solo nos quedaria cambiar el código de tal forma que, pongamos el teléfono que pongamos al arrancar la aplicación, el SMS sea siempre enviado a nuestro número real, y que cuando este se compruebe, la aplicación crea que el origen es el correcto.


Como podemos ver en la captura anterior, hemos mirado en la definición de la función sendDataMessage() en que parámetro está el número de destino y hemos visto que es el primer parámetro. En este tipo de definiciones, a la que vemos que se le pasa un vector de parámetros (v0 .. v6), el v0 es el puntero al propio objeto (self) y el v1 es el primer parámetro, es decir, el que buscamos, así que si buscamos hacia arriba donde se asigna el valor de la variable v1 vemos que sale de una variable del objeto VerifySms. Como nosotros queremos que envíe el SMS a nuestro propio teléfono independientemente del teléfono que introduzcamos en la aplicación, simplemente comentamos esta linea e introducimos una asignación estática de la variable v1 a nuestro número de teléfono real (marcado con XXXXX en la imagen).

Para la recepción del SMS hacemos el proceso análogo, pero esta vez con la función getDisplayOriginatingAddress() del objeto SmsMessage, en la que cada vez que es llamada, nosotros asignamos estáticamente el valor que queremos a continuación.


Una vez hecho esto, volvemos a empaquetar la aplicación y la instalamos en el móvil, y probamos a ver si somos capaces de suplantar la identidad de una persona en WhatsApp:



BINGO! Parece que esto funciona (o mejor dicho, funcionaba). Esta vulnerabilidad nos ha permitido el robo de cuentas de usuario de WhatsApp. Por suerte, el usuario cuya cuenta es robada vería un mensaje en su pantalla diciendo algo así como "no utilices WhatsApp en más de un teléfono móvil", con lo cual puede darse cuenta que alguien ha conseguido robarle la cuenta, pero aún así se trataba de una vulnerabilidad importante que debía ser corregida.

Eso es todo por hoy, tengan cuidado ahí fuera!

9 comentarios :

Anónimo dijo...

Muy buen post, muy elaborado.

por cierto ¿con que programa haces las capturas en video?

Anónimo dijo...

Soy el anonimo de antes.

Habias probado http://code.google.com/p/androidscreencast/ par poder tener el video del android y manejarlo desde el portatil?

Que software usas para hacer el video en tu portatil?

Jose Selvi dijo...

@Anónimo: Si te lo cuento te vas a reir, el SDK de Android permite sacar un screenshot de la pantalla del portátil y mostrarlo. También tiene un botón para refrescar este screenshot.

Lo que hice fue pulsar repetidamente este botón para que hiciera "efecto vídeo" mientras tocaba el móvil, si te fijas en el vídeo lo verás :)

MUY pedestre, pero funciona.

Para hacer el video suelo usar VLC, que es gratuito, aunque alguna vez uso algún otro.

Las presentaciones las exporto directamente a vídeo desde el KeyNote.

lobobinario dijo...

Hola!!
Estuve presente en la charla de la UEM donde presentaste este trabajo. La verdad es que estuvo genial y explicada de forma impecable. Me quito el sombrero!!

Anónimo dijo...

si, se te veia pulsando como loco :DD

Para la proxima vez, ¿has echado un vistazo al androidscreencast? te permite manejar remotamente el telefono desde el portatil

Anónimo dijo...

Así q cualquiera q tenga instalada la versión anterior de android podría aprovecharse de esta vulnerabilidad?

Jose Selvi dijo...

@Anónimo: En principio WhatsApp suele bloquear el registro desde versiones anteriores, es decir, el que tenga una versión antigua podrá seguir hablando con ella, pero si intenta registrar un número no podrá, aunque sea su propio número, tendrá que actualizar.

Tampoco digo que esa medida sea insalvable, o sí, quien sabe :P

Jose Selvi dijo...

Gracias @lobobinario, me alegra que disfrutaras la charla :)

@Anónimo: La próxima vez probaré el software que me dices. Gracias por la recomendación.

a0rtega dijo...

Genial, como siempre :)