Análisis de vulnerabilidades en aplicaciones Android (1)

1. Introducción y objetivos


Según «OWASP Mobile Security Testing» las fases para realizar un pentest de una aplicación móvil son las siguientes:

  1. Recolección: en este paso se obtiene información de la aplicación que se va a analizar. Tipo de app, fabricante, versiones anteriores, recursos que utiliza, etc.
  2. Análisis estático: se realizan labores de ingeniería inversa sobre el propio binario, donde podemos obtener información sobre permisos, actividades principales, recursos, errores de la configuración, puntos de entrada al sistema, información hard-codeada (apikeys o credenciales), etc.
  3. Análisis dinámico: se realizan labores de ingeniería inversa sobre el proceso del binario en ejecución, donde podemos estudiar y obtener a tiempo real información sobre el comportamiento de la aplicación, tal como saber los archivos que crea/modifica/accede en el sistema, datos sin cifrar e información sensible, análisis del log, esnifar tráfico de red generado por la app, realizar «fuzzing» para chequear posibles vulnerabilidades tipo «Buffer OverFlow» (BoF), «SQL Injection» (SQLi), «Cross-site scripting» (XSS), «Local File Inclusion» (LFI), «Remote Code Execution» (RCE), etc.

En este artículo vamos a aprender los conceptos básicos y metodología de análisis estático de aplicaciones Android de manera manual, sin emplear herramientas automáticas de detección de vulnerabilidades. Para ello vamos a hacer uso de un laboratorio de pruebas donde tendremos instaladas las aplicaciones que vamos a auditar.


2. Montando el laboratorio de análisis


Lo primero que debemos hacer es crear y acondicionar un entorno de análisis seguro y adecuado.

Las herramientas que necesitaremos para montarlo son las siguientes:

1. VirtualBox: Para poder montar la máquina virtual y poder hacer el análisis de aplicaciones android bajo entorno seguro. Lo descargamos de su web oficial y lo instalamos sin ninguna complicación.

2. Androl4b: Surfeando por la red podemos encontrar numerosas herramientas para el análisis de aplicaciones Android, y todas ellas se encuentran concentradas bajo una misma máquina virtual (MV) llamada “Androl4b”. Se trata de una máquina virtual basada en el SO Ubuntu, y que está puramente enfocada hacia las características de seguridad en el SO Android. Para ello incluye una colección de herramientas de seguridad, para la ingeniería inversa y el análisis de malware en aplicaciones Android, y entre las que destacan fundamentalmente «Mobile Security Framework» (MobSF), «APKStudio», «ByteCodeViewer», «Drozer», «APKtool», «AndroidStudio», «ClassyShark», «BurpSuite», «MARA», «Wireshark», «FindBugs-IDEA», «AndroBugs Framework» y «Metasploit», entre otras. De esta máquina virtual cabe destacar que funciona perfectamente en VirtualBox pero da ciertos problemas en VMware.



Una vez instalado “VirtualBox”, nos podemos encontrar con los primeros problemas a la hora de arrancar “Androl4b”, particularmente si estamos trabajando bajo un entorno Windows moderno.

Hemos importado la máquina virtual “Androl4b” y vemos en su configuración que no nos deja más que usar MV’s de  32 bits. Si echamos un vistazo al resto de las máquinas que nos deja crear VirtualBox, podemos percatarnos de que sólo nos deja crear y arrancar máquinas de 32 bits.



Esto es un problema porque si nuestra máquina es de 64 bits no nos va a arrancar correctamente.

Pero, ¿Cómo arreglamos esta situación tan sumamente problemática para poder continuar con nuestros objetivos, y poder analizar correctamente y bajo entorno seguro aplicaciones android?

