jueves, 29 de septiembre de 2011

Securizando Android para un uso corporativo (parte 2)

Contribución de Ángel Alonso-Párrizas que continua el post anterior:

En el primer post explicamos como configurar el túnel VPN. Ahora vamos a utilizar ese túnel para gestionar de manera remota el dispositivo mediante SSH. Esto nos permitie deshabilitar el acceso al smartphone por USB y así garantizar que sólo las persona autorizadas dentro de la compañía acceden al mismo. Además, el túnel es de gran utilidad para instalar software de manera remota y controlada, ya que unos de los objectivos del proyecto, como se mencionó en el post anterior, es evitar que se instale software no autorizado.

Configuración de SSH 

En primer lugar, generamos las claves RSA para el servidor VPS mediante el siguiente comando:

test -d $HOME/sshids || mkdir $HOME/sshids && ssh-keygen -t rsa -f $HOME/sshids/idrsa-1

Esto genera un par de ficheros, la clave privada (idrsa-1) y la clave pública (idrsa-1.pub). La clave pública hay que importarla a la tarjeta SD, para a su vez poder incluirlo en el fichero authorized_keys en Android.

En segundo lugar, hay que configurar el servidor SSH en el smarphone, y para ello es necesario ejecutar los siguientes comandos:

adb shell # abrimos una shell
mkdir /data/dropbear # creamos el directorio dropbear
chmod 755 /data/dropbear # cambiamos los permisos
mkdir /data/dropbear/.ssh # creamos el directorio .ssh
chmod 700 /data/dropbear/.ssh # cambiamos los permisos
mv /sdcard/authorized_keys /data/dropbear/.ssh/ # copiamos la clave publica del cliente 
chown root: /data/dropbear/.ssh/authorized_keys # cambiamos el propietario 
chmod 600 /data/dropbear/.ssh/authorized_keys # cambiamos los permisos
dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key # generamos la clave RSA
dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key # generamos la clave dss 

Con esto ya se tiene configurado el servidor. Ahora, solo hay que lanzarlo para que la autenticación funcione únicamente con claves, en lugar de usuario y password. En el siguiente post veremos como se se ejecuta el servidor ssh de manera automatica al iniciar el dispositivo. 
En una shell en Android ejecutamos el comando dropbear -s -g y a continuación en el VPS usaremos el cliente SSH con el parámetro ¨-i¨ y el fichero con la clave privada, algo del estilo: ssh -p 22 root@172.16.1.99 -i idrsa-1
Un ejemplo del la negociación SSH y del acceso al sistema se puede ver en la captura:


Al estar el SSH corriendo es posible subir cualquier fichero mediante SCP, así pues tenemos total control mediante shell y SCP sobre el sistema.



Deshabilitar la instalación de software y el acceso por USB

Una vez ya tenemos garantizado el acceso al dispositivo hay que restringir el acceso mediante USB. 
Existen varias maneras de instalar software en Android y una de ellas es mediante el acceso por USB. 
Hay dos binarios fundamentales en Android que son los que dan soporte a estas funcionalidades:
  • /sbin/adbd es el daemon que gestiona el acceso mediante shell 
  • /system/bin/pm es el binario que gestiona la instalación de paquetes
Si quitamos los permisos a estos binario, el acceso por USB/shell no funcionara y además no sera posible instalar software mediante la shell. Más adelante explicaremos como deshabilitar las aplicaciones como el Market, que sirven para instalar aplicaciones por red.  
Este proceso se hace de manera automatica mediante un script que publicaremos en el próximo post.

Un punto importante a destacar es que si queremos instalar algo de manera controlada el administrador de seguridad puede restablecer los permisos del binario /system/bin/pm  (por SSH) e instalar cualquier fichero 'apk' subido por SCP. De esta manera tenemos la posibilidad de instalar nuevas versiones del software o nuevo software.


Deshabilitar bluetooth 

En este proyecto consideré que el bluetooth no era necesario en un entorno corporativo. Puede estar justificado su funcionamiento en algunos casos (por ejemplo algún responsable que necesite hablar por bluetooth mientras conduce) pero a priori el bluetooth no debe poder usarse.
Análogamente a como se deshabilitó la instalación del software, haremos lo mismo con los dispositivos de blueetooth: 

