martes, 13 de octubre de 2015

Hackeando el 2FA en Android

Muchos de nosotros hacemos uso del doble factor de autenticación (2FA: two step verification) y recomendamos su uso, ya que es una capa de seguridad más añadida a nuestras contraseñas en cuentas de correo, blogs y otros servicios en Internet. Si es complicado hacerse con nuestras credenciales, más aún poder obtener el código de verificación 2FA. Pero ¿qué pasaría si pudiésemos obtener ambas cosas al mismo tiempo?

En el siguiendo artículo vamos a ver como podemos obtener las credenciales de cuentas de correo electrónico así como los códigos de verificación almacenadas en un terminal Android. Antes de comenzar es muy importante recordar uno de los principios de la Seguridad en Android (vistos en el artículo Metodología de Seguridad en Android) donde para cada aplicación instalada en Android se crea un usuario, de tal forma que una aplicación no puede acceder a la carpeta de otra aplicación. Además dentro de la memoria del terminal tenemos una parte de memoria interna (sólo accede el sistema) y otra de memoria externa o de usuario (sin contar con el almacenamiento SD).

Todo esto está muy bien, pero esta seguridad se rompe en el momento en que rooteamos el teléfono o una aplicación maliciosa ejecuta un exploit el cual utiliza una vulnerabilidad del sistema para hacer una elevación de privilegios y hacerse root, de tal forma que una aplicación con permisos root tendrá permiso para campar a sus anchas y acceder a los ficheros que quiera en la memoria interna. 

Nosotros nos vamos a centrar en dos aplicaciones que podemos encontrar en muchos terminales Android, un gestor de correo y el gestor de 2FA. Las aplicaciones en concreto son:
  • Correo (com.android.email)
  • Google Authenticator (com.google.android.apss.authenticator2)
Una de las grandes vulnerabilidades de las aplicaciones Android que podemos encontrar dentro del TOP 10 Owasp Mobile Risks es el almacenamiento inseguro de datos, este tipo de vulnerabilidad es la segunda más encontrada como podemos ver en el esquema de OWASP.


Como hemos hablado anteriormente, dentro del sistema operativo Android existe una memoria interna en la cual se instalan las aplicaciones, concretamente la ruta es /data/data/ y ahí vamos a encontrar las aplicaciones de la cual queremos obtener información, tal cual como lo haría una aplicación maliciosa que consigue acceso root.

Insecure Data Storage en com.android.email

Esta aplicación de correo electrónico desarrollada por Google la podemos encontrar en muchas distribuciones de Android como parte del sistema operativo, tanto en ROMs de marcas comerciales como también en ROMs cocinadas.

Si nos traemos las todo el directorio /data/data/com.android.email/ podemos encontrarnos con que hay una base de datos SQLite muy interesante dentro del directorio databases: EmailProvider.db


Concretamente dentro de la tabla HostAuth podemos encontrar los correos configurados en el terminal junto con la contraseña en plano, algo increible pero cierto. Si abrimos este fichero con algún programa para visualizar SQLites encontramos lo siguiente:


Aquí no acaba la cosa, el sistema también almacena en texto plano las contraseñas de los correos en texto plano en el siguiente fichero /data/system/users/0/accounts.db 


Bueno ya tenemos los correos electrónicos y las contraseñas, si ahora intentamos acceder a alguno de estos correos nos solicita el 2FA. ¿Cómo hacemos para conseguir el código de verificación teniendo acceso al terminal como root?

Insecure Data Storage en com.google.android.apss.authenticator2

Vamos a ver ahora un caso parecido con la aplicación de Google Authenticator ¿Alguna vez os habéis planteado restaurar vuestro Android de fábrica con su correspondiente Wipe-Data pero no os habéis atrevido porque podéis perder el 2FA? 

Además de eso podemos preguntarnos (por aquello del pensamiento lateral de los hackers) qué ocurriría si copio el directorio completo /data/data/com.google.android.apps.authenticator2 y lo monto en otro terminal, ¿debería dejarme acceder a los códigos de verificación? ¿la instalación del Google Authenticator y los códigos que se generan debería ser única? es decir,si tendría algún tipo de protección por seguridad. Pues bien, la respuesta a estas preguntas es que no tiene protección, podemos hacer lo que queramos

Paso a paso, haremos lo siguiente:

 1. Copiamos la carpeta completa del terminal con la instrucción: 

adb pull /data/data/com.google.android.apps.authenticator2  

 2. Vemos que tenemos dentro tres carpetas: app_sslcache, databases y shared_prefs.

 3. Dentro de la carpeta databases nos centramos en el fichero databases.db y en la tabla accounts obtenemos lo que buscamos, las cuentas asociadas con su código secreto.


Con estos secret keys podemos generar los códigos de verificación asociados a cada una de las cuentas de correo cuyas contraseñas ya teníamos. Pero vamos a probar a montar toda la estructura de directorios en un emulador a ver si funciona el Google Authenticator, para ello primero instalamos la aplicación y acto seguido copiamos todo el directorio completo con las tres carpetas.


Instalamos con adb install <aplicación.,apk> y copiamos todo el directorio al emulador para ver si nos permite así cambiar los códigos de un terminal a otro simplemente con Copy/Paste. En la siguiente imagen vemos como lo permite perfectamente.


Conclusión

