Análisis de malware en Android
1. Introducción y objetivos
En este artículo vamos a realizar el análisis de un malware muy conocido para Android. Se trata de un “Meterpreter” originado mediante la herramienta “Msfvenom” perteneciente al framework Metasploit.
Quien no conozca lo que es una aplicación “Meterpreter”, decir que se trata de un interprete de comandos que permite interactuar con la máquina víctima, con gran flexibilidad y fiabilidad. En otras palabras, es un malware que da al atacante el control total de la máquina infectada, pudiendo ejecutar comandos, ver la webcam, escuchar el micrófono, entre otras muchas funciones fascinantes. Definiremos lo que es una “sesión meterpreter” más adelante. Recomiendo la lectura del libro “Metasploit para Pentesters”.
Como veremos a lo largo de este artículo, esta aplicación consta de gran cantidad de funcionalidades con objetivos de troyanizar el sistema de la víctima, y de lanzar módulos de post-explotación con los que realizar distintas labores de escalada de privilegios, robo de credenciales, exfiltración de información a un sistema de mando y control (C2), entre otras.
Para conocer el montaje de un laboratorio de análisis, puede consultar en mi artículo “Análisis de vulnerabilidades en aplicaciones Android”.
2. Creación de una apk maliciosa “Android Meterpreter”
Procederemos a realizar un malware con la finalidad de poder analizarlo posteriormente para fines educativos. Para la creación del malware vamos a hacer uso de la herramienta “msfvenom” del framework Metasploit.
A continuación se muestra una captura de cómo crear el malware en cuestión, y cómo una vez creado lo firmamos con la finalidad de que pase ciertos filtros de programas encargados de verificar la legitimidad del origen del nuevo ejecutable, tales como antivirus o sistemas de detección de intrusiones.
Los parámetros que debemos pasar por argumento a “msfvenom” son los siguientes:
- -p : payload que queremos lanzar en la máquina víctima. En este caso hemos elegido que la víctima se conecte a nuestra máquina atacante dándonos su Shell de comandos mediante una sesión meterpreter.
- LHOST: (Local HOST) aquí debemos indicar cuál es nuestra dirección IP, es decir, la de la máquina atacante.
- LPORT: (Local PORT) aquí debemos indicar el puerto de nuestra máquina atacante al que queramos que la víctima se conecte para que nos ceda su Shell de comandos.
- -R > : output. Nombre del archivo de salida. Le indicamos que el nuevo binario creado estará en formato “Raw” (“crudo”). Así nos aseguramos que puede ser flexible a cambios, tal como poderlo firmar con seguridad posteriormente.
Posteriormente vemos cómo a través de la herramienta “d2j-apk-sign” firmamos el malware con la finalidad descrita anteriormente.
3. Análisis de la aplicación malware “Android Meterpreter”
Para dar cumplimiento al análisis de este malware vamos a hacer uso de la máquina virtual “Santoku” para VMware que podemos descargarnos desde su repositorio oficial.
Partimos de la base de que la APP creada en el punto anterior ha sido instalada en nuestro Smartphone.
Realizando un análisis de red del smartphone hemos detectado una conexión a una dirección IP cuyo código está en el paquete “com.metasploit.stage”.
Si vamos a la lista de apps en ejecución de Android (Ajustes → Aplicaciones) podemos ver que efectivamente se está ejecutando una app llamada “MainActivity” cuyo proceso tiene como paquete “com.metasploit.stage”.
Además podemos ver que tras su ejecución se ha recibido una reverse Shell de la máquina víctima (el Smartphone) a nuestra máquina atacante.
Entre las apps instaladas se puede leer una con nombre “MainActivity”. Podemos comprobar cómo al ejecutarla aparentemente no realiza acción alguna, sin embargo vemos que se encuentra en ejecución.
A continuación procedemos a realizar la descarga de la app para su análisis. En el terminal del dispositivo para localizar la app a descargar lanzamos los siguientes comandos:
$ pm list packages | grep meta
package:com.metasploit.stage
$ pm path com.metasploit.stage package:/data/app/com.metasploit.stage/mai.apk
Una vez localizada la ruta donde se encuentra la apk a analizar, procedemos a su descarga en nuestro LAB mediante el comando “adb pull” como sigue a continuación:
$ adb pull /data/app/com.metasploit.stage/mai.apk
[100%] /data/app/com.metasploit.stage/mai.apk
Una vez tenemos la “apk” en nuestro Lab, damos comienzo al análisis.
3.1 Análisis preliminar
Para realizar el análisis preliminar de la app vamos a hacer uso de “drozer”. Aclarar que “drozer” no es una herramienta de detección de malware, sino de vulnerabilidades. Sí que es cierto que puede arrojar información que permita la detección de malware. Una vez ejecutado drozer, podemos obtener información básica de la app, así como la lista de permisos que requiere mediante el siguiente comando:
dz> run app.package.info -a com.metasploit.stage
Package: com.metasploit.stage Application Label: MainActivity Process
Data Directory: /data/data/com.metasploit.stage
APK Path: /data/app/com.metasploit.stage/mai.apk
Permissions:
- Android.permission.INTERNET
- Android.permission.ACCESS_WIFI_STATE
- Android.permission.CHANGE_WIFI_STATE
- Android.permission.ACCESS_NETWORK_STATE
- Android.permission.ACCESS_COURSE_LOCATION
- Android.permission.ACCESS_FINE_LOCATION
- Android.permission.READ_PHONE_STATE
- Android.permission.SEND_SMS
- Android.permission.RECEIVE_SMS
- Android.permission.RECORD_AUDIO
- Android.permission.CALL_PHONE
- Android.permission.READ_CONTACTS
- Android.permission.WRITE_CONTACTS
- Android.permission.WRITE_SETTINGS
- Android.permission.CAMERA
- Android.permission.READ_SMS
- Android.permission.WRITE_EXTERNAL_STORAGE
- Android.permission.RECEIVE_BOOT_COMPLETED
- Android.permission.SET_WALLPAPER
- Android.permission.READ_CALL_LOG
- Android.permission.WRITE_CALL_LOG
- Android.permission.READ_EXTERNAL_STOR
Para conocer los posibles puntos vulnerables de la app podemos hacer uso del comando que sigue a continuación:
dz> run app.package.attacksurface com.metasploit.stage
1 Activities exported
1 broadcast receivers exported
0 content providers exported
0 services exported
La app exporta componentes, por lo que permite que sean invocados desde otras apps externas. Estos componentes podrían ser atacados externamente: una actividad GUI, la cual siempre será exportable para ser ejecutada por el sistema operativo; un Servicio, el cual corre en segundo plano para realizar determinadas tareas; y un receptor de eventos “broadcast receiver” que se encarga de recibir eventos del sistema para procesarlos.
3.2 Análisis del apk
El primer paso consiste en desempaquetar el apk. Esto se llevará a cabo con las herramientas “apktool” y “unzip/dex2jar/jd-gui”. Posteriormente se procede a descomprimir el apk “unzip” y se usa “dex2jar” para poder analizar el código fuente con “jd-gui”.
Una vez ejecutado “dex2jar” sobre “classes.dex”, ya se obtiene el paquete jar que podrá ser usado con “jd-gui” para analizar el código fuente.
No obstante, para realizar todos estos pasos podemos programar un sencillo script, como es el caso de algunas herramientas que podemos encontrarnos en github. Para este caso en particular la herramienta “apkext” nos viene fenomenal. La podemos instalar desde su repositorio que se encuentra en https://github.com/blukat29/apkext.
Tras instalarlo siguiendo las instrucciones de su sitio en github, lanzamos la extracción del apk y vemos cómo nos automatiza todo el proceso.
Una vez desempaquetado el apk y habiendo obtenido el paquete “jar” procedemos a abrirlo con JD-GUI para poder analizar el código fuente.
Aquí ya podemos observar todos los ficheros fuente por los que está conformado el APK. Analizaremos más detenidamente en puntos posteriores.
3.3 Análisis del certificado
Mediante el uso del siguiente comando podemos comprobar la información del certificado usado para firmar la app “mai.apk”.
Como podemos ver el certificado no puede ser validado seguramente debido a que es un certificado autofirmado.
3.4 Análisis del código fuente de la aplicación
3.4.1 Análisis de AndroidManifest
Primeramente vamos a proceder a localizar en el fichero “AndroidManifest.xml” la actividad que contenga el “MAIN”, osea, aquella que tenga establecida la categoría “Android.intent.category.MAIN” ya que serà la que marcará el flujo de la ejecución de la app en cuestión.
En la zona inferior podemos observar el código que buscamos:
<activity Android:label=”@string/app_name” Android:name=”.MainActivity” Android:theme=”@Android:style/Theme.NoDisplay”>
<intent-filter>
<action Android:name=”Android.intent.action.MAIN”/>
<category Android:name=”Android.intent.category.LAUNCHER”/>
</intent-filter>
Como podemos ver dicha actividad tiene el nombre “MainActivity”.
3.4.2 Análisis de MainActivity
Estudiando el código de la clase podemos ver que simplemente ejecuta el servicio “MainService”.
Podemos definir un servicio como un componente que lleva a cabo acciones en segundo plano, y podemos definir tres tipos:
- Programados: se ejecutan tras una programación temporal.
- Started: son ejecutados a través de una Actividad, de una llamada a “startService()”. Una vez han sido iniciados mantienen su ejecución de manera indefinida hasta llamar al método “stopSelf()”.
- Bound: se ejecuta tras ser invocado llamando al método “binService()”. Permanece en ejecución mientras la actividad que lo ha invocado continúe en ejecución.
Analizando el código fuente en cuestión, vemos que el “Servicio” se inicia con la llamada a “startService()”, por lo que el servicio que se lanza es del tipo “Started”, lo cual implica que permanecerá en ejecución de manera indefinida en segundo plano sin que el usuario se percate de su presencia. El servicio “MainService” realiza la llamada al método de la clase “payload” que vamos a analizar a continuación.
3.4.3 Análisis de payload
Como podemos ver el código fuente ha sido ofuscado con la intención de dificultar su entendimiento. Podemos ver cómo a través del método “a(DataInputStream, OutputStream, Object[])” se procede a cargar en memoria una clase que no aparece en todo el paquete apk. Se trata concretamente de “com.metasploit.meterpreter.AndroidMeterpreter”.
Usando ciertos buscadores por Internet hemos podido encontrar el código fuente de esta clase sin ofuscar. Esto nos facilita mucho el estudio del malware. A continuación se pasa a detallar el funcionamiento del código encontrado.
Analizando acorde al flujo de ejecución vemos que tras invocar el método “start” de “Payload”, se introduce como parámetro a través de la función “getFilesDir()” el directorio “/data/data/<paquete>/files” y crea un hilo nuevo para invocar a su método Main.
Como vemos a continuación, “Main” se inicia definiendo ciertas variables con las que posteriormente, dependiendo del valor de la url si empieza por tcp o http, se emplean sus respectivos protocolos y se encargan de abrir canales de entrada y salida para la conexión con un servidor (host), una vez se han generado estos canales (DataOutputStream y DataInputStream in), ambos métodos llaman al método de creación del socket.
Se reproduce a continuación el método de creación de los canales por conexión segura: https.
Ya abierta la conexión, se procede a descargar del servidor una librería (xxxxx.jar), que se guarda en el path obtenido anteriormente, para posteriormente cargarla en memoria.
Aquí vemos cómo se procede a leer el nombre de la clase y a descargar el paquete.
Lee el nombre de la clase a cargar y lo guarda en la cadena “str1”. Posteriormente lee la librería y la guarda como “xxxxx.jar”. Llegados a este punto, la librería es cargada en memoria mediante el uso de un objeto de la clase “DexClassLoader”, que permite cargar librerías “jar” o directamente un “apk” para su posterior ejecución. Se le pasa como parámetro:
- dexPath: la ruta de la librería a cargar (“xxxxx.jar”).
- optimizedDirectory: la ruta donde se generará el fichero “xxxxx.dex” optimizado, partiendo del “xxxxx.jar”
- librarySearchPath: directorio donde se encuentran las librerías nativas.
- parent: es el cargador de clases.
Una vez inicializado el “DexClassLoader” se carga la clase que se ha descargado del host con anterioridad y se crea una instancia de ésta:
- localObject2=((Class)localObject1).newInstance();
Ya con la clase cargada, se pasa a eliminar los ficheros “xxxxx.jar” descargado y “xxxxx.dex” generado como optimización a partir del “xxxxx.jar”. Es una medida para eliminar posibles huellas de la intrusión en el sistema.
- localFile.delete();
- new File(str1).delete();
Finalmente se realiza la invocación de un método con nombre “start” de la clase que se acaba de cargar.
3.4.4 Análisis dinámico de las funciones que realiza la APP
Para poder verificar que realmente se realiza la descarga y eliminación de los ficheros mencionados, vamos a proceder a instalar la APP en el dispositivo mediante el comando “adb install app.apk” y mediante una sesión de shell como root con “adb Shell” vamos a ir comprobando a tiempo real el contenido del directorio donde se supone que todo ello sucede. Vamos a establecer un bucle que nos refresque continuamente el directorio en cuestión para poder verificar con exactitud lo que va ocurriendo a tiempo real.
Lanzamos el comando para la ejecución una vez instalada la aplicación y antes de ejecutar la misma. Por otro lado, ponemos a la escucha metasploit para esperar a la conexión reversa.
root@generic:/data/data/com.metasploit.stage# while true; do > date;pwd;ls files; sleep 0.2; echo “\n”; done
Una vez ejecutado con el escenario preparado vemos que recibimos satisfactoriamente la sesión reverse meterpreter, y que en el directorio se crean ciertas carpetas y archivos.
Ahora vamos a realizar lo mismo pero monitorizando la carpeta “files” que se crea después de la ejecución. Para ello volvemos a dejar el directorio sólo con la carpeta “lib” y procedemos a ejecutar la app “MainActivity”.
Todo ocurre muy rápido. Tras lanzar el bucle esta vez para monitorizar la carpeta “files” situada concretamente en “/data/data/com.metasploit.stage/files”, vemos cómo una vez ejecutada la app “MainActivity” se descargan archivos “.jar”, se optimizan creando los “.dex”. Una vez cargados en memoria y ejecutados, se nos brinda la sesión “reverse meterpreter” y se eliminan los archivos.
Para intentar obtener los ficheros descargados “met.jar” y “payload.jar”, se puede volver a ejecutar otro bucle similar al anterior pero en lugar de ejecutar el listado del directorio, se intentará mover el fichero a otro directorio. Al mismo tiempo se inicia el exploit en el host, que queda a la espera de recibir peticiones por parte del dispositivo móvil, es decir, a que la aplicación sea iniciada.
root@generic:/data/data/com.metasploit.stage# while true; do cp –R files/ /data/;sleep 0.1;done
Así, iniciando la aplicación con el bucle ya arrancado, éste es capaz de copiar los ficheros “jar “al directorio “/data/”, evitando así que sean borrados definitivamente del dispositivo móvil.
Llegados a este punto ya podemos pasar los ficheros a nuestro lab para analizarlos.
3.4.5 Análisis del archivo “sri8sg.jar”
En primer lugar vamos a analizar “sri8sg.jar”, ya que es el primer fichero que se descarga y el que se carga en memoria para su ejecución.
Se descomprime y se transforma el paquete binario “.dex” en “.jar” usando “des2jar”:
Procedemos a cargar en “jd-gui” el fichero resultante:
A continuación podemos ver que el paquete contiene una interfaz llamada “Stage” y una clase, llamada “Meterpreter”. Al igual que anteriormente, éste se ocupa de descargar del servidor el archivo “met.jar”, y proceder a su ejecución.
En el código expuesto podemos ver cómo una vez se ha descargado “met.jar”, se carga en memoria la clase “AndroidMeterpreter”, para posteriormente proceder a invocar a su constructor, y al que se le pasan los parámetros de flujos de entrada y de salida, “DataInputStream” y “OutputStream”, ya abiertos desde la ejecución inicial.
3.4.6 Análisis del archivo “met.jar”
Ahora, al proceder a analizar “met.jar”, podemos ver que contiene la clase “com.metasploit.meterpreter.AndroidMeterpreter”. En el siguiente punto definiremos en profundidad la composición de una sesión “Meterpreter”.
En el lateral Izquierdo podemos percatarnos de las funciones que tiene este malware:
Continuando con el análisis de la aplicación, podemos ver que “met.jar” está compuesto por distintas clases y funciones, entre las que destacan:
3.4.6.1 La clase “AndroidMeterpreter”
Es clase principal del módulo de payload. Es la responsable de coordinar y ejecutar los demás módulos del troyano. Extiende su funcionamiento a la clase “Meterpreter”, responsable de ejecutar los componentes encargados de los canales de flujo de información y el gestor de comandos (CommandManager), entre otros.
Si vamos a ver el código fuente de “Meterpreter” vemos lo siguiente:
3.4.6.2 La clase de gestor de comandos “CommandManager”
Este módulo es el responsable de gestionar los comandos que envía el atacante a la máquina víctima. Cada comando se registra a través de su nombre y de la clase que lo implementa. De no ser un comando definido se lanza el error contenido en “NotYetImplementedCommand”.
3.4.6.3 La interfaz “Command”
Es la encargada de implementar el método “execute” para la ejecución de comandos y de dar el resultado de dicha ejecución.
3.4.6.4 La clase “Channel”
Encargada de establecer la comunicación entre la máquina víctima y el atacante mediante flujos de comunicación abiertos ya estudiados anteriormente: “InputStream” y “DataStream”.
3.4.7 Definición y composición de un “Meterpreter”
Si tuviéramos que definir una sesión “Meterpreter”, podríamos decir que es un framework constituido por varias herramientas ejecutadas como “payloads”. Un “payload” lo podríamos definir como una porción de código malicioso, especialmente desarrollado para ejecutar sus acciones de una manera silenciosa. Normalmente, todo malware cumple con ciertos estándares de comportamiento, instalando en la máquina víctima un programa de un tamaño reducido, encargado de descargar posteriormente del servidor atacante los distintos “payload”, que cargará directamente en memoria para no dejar rastro en el disco de la máquina víctima.
En el ámbito de “Metasploit”, estos programas de reducido tamaño que se instalan en la máquina víctima con la finalidad de descargar posteriormente los módulos “payload” (“stages”) para cargarlos en memoria, se denominan “stagers”. Los “stages” evidentemente son más pesados y son los encargados de dar el control de la máquina víctima al atacante.
Si nos extrapolamos al caso que hemos analizado, podemos afirmar que la APP instalada en el smartphone es el “apk stager”, mientras que el payload descargado “met.jar”, que tras su ejecución da el control de la máquina víctima al atacante, es el “stage”. Así pues, por norma general podemos afirmar que este tipo de malware:
- Está formado por un módulo de reducido tamaño, que es el “stager”.
- El artefacto inicial (“stager”) descarga de un servidor remoto propiedad del atacante, un “payload” para posteriormente cargarlo en memoria.
- Posteriormente a la carga en memoria se procede a eliminar el fichero descargado con la finalidad de eliminar huellas y no dejar rastro. El “payload” o “stage” descargado (en nuestro caso “met.jar”), es de un tamaño mucho mayor ya que porta en su código fuente todas las funciones necesarias para el correcto funcionamiento del troyano.
De esta manera podemos afirmar que en el dispositivo víctima únicamente consta el artefacto (aplicación) inicial de un peso mínimo (pequeño tamaño), y a nivel de conexiones aquellas que se establecen hacia el servidor atacante, la cual cabe destacar que puede usar canales seguros para que la información viaje cifrada, lo que dificultará en gran medida su análisis, pudiendo incluso pasar desapercibido junto al resto de conexiones realizadas por el dispositivo.
Es por ello que a nivel de análisis forense, para encontrar evidencias más claras sobre el código dañino, deberemos realizar un volcado de la memoria RAM del dispositivo con herramientas como “Volatility”, “Autopsi”, “DumpIt”, o “FTK Imager”, según el sistema operativo en cuestión.
4. Conclusiones
Como conclusión sobre el análisis realizado, podemos afirmar que se trata de un malware de administración remota para dispositivos Android, que descarga archivos maliciosos (“payloads”) de un servidor externo, y que emplea técnicas de reflexión para la ejecución en memoria de los “payload” descargados, con la finalidad de no tocar el disco, pasar desapercibida su actividad, y eliminar huellas en los dispositivos de las víctimas.
Este tipo de malware para sistemas Android, normalmente se propaga empleando métodos de ingeniería social, y/o mediante la introducción del código malicioso dentro de una aplicación, con todas las garantías de legitimidad ante los usuarios (firmas digitales, etc.).
En cuanto al impacto que puede llegar a producir un malware de este tipo, decir que conociendo todos los permisos que requiere para su funcionamiento, el impacto negativo (daño) que puede realizar en el dispositivo de la víctima es de un alcance gravísimo.
Para saber más sobre el análisis de malware en Smartphone puede adquirir nuestro curso de “Seguridad y Análisis de Malware en Android”.