/dev # ls -l /dev/* | grep blue
crw-rw---- 1 bluetoot bluetoot 249, 0 Jun 29 19:48 /dev/ttyHS0
crw-rw---- 1 bluetoot bluetoot 250, 0 Jun 29 19:48 /dev/ttyMSM0
crw-rw---- 1 system bluetoot 10, 223 Jun 29 19:48 /dev/uinput
srw-rw---- 1 bluetoot bluetoot 0 Jun 29 19:49 dbus

Así, si revocamos los permisos a /dev/ttyHS0 y /dev/ttyMSM0 bluetooth no funcionara como podemos ver en los logs:

V/NotificationService( 164): Active profile: Default
I/PROFILE ( 164): Group: Gmail containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Phone containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Calendar containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: Email containing : com.android.server.vpn : false
I/PROFILE ( 164): Group: SMS containing : com.android.server.vpn : false
V/ProfileManager( 164): No active group, returning default: Other
V/NotificationService( 164): Pkg: com.android.server.vpn group: Other
E/bluedroid( 164): bt_enable: Timeout waiting for HCI device to come up
D/BluetoothService( 164): Bluetooth state 11 -> 10
V/BluetoothEventRedirector( 791): Received android.bluetooth.adapter.action.STATE_CHANGED
D/SettingsAppWidgetProvider( 791): Widget is from a previous version... Let's update
D/SettingsAppWidgetProvider( 791): No instances yet... Wait for at least one instance to exist before adding global set
tings

Deshabilitar la tarjeta SD

Conectar un dispositivo externo, como un pendrive, a un sistema seguro puede ser peligroso y las políticas corporativas deben de limitar estas situaciones. En el caso de Android, tenemos varios problemas con la tarjeta SD:
  •  La ausencia de cifrado de datos
  •  El modelo de permisos. Al ser FAT, una aplicación con permisos de lectura/escritura tiene acceso a toda la tarjeta independientemente de los permisos de las aplicaciones dueñas de los datos.
  • Algunas vulnerabilidades que aprovechan la SD com la descubierta por el colega Mario Ballano.
Por estas razones la tarjeta hay que deshabilitarla desmontándola con 'umount' en tiempo de booting.


lunes, 26 de septiembre de 2011

Securizando Android para un uso corporativo (parte 1)

Contribución de Ángel Alonso-Párrizas:

Esta serie de posts sobre Android son el resultado de un trabajo hecho como parte del proyecto final del Máster en seguridad y análisis forense en la Universidad de Dublin City University. El trabajo original con título "Securely deploying Android devices¨ se puede encontrar en inglés aquí, así como la publicación del paper en la web del SANS Institute. Como nada del proyecto ha sido publicado en castellano aprovecho el blog del colega José Selvi, al cual tengo el placer de conocer desde nuestros años mozos en la Universidad, para exponer el trabajo en la lengua de Cervantes :)

Antes que nada comentar que la idea de este proyecto surgió cuando trabaja en una compañía en la que necesitábamos dar cobertura al uso de Android de manera segura en entornos corporativos. Así que algunas de las funcionalidades que son limitadas en este proyecto pueden no tener tanto sentido si se trata de un usuario final (como por ejemplo la posibilidad de instalar software). Teniendo esto en cuenta, vamos al lío.

Android está sujeto a los mismos problemas de seguridad que cualquier sistema operativo moderno con la particularidad de que el acceso a Internet es itinerante, es decir, puede usarse cualquier conexión WiFi o 3G de manera dinámica. Esto implica ciertos riesgos, como por ejemplo ataques de tipo sniffing. Además, el modelo de distribución de software vía los distintos repositorios (como Market) lo hacen muy vulnerable al malware. Estos son los puntos más débiles de Android pero no los únicos.