Pues la respuesta a esta gran pregunta es muy sencilla: deberemos seguir unas instrucciones sumamente básicas pero en un orden correcto.

  • Lo primero de todo, y asumiendo que estamos trabajando bajo un entorno Windows, debemos asegurarnos que nuestra máquina sea de 64 bits a través de la ejecución de la herramienta “dxdiag” (hay muchas otras maneras de averiguarlo):


  • Una vez estemos seguros de que nuestra máquina es de 64 bits, debemos chequear si nuestro procesador provee soporte para virtualización. Por lo general los procesadores modernos proveen soporte para 64 bits, y también proveen soporte para virtualización (especialmente los Intel y AMD). Para saber cuál es nuestro procesador y poder averiguar si soporta virtualización, podemos verlo en características del sistema y posteriormente verificarlo fácilmente en la web oficial del procesador.


  • Dando por hecho que los pasos anteriores han sido positivos y que nuestro sistema provee el soporte de virtualización, continuamos. Vamos a la BIOS de nuestra máquina y buscamos bajo las pestaña de seguridad o de configuración una opción que se llame “VIRTUALIZACIÓN”, o algo relativo a ello (también podemos ver “AMD-v” si es un procesador de AMD o “VT-x” si es un procesador de Intel);  la habilitamos y salimos guardando los cambios. Si hemos tenido éxito en el encuentro de esa opción y la hemos habilitado correctamente, veremos cómo al reiniciarse la máquina e iniciar sesión, tras arrancar VirtualBox,  ya nos permite crear e importar máquinas virtuales de 64 bits.

*NOTA: si en nuestra BIOS no encontramos la opción de virtualización y hemos comprobado que nuestro sistema sí que provee ese soporte, entonces deberemos comprobar que nuestra BIOS esté actualizada, y si no lo está deberemos actualizarla desde la web oficial del procesador.

  • Si hemos realizado todos los pasos anteriores correctamente y aún así no hemos tenido éxito en las opciones de 64 bits de VirtualBox, deberemos comprobar que en nuestra máquina no esté corriendo el servicio de “Hyper-V”. Para ello vamos donde se deshabilita este servicio a ver si lo encontramos, y si está habilitado deberemos deshabilitarlo. Procedemos a buscarlo en  “Activar o desactivar las características de Windows”.


Si no lo encontramos ya estará hecho el trabajo, pero si damos con él (igual que podemos ver en la imagen) deberemos desmarcar la carpeta, y asegurarnos que también están desmarcadas las subcarpetas. Una vez realizados estos cambios, aceptamos y veremos cómo Windows se pone a trabajar aplicando los cambios correspondientes. Posteriormente nos llevará a otra ventana con la confirmación de que los cambios han sido completados satisfactoriamente, y entonces deberemos reiniciar nuestra máquina. Cuando se esté reiniciando veremos que Windows trata este cambio como si fuese una actualización. Iniciamos sesión y al arrancar VirtualBox ya podremos ver que nos deja crear/importar máquinas de 64 bits.



Ahora es el momento de ir a VirtualBox y sobre la máquina importada de Androl4b vamos a su configuración y la cambiamos a Ubuntu 64 bits. Iniciamos y vemos que todo va correctamente.

Iniciamos sesión con las credenciales de usuario: «andro» y contraseña: «andro» o «androlab«, y ya tenemos todo listo para empezar a trabajar.



Ya tenemos nuestro laboratorio preparado para realizar el análisis de las aplicaciones que veremos a continuación.


3. Análisis estático del Lab «DIVA»


Este laboratorio llamado «Damn Insecure and Vulnerable App» (DIVA), esta compuesto por un paquete de aplicaciones android programado intencionadamente para ser vulnerable, y dar a conocer a los desarrolladores y profesionales de la seguridad, las vulnerabilidades más comunes en las aplicaciones, debido a las prácticas de codificación pobres o inseguras.


a) Preparación del emulador


Antes de todo iniciamos el emulador desde el terminal con el comando “android avd” y la password “1234”:



Para poder analizar esta aplicación primeramente, y trabajando bajo el entorno de Androl4b, nos descargamos la aplicación desde http://www.payatu.com/wp-content/uploads/2016/01/diva-beta.tar.gz, la descomprimimos y la instalamos en el emulador.



A continuación ejecutamos la aplicación Diva desde el emulador, y podemos ver su interfaz:



