lunes, 6 de marzo de 2017

Pentest a Android Apps - Una guía útil


Entre varios libros que me traje de DefCon 24 (2016) se encuentra uno llamado Android Security que terminé de leer esta semana, su contenido me pareció muy práctico, sin embargo, ese no fue mi primer contacto con este topic. A finales de 2015 aprendí a programar aplicaciones para Android y enseguida comencé a envolverme en las técnicas de ataque y defensa sobre esta plataforma. Ya he escrito algunas notas respecto de pentest a aplicaciones Android, y también di una charla sobre malware en estos dispositivos.

Esta vez quiero escribir una nota dedicada especialmente al pentester que trabaja de esto pero nunca ha auditado una aplicación Android y sabe que en cualquier momento (si es que no le ha pasado ya) le puede caer un cliente con: ¡Acabamos de crear una versión de nuestra App para Android! ¿Podemos incluirla en la auditoría? :)

Me concentraré en responder las siguientes preguntas claves: ¿Qué es lo indispensable que necesito saber de Android en sí? ¿Cuáles son los componentes de una App Android? ¿Qué debo auditar en cada uno de esos componentes y cómo hacerlo? y por último: ¿Qué herramientas pueden facilitarme el proceso?.


¿Qué es lo indispensable que necesito saber de Android en sí?

Android usa el kernel de Linux, sin embargo no es un Linux tradicional. Hay muchos binarios y archivos que no están, ya que, se modificó para ser minimalista y ejecutarse en entornos embebidos.

Dentro de este hecho, hay algo que tenemos que saber: Android tomó de Linux su sistema de permisos basado en usuarios y grupos. ¿Para qué? ¿No es acaso un dispositivo Android usado generalmente por un solo usuario? Si, pero Android implementó este sistema sobre el filesystem y las aplicaciones, cumpliendo los siguientes objetivos:

  • Proteger los archivos del sistema, de manera que no puedan ser accedidos ni por el propio usuario del dispositivo (salvo que lo rootee) ni por las aplicaciones instaladas.  
  • Proteger los datos de las aplicaciones instaladas, de manera que una aplicación no pueda acceder a la información de otra aplicación.

Es indispensable entender bien ese último punto. Cada vez que el usuario instala una aplicación en su dispositivo, un nuevo usuario es creado por el sistema para esa aplicación.  Dicho usuario será el dueño del proceso de esa aplicación cada vez que la misma se ejecute, también, ese usuario será el único que tenga permisos de acceso a las carpetas propias de esa aplicación, las cuales se encuentran en: /data/app/<nombre_app>/ y /data/data/<nombre_app>/.

En /data/app/<nombre_app>/ se encuentran los archivos fuente de la aplicación, mientras que en /data/data/<nombre_app>/  se encuentran los datos del usuario pertenecientes a la misma. Por ejemplo en el caso de WhatsApp, en /data/data/com.whatsapp/ se encuentra la clave con la que es cifrada la base de datos de nuestros chats. Entonces, siguiendo este ejemplo, debe quedar claro que ninguna otra aplicación puede acceder a las carpetas de WhatsApp en /data, ya que como bien dijimos, solo el usuario owner de cada app tiene los permisos de acceso a las carpetas propias de la misma.

Hay mucho más para hablar sobre el aislamiento de los procesos a través de las máquinas virtuales de Android (Dalvik/Art), el Android IPC, etc. Pero en lo que a Pentest respecta, esto es lo que considero indispensable de saber sobre Android en sí.


¿Cuáles son los componentes de una App Android?

Una aplicación Android viene comprimida en un paquete .apk en cuyo interior encontraremos -entre otros archivos- un classes.dex que contiene todas las clases Java de la aplicación. Estas clases pueden contener código relacionado a uno o más de los siguientes componentes principales de una App Android:

  • Activities: es un componente gráfico, simplemente, cada ventana de la aplicación. 
  • Services: una aplicación puede tener un servicio de si misma que se ejecute permanentemente de background en el dispositivo. 
  • Content Providers: le permiten a una aplicación exponer datos propios (los que se quieran) para que otras aplicaciones puedan accederlos y utilizarlos.
  • Broadcast Receivers: una aplicación a través de "Intents" puede "estar atenta" a ciertas acciones que se producen en el dispositivo (encendido, llegada de un mensaje o llamada, etc.) el broadcast receiver de una aplicación contendrá lo que se desea ejecutar cuando se produzca un "Intent" al que debe responder.

¿Qué debo auditar en cada uno de esos componentes y cómo hacerlo?

Aunque una aplicación Android se compone por varios componentes, en principio vamos a tratarla como una "única cosa". Luego veremos algunas cuestiones puntuales a revisar en ciertos componentes.

Comencemos con algo tan simple e indispensable como entender qué hace la aplicación que estamos analizando y con ello descubrir cuáles serían los potenciales vectores de ataque que vamos a revisar. ¿Existen formularios de autenticación? ¿La aplicación se conecta a internet? ¿Se solicita información sensible al usuario? Son algunas de las preguntas a responder en este momento.

Podemos ejecutar la aplicación en un emulador -recomiendo GenyMotion- sin embargo, siempre que podamos es recomendable usar un dispositivo real, así nos aseguramos que todas las funcionalidades de la aplicación se están ejecutando correctamente.