Si entrar mucho al detalle, el modelo de seguridad de Android a nivel de Sistema Operativo es robusto ya que las aplicaciones se ejecutan en la máquina virtual (Dalvik) de manera aislada (como en un sistema operativo tradicional donde cada proceso tiene su espacio de memoria). Además, el sistema de ficheros sigue el modelo de permisos de Linux. La diferencia fundamental radica en que en lugar de múltiples usuarios tenemos múltiples aplicaciones (cada aplicación tiene asignado un UID).
Con este modelo es posible definir con cierta granularidad, cuando se desarrolla la aplicación, que permisos necesita ésta para ejecutarse (esto se hace en un fichero llamado AndroidManifest.xml), pero es el usuario final quién tiene la última palabra al aceptar (o no) los permisos. Los problemas que subyacen de este modelo son dos: que un desarrollador con malas intenciones cree un fichero AndroidManifest.xml con más permisos de los necesarios y que un usuario acepte los permisos de una aplicación con más permisos de los requeridos. Si hablamos de un entorno corporativo, donde las políticas de seguridad deben restringir la instalación de cualquier software, aún hay más motivo para mitigar estos riesgos.

Teniendo en cuenta los problemas expuestos de manera resumida arriba, los objetivos principales de este trabajo se pueden resumir en lo siguientes puntos:

  1. Implementar un canal de comunicación seguro a través de VPN (OpenVPN) y enrutar todo el tráfico a través del túnel. Implementar políticas de filtrado de tráfico entrante y saliente.
  2. Limitar el acceso a la administración del dispositivo y centralizar su acceso. El acceso al dispositivo sólo debe ser permitido a los administradores de seguridad a través de SSH con claves.
  3. Deshabilitar la instalación del software. Solo debe instalarse software autorizado por las políticas de seguridad corporativas y el usuario no debe poder instalar nada.
  4. Implementar una política de contraseñas alineados con los estándares de la compañía. El dispositivo debe de borrarse después de un número determinado de fallos en la contraseña.
  5. Habilitar funcionalidades remotas de seguridad, como por ejemplo el borrado remoto, la localización a través de GPS (Google Maps) o el borrado mediante mensaje de texto.
  6. Incluir capas adicionales de seguridad como el antivirus.
  7. Deshabilitar servicios y dispositivos inseguros o innecesarios, como por ejemplo el bluetooth o la tarjeta SD.

Las herramientas que son necesarias para este proyecto son:
  • Un smartphone al que se le pueda instalar la versión de ROM Cyaongenmod (en el caso de este proyecto fue un HTC Desire).
  • Un servidor con Linux (para este proyecto use un VPS ubicado en Holanda).
  • El kit de desarrollo SDK para Android (indistintamente en Linux, Mac o Windows).
  • Tarjeta 3G y un punto de acceso WiFi.
  • Algunas herramientas como OpenVPN, Iptables y SSH.




Cifrar el canal de comunicación e implementar políticas de filtrado

La idea fundamental de este punto consiste en enviar todo el tráfico a través de un túnel VPN-SSL independientemente de que nos conectemos por 3G o WiFi. Para ello, lógicamente, lo primero es establecer el túnel entre el dispositivo y el VPN endpoint (que es el VPS bajo nuestro control o un sistema Linux).
Además, implementaremos políticas de firewall en Android mediante iptables, de tal manera que el único tráfico permitido es el necesario para establecer el túnel y para enrutar todo el tráfico hacia el VPS. Se puede ver un diagrama con la arquitectura en la siguiente figura:


Como muestra la figura, todo el tráfico pasa por el VPN endpoint, por lo que es también posible crear reglas de filtrado con iptables. Así pues es posible aceptar solo el tráfico que las políticas de seguridad de la empresa dictaminen, por ejemplo HTTP/s. Adicionalmente sería posible añadir filtrado de contenido en el trafico web, un antivirus perimetral o lo que se quisiera.
También, es posible crear reglas de filtrado por usuario o rol, es decir, podemos asignar IP estáticas a los clientes del VPN y aplicar reglas en función de la dirección origen.
Con este modelo se consigue 4 cosas: 

  1. Que todo el tráfico vaya cifrado
  2. Que se pueda controlar de manera centralizada qué tráfico es aceptado y cuál debe ser filtrado
  3. Crear reglas en función de un perfil o usuario determinado
  4. Tener visibilidad y poder analizar todo el tráfico en caso de que el smartphone sea comprometido (o porque las políticas de seguridad así lo requieran)