Hemos visto como por culpa de fallos a nivel de programación donde se lleva a cabo un almacenamiento inseguro de información sensible, se ven expuestas nuestras contraseñas y los códigos secretos de verificación. Cualquiera de nuestros terminales puede ser víctima de cierta aplicación maliciosa, de una vulnerabilidad de 0day o de una vulnerabilidad no parcheada por nuestro fabricante.

Recomendaciones
  • Actualizar el sistema lo máximo posible, ya que los fabricantes no suelen sacar muy a menudo actualizaciones para forzarnos así a comprar nuevos terminales. Recomiendo en este caso el uso de ROMs cocinadas que parchean los fallos de seguridad a diario
  • Hacer uso de herramientas de control de permisos para impedir a las aplicaciones tener más permisos de los necesarios, de tal forma que podemos así controlar quien accede a que recuersos. Podéis ver herramientas de control de recursos en mi artículo  Privacidad en Android del blog de Hacking Ético (http://hacking-etico.com/2014/08/12/privacidad-en-android/)
  • Hacer uso de herramientas de seguridad como antivirus, antimalware y otras herramientas que te chequean los fallos de seguridad más reciente. Os recomiendo que uséis la herramienta Android Vulnerability Test Suite (https://github.com/nowsecure/android-vts) que os permite testear si tenéis las últimas vulnerabilidades parcheadas.
  • Otras capas de seguridad recomendables serían deshabilitar el ADB (Android Debug Bridge), usar bloqueo de sesión bien con pin numérico de más de 5 dígitos o patrón y sobre todo cifra tu dispositivo por si cae en manos equivocadas. 
Formación en Seguridad Android

Si te interesa la seguridad en Android, los próximos cursos y talleres que impartiré serán los siguientes:


  • Curso Forense en Android ( 29 Enero y 5 Febrero - Modalidad Online): curso totalmente práctico donde llevaremos a cabo el proceso forense de un terminal Android para obtener el máximo número de pruebas. Tocando directorios claves del sistema operativo como de las aplicaciones más utilizadas que nos brindan gran cantidad de información. Más información aquí.
  • Taller Pentesting de Aplicaciones Android (12 Febrero Cuenca - MorterueloCon): taller de 4 horas sobre auditoría de aplicaciones móviles siguiendo la metodología OWASP. Más información aquí.
  • Curso Pentesting en Android (27 Febrero Valencia): un curso presencial muy completo de 8 horas de duración, donde veremos los diferentes puntos del Pentesting en Android para poder auditar aplicaciones, analizar malware e incluso llevar a cabo un análisis forense de un terminal. Más información aquí.



Espero que os haya gustado el artículo y que tengáis presente que la seguridad 100% no existe, sólo podemos añadir cuantas más capas de seguridad mejor.

Un handshake


"Comienza haciendo lo que es necesario, después lo que es posible y de repente estarás haciendo lo imposible"
S.F.d.A.










3 comentarios:

  1. Muy bien explicado todo y la verdad mola mucho!
    Tengo unas dudas: ¿Cámo podrías guardar algo de manera segura y que sea resistente a un teléfono rooteado? En este caso, ¿cómo consigues que la aplicación gmail haga login automático sin guardar credenciales? Token de app? No sería lo mismo al fin y al cabo?
    Para authenticator entiende que la bd debería estar cifrada, pero en algún sitio tienes que guardar la clave de cifrado para poder abrirla...
    Una vez que rooteas el teléfono.. ¿Se puede seguir considerando que en insecure storage por el hecho de poder acceder cuando esta rooteado?

    Gracias

    ResponderEliminar
  2. Buenas preguntas Carlos, te cuento las posibilidades que tenemos para almacenamiento seguro:

    1. Proteger con contraseña el fichero de contraseñas. Esto sería lo siguiente, cifrar con una master key el fichero con información sensible: EmailProvider.db, el accounts.db...y cada vez que se necesite acceder a estos ficheros se deba introducir la contraseña.
    2. Almacenar la información sensible (usuarios y contraseñas) en algún formato no plano, de tal forma que al acceder el programa al fichero, te lo mostraría de manera correcta, oscurecer la contraseña que se llama (seguridad por oscuridad). Esto realmente le da al usuario una falta sensación de seguridad porque el algoritmo para mostrar en plano las credenciales estará en el código de la aplicación y por medio de ingeniería inversa puede sacarse.
    3. Control de acceso a usuarios que quieran acceder a un fichero con información sensible. Este es el método que utiliza Android, donde sólo el usuario de la App en cuestión puede acceder a sus propios ficheros. Inconveniente que tenemos es que al hacernos root se rompe este control de acceso.
    4. No almacenar contraseñas, es decir, la manera más segura de almacenar las credenciales es no almacenarlas e introducirlas cada vez. Lo que se suele hacer es hacer uso de un token de acceso, pero este también tiene que almacenarse.

    Eso es lo que tenemos por el momento, la otra solución sería el uso de algoritmos de clave pública haciendo uso de un Almacen de Claves (Android KeyStore Provider). Os dejo el enlace por si queréis profundizar más.

    https://developer.android.com/training/articles/keystore.html

    Un @handshake

    ResponderEliminar
  3. Ya es un poco mas complejo :(
    com.android.email
    045BW7O/wlTUvH7nNnEklS/V2Vlr1hnEBDynFh87dBw=

    com.google
    oauth2rt_1/Z0u_JgEJ_qeYSWHO0z9V-FSPCxghADgmC26GNGR58Zw

    ResponderEliminar