A continuación, una serie de puntos a auditar sobre la aplicación:

  • Autenticación: todas las revisiones típicas como el testeo contra fuerza bruta, testeo de las opciones de recuperación del password, revisión de que las credenciales se manden por https (si es que se autentica contra un server online) y demás, deben ser atendidas en este punto. Algo adicional a tener en cuenta, es que en una aplicación de Android podría pasar que el activitie que se muestra al usuario después del login pueda ser accedido si se lo invoca directamente, permitiéndose un bypass de la autenticación. Al final del artículo mencionaré una herramienta que nos ayudará a revisar este punto.
  • Criptografía: no solo es necesario revisar que los datos que la aplicación está enviando a un servidor online (si es que lo hace) lo haga por HTTPs o un canal cifrado, sino también debemos asegurarnos que la criptografía esté implementada correctamente utilizando de forma segura un algoritmo dentro de los estándares, en lugar de uno inventado por el programador, cosa que se suele hacer. 
  • Almacenamiento de datos: como ya mencionamos, al instalar una app Android se crea una carpeta en /data/data/<nombre_app> cuyo fin es almacenar los datos del usuario pertenecientes a esa aplicación. Al ser almacenados allí, se protegen de que otras aplicaciones accedan a tales datos ya que las mismas no tienen los permisos para hacerlo. En nuestra auditoría tenemos que revisar que la aplicación efectivamente almacene los datos sensibles dentro de esa partición y no en la memoria externa u otro lugar que pueda ser leído por el resto de las aplicaciones. 
  • Exposición de información: una aplicación Android puede utilizar los contents providers para compartir "con el exterior" la información que maneja. Debemos asegurarnos que si este mecanismo se está utilizando, la información expuesta es realmente la que se quiere exponer y no se revela información sensible del usuario.
  • Validación de entradas: un content provider es una base de datos SQLite, por lo tanto, debemos revisar que las consultas se validen correctamente antes de ser ejecutadas en el gestor. Lo mismo para cualquier otra entrada de datos a través de formularios.
  • Información sensible en parámetros de URL: si la aplicación se comunica con un server online, debemos asegurarnos que en esas comunicaciones no se envíe información sensible del usuario a través de los parámetros de la URL que se está llamando.
  • Gestion de logs y errores: es típico que durante la etapa de desarrollo los programadores arrojen al log distinta información que se va generando en el uso de la aplicación. Muchas veces esa información está relacionada a contraseñas u otros datos sensibles. Es un error típico de los programadores no quitar esas líneas cuando la aplicación ya está en producción, debemos asegurarnos de que esto no esté ocurriendo.
  • Datos sensibles hardcodeados en el código: algo muy común, es encontrarse con datos sensibles tales como contraseñas, hardcodeadas dentro del código de la aplicación. ¡grave error!. En este caso, mas que reportarlo, hay que asesinar al programador (?.
Hasta acá hemos visto muchas cosas que ya estamos acostumbrados a testear en cualquier otro tipo de aplicación (web u desktop) y es así, mucho de lo que ya estamos acostumbrados a revisar en nuestras auditorías podremos revisarlo en estas aplicaciones de la misma forma con las herramientas que funcionan sobre esta plataforma.

Puntualmente sobre los componentes propios de una aplicación Android, debemos tener en cuenta que los contents providers son bases de datos que pueden sufrir ataques SQL. Los activities pueden ser fácilmente saltados evadiendo sistemas de autenticación. Los broadcast receivers / intents y llamadas vía Android IPC, no deben ser utilizados para pasar información sensible. Esas son las cosas que quizás debemos revisar y no estamos acostumbrados a tratar, ya que son componentes propios de las aplicaciones Android. Drozer, una herramienta que citaré al final de la nota, puede ayudarnos a testear fácilmente todas estas cosas.

Si estamos haciendo una revisión de código podemos revisar también, que dentro del mismo no se encuentren vulnerabilidades conocidas de Java.


¿Qué herramientas pueden facilitarme el proceso?

Bien, en principio un emulador como GenyMotion es indispensable si no disponemos de un dispositivo físico para analizar la aplicación.

La herramienta adb (android debug bridge) no nos puede faltar para comunicarnos fácilmente con el dispositivo (emulador o físico) y subir y bajar información del mismo.

La herramienta BurpSuite puede ser utilizada como proxy para interceptar y revisar las comunicaciones HTTP/s. Simplemente debemos configurar como proxy en el emulador, la IP de nuestro equipo donde tenemos corriendo el BurpSuite. En caso de que la aplicación utilice otro protocolo fuera de HTTP/s, podemos utilizar WireShark de la misma forma.

Si queremos descompilar la aplicación podemos usar dex2jar, apktool, bytecode-viewer o APKStudio.

Una herramienta excelente para hacer pentest a aplicaciones Android y a la que le he dedicado una nota completa es Drozer: http://www.semecayounexploit.com/?sec=android-hacking&nota=6.


Bueno, se hizo bastante larga la nota, y no puse ni una sola imagen para agradarles la vista xD si llegaron a leer hasta acá se los agradezco mucho y espero que les sea de gran utilidad la información. Traté de resumir lo más posible, quizás no me extendí en algunas cosas importantes ¡pero lo fundamental está! ¡nos leemos pronto en otro post!.

Author: Sheila A. Berta.
Tw: @UnaPibaGeek.
Web: www.semecayounexploit.com.

No hay comentarios.:

Publicar un comentario