Ahora ya estamos listos para comenzar a analizar esta apasionante aplicación. Necesitaremos estar en posesión de las herramientas actualizadas de «dex2jar», «JD-GUI», «APKTOOL» y «Drozer». Además de las utilidades de android para manejarnos con el emulador (adb, sqlite3…) que ya vienen por defecto en Androl4b.


b) Obteniendo archivos fuente de la aplicación


Descargamos e instalamos “dex2jar”, y descomprimimos el “.apk” a analizar para poder obtener el código fuente desempacado de la aplicación, como sigue en la siguiente imagen.



Una vez obtenido el “.jar” de la app, procedemos a la descarga e instalación de “JD-GUI” desde su web oficial “jd.benow.ca”, y abrimos el archivo “diva-beta-dex2jar.jar” con el “JD-GUI”. De esta manera obtendremos el código fuente a través de los archivos “.java” que conforman la app a analizar.



Llegados a este punto, debemos obtener a través de la herramienta “apktool”, el archivo “AndroidManifest.xml”. Este archivo nos proporcionará información muy valiosa sobre la estructura interna del programa.




Una vez obtenidos todos los archivos que conforman a “DIVA”, ya podemos ponernos manos a la obra y empezar a analizarla.


c) Analizando «Insecure Logging»


Vamos a empezar por la app “Insecure Logging”. Se nos solicita que ingresemos nuestro número de tarjeta de crédito, y nuestro objetivo es averiguar la inseguridad que presenta. Pues bien, decir que en android por norma general se registra la información en un «logcat», y será aquí donde encontraremos nuestros datos introducidos. Posteriormente buscaremos errores de programación en los distintos códigos fuente obtenidos anteriormente, para poder corregirlos y parchear las vulnerabilidades encontradas.

Mediante el uso del comando “adb logcat” podemos ver todo lo que se «loggea» bajo el entorno de android del emulador, y al introducir nuestros datos podemos observar que son transferidos y registrados en texto claro (sin ningún tipo de cifrado), por lo que cualquier atacante puede hacerse con ellos, con las graves consecuencias que eso puede conllevar.



Es el momento de ir al código de la aplicación que ya tenemos abierto con “JD-GUI”. Si vamos a “LogActivity.class” podemos ver lo siguiente:



Como podemos observar, el error está en registrar el error de la transacción junto al número de la tarjeta de crédito introducida. Si eliminamos esa línea del código el error quedará subsanado.


d) Analizando «Hardcoding Issues»


A continuación procedemos a analizar la siguiente app “Hardcoding Issues – Part 1”. El objetivo es ver los fallos de seguridad que presenta la app para que podamos averiguar la “vendor key”, y poder acceder a la aplicación con privilegios de administrador. Para ello vamos a estudiar el código fuente obtenido anteriormente, hasta llegar a un punto donde podamos interceptar la vulnerabilidad.



Como podemos ver, en la función «access()» se compara el texto introducido por el usuario con la cadena “vendorsecretkey”, que es la password correcta y por tanto la que nos da acceso positivo.



e) Analizando «Insecure Data Storage 1»


En este apartado vamos a analizar la app “Insecure Data Storage 1”.  El objetivo es encontrar, a través del estudio del código fuente, dónde se almacenan las credenciales en el sistema y de qué manera (encriptadas, en texto plano, etc.).

Vamos a la aplicación e introducimos nuestro usuario y contraseña, y al pulsar “SAVE” vemos un mensaje que nos confirma que las credenciales han sido guardadas correctamente. Posteriormente, si vamos al código fuente de la app en “InsecureDataStorage1Activity.java”, observamos que la función «saveCredentials()» guarda en “DefaultSharedPreferences” las credenciales.



Físicamente en el dispositivo, la ruta “DefaultSharedPreferences” la encontramos en “/data/data/jakhar.aseem.diva/shared_prefs”, así que vamos navegando con “adb shell” por el interior del dispositivo, y al llegar a ese directorio nos encontramos con el archivo “jakhar.aseem.diva_preferences.xml”. Al abrir dicho archivo nos encontramos nuestros datos almacenados en texto plano.



Como podemos observar se trata de un fallo de seguridad de almacenamiento de credenciales gravísimo, y que sucede por un descuido en la programación del código, más a menudo de lo que podríamos imaginar.