Para establecer el túnel con OpenVPN es necesario únicamente instalar el binario (o compilar) en la máquina linux ya que la ROM de Android antes mencionada ya incluye OpenVPN. A la hora de establecer el túnel es posible hacer uso de certificados o usar una clave privada compartida. Evidentemente, para un entorno corporativo lo aceptable es el uso de clave pública.
El manual de como configurar la CA (autoridad de certificación) para generar certificados y usarlos con OpenVPN lo podéis encontrar en este link. Sin entrar mucho al detalle los pasos importantes para crear la CA y los certificados son:
  • Editar el fichero 'vars' para configurar los datos de los certificados (país, ciudad, correo, etc)
  • Inicializar la PKI y crear la CA con los comandos ./vars; ./clean-all; ./build-ca
  • Generar el certificados del servidor OpenVPN con el comando ./build-key-server server
  • Para cada cliente que queramos que se conecte, hay que generar un certificado con el comando ./build-key client1
  • Generar el fichero que se usara para el intercambio de claves con Diffile Helman mediante el comando ./build-dh

Con esto ya tendremos los ficheros necesarios.



El único paso restante es mover el certificado del cliente, la clave privada y el certificado de la CA a un único fichero con formato 'p12' para poder integrarlo de manera sencilla con Android. Este fichero debe estar protegido con contraseña.
El comando para crear el fichero es:

openssl pkcs12 -export -in client1.crt -inkey client1.key -certfile ca.crt -name cert-master -out client1-all.p12

Una vez tenemos solucionado la parte de los certificados hay que configurar el servidor OpenVPN mediante el fichero server.conf. Básicamente, lo que hay que configurar son los siguientes parámetros:
  • local X.X.X.X # dirección IP del servidor
  • port 80 # puerto donde escucha el servidor VPN
  • proto tcp # protocolo
  • dev tun # interfaz del tunel (no está en modo bridge) 
  • ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt # ubicacion del fichero de la CA
  • cert /etc/openvpn/easy-rsa/2.0/keys/server.crt # ubicacion del fichero del servidor 
  • key /etc/openvpn/easy-rsa/2.0/keys/server.key # ubicación de la clave del servidor 
  • dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem # ubicacion del fichero del Diffie Hellman 
  • server 172.16.1.0 255.255.255.0 # red asignada al VPN 
  • push "route 0.0.0.0 0.0.0.0" # rutas que irán através del VPN 
  • client-config-dir ccd # directorio con los ficheros que mapean las IPs por usuario/certificado 
  • cipher AES-256-CBC # algoritmos de cifrado simétrico, clave privada, etc
  • comp-lzo # habilitación de la comprension

Aquí hay que destacar que se eligió el puerto 80/TCP en lugar del estándar de OpenVPN 1194/UDP para saltarse los firewalls en los puntos WiFi que estén filtrados. Es cierto que puede existir sitios donde haya filtrado de contenidos en el tráfico web mediante proxys con lo que podría fallar, pero siempre se pueden usar otros puertos.
La ruta 0.0.0.0/0.0.0.0 es necesaria para enrutar todo el tráfico por el VPN y así conseguir nuestro objectivo.

Para configurar el cliente OpenVPN en Android es tan sencillo como importar el fichero p12 a la tarjeta SD y desde la aplicación OpenVPN de Android abrirlo (hay que introducir  la password configurada anteriormente). Luego, a través de las opciones de configuración es necesario seleccionar la IP del servidor VPN, puerto/protocolo y los valores para la clave simétrica: AES con 256 bit en modo CBC.



Con esto ya se tiene configurado el túnel VPN y lo único que falta es implementar las políticas de firewall en ambos endpoints.

En Android es sencillo usar iptables si se tiene acceso a la shell, así pues podemos crear un script con las políticas de firewall con el siguiente contenido:


#!/system/bin/sh
/system/bin/iptables -F
# Aceptamos el tráfico a lo
/system/bin/iptables -A INPUT -i lo -j ACCEPT
/system/bin/iptables -A OUTPUT -o lo -j ACCEPT
# Política por defecto
/system/bin/iptables --policy INPUT DROP
/system/bin/iptables --policy OUTPUT DROP
/system/bin/iptables --policy FORWARD DROP
# Reglas para el tráfico aceptado
/system/bin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/system/bin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED  -p 6 --sport 22 -j ACCEPT
# Tráfico del tunel VPN 
/system/bin/iptables -A INPUT -i tun0 -p 6 --dport 22 -j ACCEPT
/system/bin/iptables -A INPUT -i tun0 -p 1 -j ACCEPT
# Tráfico hacia el endpoint para establecer el túnel
/system/bin/iptables -A OUTPUT -d x.x.x.x/32 -j ACCEPT
# Trafico que va por el túnel
/system/bin/iptables -A OUTPUT -o tun0 -j ACCEPT

