En esta entrada vamos a ver un pequeño ejemplo de como podría ocultarse un Malware de Android de cara al usuario.
1. La muestra
Hemos elegido un malware muy sencillo que tiene el código bastante legible desde el punto de vista de un reversing. Se identifica con el hash SHA256 48618153df1b2b5be3f83e6e1fa6aa5f517b173b10f3f6e925d1598a22b459e1. Lo hemos obtenido del repositorio AndroidMalware_2019. Según el nombre que le ha dado el repositorio, Brazilian_androRAT, debe de tratarse de un Malware de origen Brasileño.
2. Información pública.
Partimos de la situación de que nos envían un fichero apk llamado 48618153df1b2b5be3f83e6e1fa6aa5f517b173b10f3f6e925d1598a22b459e1.apk y nos piden que veamos si realiza alguna actividad maliciosa. El primer paso será ver si existe información pública de este hash. En Google solo obtenemos 10 resultados sobre repositorios donde se encuentra o reportes de escáneres automáticos.
VirusTotal tiene los siguientes resultados:
Parace que el malware es detectado por muchas casas de antivirus, aun así siguen habiendo antivirus que no lo detectan. Las casas que lo detectan identifican la familia como «Brata»
Buscando información sobre Malware RAT de Android de origen Brasileño y BRATA podemos ver algunos portales de noticias que se hacen eco de este malware. Según estas noticias el malware se hace pasar por una actualización de Whatsapp y una vez ejecutado explota una vulnerabilidad conocida de Whatsapp con el CVE 2019-3568, desbordamiento de búfer en la pila VOIP, vulnerabilidad de Alta gravedad que permite ejecución remota. Sorprende que el Malware estuvo alojado en la Play Store durante un tiempo.
3. Análisis estático
Vamos a lo que nos atañe a nosotros como técnicos de seguridad. En primer lugar vamos a descomprimir el apk, mediante un script para automatizarlo y no tener que acordarnos de los comandos cada vez que decompilemos un apk:
#!/bin/bash APK=$1 unzip -q $APK -d ${APK}_unzip apktool d $APK -o ${APK}_apktool jadx $APK -d ${APK}_jadx
Llamaremos al script de la forma:
./apk_extractor 48618153df1b2b5be3f83e6e1fa6aa5f517b173b10f3f6e925d1598a22b459e1.apk
Ya tenemos el código listo para analizar. En principio vamos a usar la versión gráfica de jadx para analizar el código (esto lo decompila y lo aloja en memoria):
jadx-gui 48618153df1b2b5be3f83e6e1fa6aa5f517b173b10f3f6e925d1598a22b459e1.apk
Con jadx-gui se crea un proyecto de la decompilación, luego todas las acciones que realicemos se pueden guardar para recuperarlo más tarde. Acciones que podemos guardar: el renombre de funciones, nivel de desofuscación, preferencias, etc. El proyecto de desofuscación se guarda como un fichero con extensión .jobf.
Permisos
Observando el fichero principal AndroidManifest.xml vemos que tiene los siguientes permisos declarados:
<uses-permission android:name=»android.permission.INTERNET»/>
<uses-permission android:name=»android.permission.WRITE_EXTERNAL_STORAGE»/>
<uses-permission android:name=»android.permission.REQUEST_INSTALL_PACKAGES»/>
<uses-permission android:name=»android.permission.REQUEST_DELETE_PACKAGES»/>
Se puede observar que pide permisos para instalar (REQUEST_INSTALL_PACKAGES) y desinstalar (REQUEST_DELETE_PACKAGES) aplicaciones, permisos para abrir sockets a internet (INTERNET) y escribir en la tarjeta SD (WRITE_EXTERNAL_STORAGE).
Entry Points
Dentro del nodo <application> vemos un Servicio y una Actividad declarados:
Debido al intent filter declarado (en la entrada Android Malware II. Basics. hablamos de los intents filters) sabemos que esta actividad se ejecuta al pulsar el icono del app:
<intent-filter>
<action android:name=»android.intent.action.MAIN»/>
<category android:name=»android.intent.category.LAUNCHER»/>
</intent-filter>
En este caso tenemos una sola actividad pero si hubiesen muchas, esto nos ayuda a situarnos en el punto de partida. En cuanto al servicio vemos que también tiene un intent filter:
<intent-filter>
<action android:name=»android.accessibilityservice.AccessibilityService»/>
</intent-filter>
<meta-data android:name=»android.accessibilityservice» android:resource=»@xml/accessibility_service_config»/>
Vemos que el servicio esta configurando un servicio de Accesibilidad, que de cara a la seguridad, es un servicio crítico ya que con los servicios de accesibilidad de Android puedes hacer muchas cosas sin depender el usuario. La etiqueta «meta-data» sirve para configurar los tipos de eventos de accesibilidad mediante un archivo xml que lo encontramos entre los archivos de la decompilación.
Resumiendo los entry points que tenemos:
- Launcher Activity: irifix.MainActivity
- Servicio: irifix.AccService – Cuando se lanza un intent con la acción AccessibilityService
Launcher Activity
Como se trata de una Actividad, la primera función que se ejecuta es onCreate(). Ésta crea un Thread para ejecutar otra función que vamos a renombrar como la función de entrada (jadx-gui pulsando botón derecho sobre el nombre de la función podemos cambiarle el nombre).
Hemos indicado nuestros cambios en los nombres de funciones con letras mayúsculas. La función interesante y la que origina esta entrada al blog es la indicada en la imagen con número 3. Aquí el malware esta indicandole al PackageManager mediante setComponentEnabledSetting que oculte el icono de la aplicación a ojos del usuario. No lo hace directamente, tiene un delay de 15000ms que aplica a la hora de la creación del Thread, posiblemente para que el usuario no viese que la aplicación desaparece inmediatemente después de pulsar el launcher, sino una vez ya pasado 15 segundos. El segundo parámetro de setComponentEnabled que está a 2 corresponde con COMPONENT_ENABLED_STATE_DISABLED (valor que oculta el icono) y el tercero, de valor 1, con DONT_KILL_APP para indicar que no se quiere cerrar la aplicación cuando el estado del componente cambie. De esta manera el malware ya estaría oculto.
Siguiendo el flujo de HTTP_QUERY (zona indicada como 1 en la imagen anterior) tenemos la siguiente función:
Tiene pinta de ser algún string que se está ocultando, aplicamos el algoritmo al revés:
Aquí tenemos la URI que se realiza, yemnic[*.*]com. Como es un malware del año pasado, este dominio no resuelve a día de hoy. Debido a esto el Malware ya no tiene un comportamiento como esperaba el desarrollador del malware.
Volvemos a FUNCION_ENTRADA(). Hace un edit de los shared_preferences, luego comprueba si esta configurado los servicios de accesibilidad. Si no está configurado lanza una ventana(lo que en Android se le llama a alertDialog) con un botón que lanza el siguiente intent:
public void mo2720onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(«android.settings.ACCESSIBILITY_SETTINGS»);
intent.addFlags(268435456); —-
intent.addFlags(32768);
intent.addFlags(8388608);
context.startActivity(intent);
}
Esto arranca la actividad de los servicios de accesiblidad para que el usuario habilite los servicios para la aplicación.
En resumen, hace al usuario que active los servicios de accesibilidad y luego se queda un servicio arrancado en segundo plano. Pasemos al análisis dinámico para confirmar estos comportamientos.
4. Análisis dinámico
Vamos a instalar el malware por adb:
adb install 48618153df1b2b5be3f83e6e1fa6aa5f517b173b10f3f6e925d1598a22b459e1.apk
Ponemos en marcha Wireshark y Burp para observar las comunicaciones y pulsamos el Launcher:
Nos salta la ventana con que la actualización ha sido aplicada y se cierra la aplicación. Al rato el icono desaparece, como vimos en el análisis estático. La aplicación sigue instalada y recordemos que tiene un servicio a la escucha. En el Burp no hemos visto ninguna petición. Pero en Wireshark vemos que el Android intenta resolver la dirección que vimos en el análisis estático.
Aunque la aplicación se cierre y desaparezca, sigue en ejecución como se puede ver en la siguiente imagen:
quedándose a la escucha de movimientos del usuario mediante el permiso de accesibilidad.
5. Conclusiones
Una cosa que no hace este malware y se podría conseguir fácilmente es persistencia. Mediante un Broadcast Receiver y el uso del permiso android.permission.RECEIVE_BOOT_COMPLETED podríamos ejecutar nuestro código deseado cuando el dispositivo se reiniciara.
No vamos a indagar mucho más en este malware porque lo que queríamos enseñar ya esta hecho. De este malware podemos sacar las siguientes concluciones/técnicas:
- El uso de setComponentEnabledSetting para ocultar el icono.
- El tipo de ofuscación de URI (que dificulta mucho encontrarla de forma automática).
- Aunque no lo veamos el malware está en ejecución, espíando todos los movimientos con el permiso de accesibilidad.
- El permiso de accesibilidad tiene un gran riesgo y no debería ser activado a no ser que sea necesario.