f) Analizando «Insecure Data Storage 2»


Ahora vamos a analizar la app “Insecure Data Storage 2”. Aquí el objetivo es exactamente el mismo que el del “Insecure Data Storage 1”.

Sin más preámbulos nos ponemos manos a la obra. Ingresamos usuario y contraseña, y vamos al código fuente de la aplicación para buscar el lugar donde se almacenan las credenciales introducidas, y de qué manera.



Con un simple golpe de vista podemos observar que las credenciales se almacenan en una base de datos. Si vamos al directorio de “jakhar.aseem.diva” (que es donde está instalada la aplicación en el dispositivo), podemos encontrar la carpeta “databases” que es el directorio de bases de datos de la aplicación.



Vemos que hay varias bases de datos, vamos abriendo una por una con “sqlite3”, y navegamos hasta que llegamos a ver nuestras credenciales introducidas anteriormente en texto plano:



Como podemos observar, con unos pocos conocimientos de la arquitectura del sistema y de BBDD, hemos sido capaces de vulnerar el sistema de almacenamiento de datos.


g) Analizando «Insecure Data Storage 3»


A continuación pasamos a analizar la siguiente app “Insecure Data Storage 3”. El objetivo nuevamente es averiguar dónde se almacenan las credenciales introducidas y cómo obtenerlas.

Como podemos ver en el análisis del código fuente se crea un archivo temporal con el nombre de “uinfo+nº identificacion” en el directorio por defecto.



Comprobamos que al pulsar el botón SAVE y confirmarnos que las credenciales han sido almacenadas satisfactoriamente, se ha creado un archivo temporal con el nombre “uinfo+identificador” en el directorio del paquete “jakhar.aseem.diva”. Este archivo es el que contiene nuestras credenciales en texto plano.



h) Analizando «Insecure Data Storage 4»


A continuación, y con mismos objetivos de operación, vamos a proceder a analizar la app “Insecure Data Storage 4”.

Estudiando el código fuente podemos percatarnos de que las credenciales se guardan en el almacenamiento externo, en un archivo con el nombre “.uinfo.txt”. Sin perder más tiempo procedemos a comprobar que dicho archivo está donde dice estar, y que existe y contiene en su interior nuestras credenciales.



Aquí observamos la localización del archivo “.uinfo.txt” y su contenido en texto plano.



Podemos ver que la seguridad brilla por su ausencia en estos cuatro últimos casos expuestos, y lamentablemente no se trata de casos aislados ya que estas fallas de seguridad han sido descubiertas en numerosas aplicaciones android.


i) Analizando «Input Validation Issues 1»


Se trata de una app vulnerable en cuanto a la validación de los datos introducidos, en este caso en un campo de búsqueda. Vamos directos al código fuente para ver qué es lo que hace, y encontrar la manera de vulnerarla.



Con un simple golpe de vista vemos en el código fuente todos los usuarios y contraseñas, además de sus números de tarjeta de crédito. Sin embargo, nuestro objetivo en esta aplicación es el averiguar cómo vulnerar la búsqueda en la base de datos, a través de la introducción de caracteres en el campo de búsqueda que nos brinda la aplicación. Así pues, podemos ver en la búsqueda que se realiza según el código de la app, que con un simple “ 1’ or ‘1’=’1’– “ conseguimos todas las credenciales almacenadas. Se trata de la vulnerabilidad más conocida de «SQL Injection».



Este fallo de seguridad se soluciona con una simple función de sanitización de los caracteres introducidos en el campo de búsqueda.


j) Analizando «Input Validation Issues 2»


Ahora vamos a pasar a analizar la app “Input Validation Issues 2” con el objetivo de encontrar vulnerabilidades. Vamos al código fuente a ver qué podemos averiguar.



Podemos ver que no hay ningún tipo de saneamiento de los datos introducidos, por lo que nos ejecutará cualquier ruta que pongamos en el campo de la app como si de un browser se tratara. De esta manera podremos ver el contenido de archivos almacenados en el dispositivo, así como conectarnos a webs y a servidores FTP, entre otras cosas.