Ahora es necesario crear las reglas en el VPS. Estas incluyen reglas para hacer en forwarding del VPN hacia el interfaz público, reglas de NAT para salir a Internet y las políticas de filtrado que en este caso no he aplicado y las dejo a gusto del consumidor:


#!/bin/sh
/sbin/iptables -F
# Tráfico de/hacia localhost y el VPN aceptado
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT
/sbin/iptables -A INPUT -i tun0 -j ACCEPT
/sbin/iptables -A OUTPUT -o tun0 -j ACCEPT
# Política por defecto. 
/sbin/iptables --policy INPUT DROP
/sbin/iptables --policy OUTPUT ACCEPT
/sbin/iptables --policy FORWARD ACCEPT
# Tráfico aceptado hacia los puertos 80 y 443
/sbin/iptables -A INPUT  -i eth0 -p 6 --dport 80 -j ACCEPT
/sbin/iptables -A INPUT  -i eth0 -p 6 --dport 443 -j ACCEPT
/sbin/iptables -A INPUT -p ALL -i eth0 -m state --state  ESTABLISHED,RELATED -j ACCEPT
# NAT / Forwarding para el tráfico del VPN a Internet
/sbin/iptables -A FORWARD -i tun0 -j ACCEPT
/sbin/iptables -A FORWARD -i tun0 -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -j ACCEPT
/sbin/iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


Con esto ya se tiene configurado el túnel, las políticas de firewall en el smartphone para forzar el tráfico a través del túnel y la política en el endpoint para enrutar el tráfico hacia Internet.

lunes, 19 de septiembre de 2011

Debuging (Exploit) Payloads - NcN 2011

Este pasado fin de semana, tal y como ya anuncié, tuve la oportunidad de dar una charla en las Conferencias No cON Name, que como ya sabéis tienen lugar anualmente en Barcelona.


La conferencias fue grabada y añadiré el enlace en cuanto sea publicada, pero mientras tanto os dejo la presentación en PDF para que podáis descargarla, aunque se ve mejor en la grabación que he hecho en video, ya que se ven las transiciones aunque sea rápido:



En la charla se comentó la problemática que nos puede surgir cuando estamos haciendo una auditoría y un exploit falla, las diferentes opciones de por qué un exploit puede fallar, centrándonos en el fallo del Payload.

Se comentaron algunos "trucos" para depurar un Payload y llegar a parchearlo para que funcione correctamente en el entorno que pretendemos explotar. Como ejemplo práctico y real, se realizó una modificación sobre el módulo reverse_http basado en ActiveX de Metasploit, que tras el análisis se determinó que no funcionaba bien en sistemas en idiomas diferentes al inglés debido a un path hardcodeado hacia Internet Explorer. Tras modificarlo se mostró como el Payload funciona correctamente, y por lo tanto ya es posible explotar al objetivo:



En segundo lugar, se mostró otro ejemplo de como podemos depurar el Payload, pero en un entorno completamente diferente. El segundo ejemplo, llamado "Fron JailbreakMe to Jail0wnMe" muestra como a partir de la web "JailbreakMe 3.0", empleada para hacer JailBreak de dispositivos iOS (iPhone y iPad) con versiones inferiores a la 4.3.3, es posible descargar el PDF que explota la vulnerabilidad, analizarlo, y acabar generando un nuevo PDF que tras la explotación ejecuta el Payload que queremos en lugar de instalar el Jailbreak + Cydia, como por ejemplo un reverse shell.



El script empleado para generar el PDF nuevo a partir del PDF original de JailbreakMe 3.0 por el momento he decidido que no será publicado, para evitar su uso masivo por parte de los script kiddies. El que tenga interés por investigar y aprender sobre estos temas, tiene información más que suficiente en la presentación como para reproducir el script y los Payloads, si le dedica el suficiente tiempo, claro.

Gracias a todos los que asististeis a la charla, y a los que no, espero veros a la próxima.

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!