Para comprobar que efectivamente podemos leer información sensible del dispositivo sin ningún problema, vamos a introducir la ruta de un archivo “file:///mnt/sdcard/.uinfo.txt” que contiene información sensible, y veremos cómo nos hace un volcado de su contenido sobre la pantalla.



Como podemos ver se trata de un fallo muy grave de seguridad, que se soluciona aportando en el código fuente una función sencilla de saneamiento de los caracteres introducidos, para que únicamente permita “ejecutar” las direcciones que empiecen por “http” o “https”.


k) Analizando «Access Control Issues 1»


A continuación pasamos a analizar la app “Access Control Issues 1”. El objetivo es acceder a las credenciales de la aplicación desde fuera de la aplicación, saltándonos los accesos de control. Sin perder más tiempo vamos directos al código fuente y lo analizamos.



Vemos que al pulsar el botón “VIEW API CREDENTIALS” se acciona el “intent” “jakhar.aseem.diva.action.VIEW_CREDS”. Así pues, si lo llamamos desde “adb shell am start -a”  iniciando el “intent” podemos observar que efectivamente no hay ningún filtro de acceso de control, y podemos acceder directamente a las “API CREDENTIALS”.



 Ejecutamos la línea de comando y vemos que nos brinda en pantalla las API CREDENTIALS.



l) Analizando «Input Validation Issues 2» con Drozer


Ahora pasamos a analizar la app “Access Control Issues 2”. El objetivo es acceder a las credenciales directamente saltándonos los filtros de seguridad de introducir un número pin correcto.



En la imagen anterior podemos observar cómo en el código fuente se hace la llamada a “jakhar.aseem.diva.action.VIEW_CREDS2”, chequeando el número pin introducido para devolvernos las credenciales o el mensaje de error.

Si continuamos brujuleando el código fuente de la aplicación, podemos ver cómo en “jakhar.aseem.diva.APICreds2Activity” se hace el chequeo del número pin introducido y si el valor es “true” nos devuelve el mensaje de “error”; sin embargo, si el resultado es “false” nos devuelve en pantalla las credenciales que tanto queremos conseguir.



A continuación vamos a necesitar hacer uso de “drozer”, una herramienta que nos permite ejecutar comandos con los parámetros y valores que nosotros estimemos oportunos. Nos permite poder “inyectar código”.

Para descargar “drozer” e instalarlo en nuestra máquina, y para descargar “agent.apk” e instalarlo en el emulador, lo podemos obtener desde la siguiente web: https://labs.mwrinfosecurity.com/tools/drozer

En nuestra máquina “androl4b” nos viene instalado “drozer” por defecto, pero necesitamos descargarnos de la web anteriormente mencionada el archivo “agent.apk” para instalarlo en el emulador y poder usar “drozer”.



Ahora ejecutamos “drozer” en el emulador y nos conectamos desde la máquina virtual a través del comando “drozer console connect”. Así obtenemos Shell de drozer, lista para introducir comandos e inyectar ese código que debemos introducir para saltarnos los filtros de seguridad del número pin, y conseguir las credenciales.



Necesitamos realizar una inyección de código de tal forma que el chequeo del “pin” nos dé un valor “false”, y así poder conseguir las credenciales. Esto lo podemos hacer ejecutando en la consola de “drozer” el comando “run app.activity.start –component jakhar.aseem.diva jakhar.aseem.diva.APICreds2Activity –extra boolean check_pin false”. Una vez ejecutado el comando, podemos ver en la imagen cómo se nos devuelven las credenciales en la pantalla del emulador.



m) Analizando «Input Validation Issues 3» con Drozer


Ahora pasamos a analizar la app “Access Control Issues 3”. El objetivo es acceder a las credenciales directamente saltándonos los filtros de seguridad sin introducir un número pin correcto.



Lo que debemos conseguir son las siguientes credenciales que se obtienen tras introducir el número pin correcto:



Sin perder más tiempo vamos directamente a analizar el código fuente. En él podemos observar el mensaje de error “Please Enter a valid pin” y al final del code vemos lo que más nos interesa; se accede a “AccessControl3NotesActivity.class”.



Vamos a estudiar el código fuente de “AccessControl3NotesActivity.class”, y en él podemos observar cómo al haber obtenido un número pin válido se accede a mostrar en pantalla las credenciales, a través de la llamada “getContentResolver().query(NotesProvider.CONTENT_URI,)”



(Aquí podemos ver la llamada)



Si vamos al source de NotesProvider y buscamos el valor de “CONTENT_URI” podemos ver que su valor es “content://jakhar.aseem.diva.provider.notesprovider/notes”. También podemos ver desde aquí la base de datos a la que se debe hacer la consulta, una vez el número ”pin” haya sido correcto tras la validación.




Estando en posesión de todos estos conocimientos, ya podemos hacer nuestra consulta a la base de datos a través de “drozer”, para obtener los resultados sin falta de introducir ningún “pin” correcto, por lo que nos saltamos así los filtros de seguridad.



De la misma manera podemos hacer la consulta a través de “adb shell”, como sigue en la imagen obteniendo mismos resultados.



Una vez acabado con el análisis de las app’s de “Access Control Issues” damos paso al análisis de la última aplicación de interés de este laboratorio.


n) Analizando «Hardcoding Issues 2»


En la app “HardCoding Issues part 2” el objetivo es averiguar a través del código fuente, dónde está y cuál es la contraseña con la que poder obtener el acceso.



Estudiando el código fuente de esta aplicación podemos ver que se hace una llamada a “Divajni()”, concretamente a la función “access”.



Sabiendo esto vamos directamente a ver el código fuente de “Divajni”, que lo encontramos en el panel de códigos de la izquierda. Aquí podemos encontrar la función access() a la que se llamaba en el código anterior, y al final del código podemos ver que se invoca a la librería “divajni.so”. Ahora este es nuestro objetivo, encontrarla y acceder al contenido de la librería “divajni.so” donde se encuentra nuestra clave de acceso.



En los “resources” de la aplicación podemos encontrar la carpeta “lib” donde se encuentran las librerías de la aplicación, y entre ellas encontramos a “libdivajni.so”:



Una vez tengamos localizado el archivo “libdivajni.so”, procedemos a realizar un volcado en pantalla de la sección “.rodata” con “objdump”. Como breve explicación decir que la sección “.rodata” es una sección de datos donde se almacenan valores de constantes, y se colocan los datos iniciados. Destacar que en la sección “rodata” los datos nunca son modificados.

Para poder realizar un volcado de dicha sección empleamos el comando como sigue en pantalla “objdump –s –j .rodata libdivajni.so”, o también podemos obtener los mismos resultados a través del comando “readelf –x .rodata libdivajni.so”. De esta manera podemos observar que hemos obtenido una cadena de caracteres: “olsdfgad;lh..dot”. Al introducir esta cadena de caracteres en el campo de la contraseña, podemos ver que efectivamente es la contraseña correcta y obtenemos el acceso correctamente.


Android
Android

4. Conclusiones


Llegado a este punto damos por finalizado el análisis realizado a las Apps de este laboratorio DIVA. Hemos realizado un análisis estático de las apps del laboratorio, estudiando el código fuente paso a paso, llegando a explotar numerosas vulnerabilidades obteniendo los resultados esperados.

Según el “Mobile_Top_10” de OWASP, hemos explotado las siguientes vulnerabilidades:

1. Improper Platform Usage

2. Insecure Data Storage

4. Insecure Authentication

5. Insufficient Cryptography

6. Insecure Authorization

7. Client Code Quality

9. Reverse Engineering

Para comprobar las vulnerabilidades explotadas a lo largo del análisis de todas las App’s estudiadas en el laboratorio DIVA, podemos hacer uso de la “OWASP Mobile Checklist”.


En el próximo artículo (parte 2), veremos cómo realizar un análisis dinámico de una aplicación Android que simula una App bancaria. Veremos cómo estudiar el tráfico de red viendo las conexiones entrantes y salientes que realiza, además de sus distintas metodologías de autenticación, entre otras cosas.

No puedes copiar el contenido