En nuestro departamento
de antifraude hemos analizado el APK de un troyano Android para
envío de SMS, en él hemos encontrado una técnica de desempaquetado
muy interesante. El malware usa una librería nativa integrada
(libAPKProtect.so) en el APK para desempaquetar el bytecode Dalvik. Además de
eso, implementa técnicas para hacer mas difícil el volcado de la memoria del
proceso y extraer el bytecode Dalvik también implementa un control para
terminar la ejecución en caso de que el APK haya sido reempaquetado. Entendemos
que el lector está familiarizado con el entorno Android y con las herramientas
para depurar las aplicaciones Android como ndk-gdb de la NDK de Android.
Al abrir el archivo "classes.dex" del APK que contiene
el bytecode Dalvik, vemos que hay instrucciones que no fueron interpretadas
porque los byte codes están cifrados. El cifrado dificulta la ingeniería inversa,
evita que los sistemas automatizados inserten "hooks", etc.
Ejemplo de la funcion "onCreate" cifrada:
Recorriendo el archivo,
vemos el constructor de la clase "APKMainAPP12D0C"
que carga una librería llamada "APKProtect".
El desempaquetador seguramente está dentro de la librería nativa. ¿Cómo? Sí, un
desempaquetador de bytecode Dalvik está contenido en una librería nativa
compilada para procesadores ARM. Necesitamos de depurar la librería
nativa. Por eso, nos hemos inspirado en el blog "The Cobra
Den" para configurar el entorno de depuración y la instalación
de ndk-gdb de Google.
Cuando el malware carga
la librería nativa con la función "loadLibrary",
el sistema operativo llama a la funcion "On_JNILoad" de esa misma librería nativa. Depurando
la librería, hemos puesto un breakpoint a esa función "On_JNILoad".
En esa función, la
primera parte se encarga de llamar a la función
"ptrace" con el parámetro
PTRACE_TRACEME. Evita el funcionamiento de todo tipo de depuradores como GDB al
igual que tampoco funcionará cualquier tentativa de volcado de memoria.
En la segunda parte, el
malware abre el archivo "/proc/self/maps"
que contiene el mapeado de su memoria. Itera cada línea hasta encontrar la
cadena "classes.dex", es
decir la zona de memoria que contiene el mapa del archivo "classes.dex". Analizando esa misma línea,
el malware conoce la localización en memoria del mapa del archivo "classes.dex".
Ejemplo del mapeado del
codigo Dalvik en el proceso donde vemos que el archivo “classes.dex” esta
mapeado entre la dirección 0x47c46000 y 0x47c53000.
47c46000-47c53000
r--p 00000000 1f:01 525
/data/dalvik-cache/data@app@google.service-1.apk@classes.dex
Luego el malware
comprueba si es un DEX o un DEX optimizado (DEY) buscando la cadena "dex"
o "dey". Si es un DEX, recoge 20 bytes y compara esos 20 bytes con
bytes de su librería. Si no hay correspondencias, el malware lanza un hilo que
termina la ejecución del proceso en un tiempo aleatorio. ¿Pero…? un momento, ¿20
bytes no es el tamaño de una firma SHA1? En la documentación de Google,
vemos que cada archivo DEX tiene una firma SHA1 en su cabecera excepto los códigos
optimizados (DEY). Sirve para asegurarse de la integridad del archivo, es decir
que el archivo no fue modificado. Si el archivo fue modificado, vuelve a matar su proceso de la misma manera. Pensamos, que el
malware comprueba eso para evitar todos los tipos de reempaquetado que
consisten en desempaquetar, insertar hooks, y re-empaquetar.
Esta es la firma SHA1 del
archivo "classes.dex" que
hemos encontrado:
0x73 0xAD 0x50 0x7F 0x1C 0xC6 0x8A 0x4D 0x2E 0x8C 0xEE
0xF5 0xDA 0xF8 0xE7 0x7C 0x27 0x4D 0x97 0xE7
En la tercera parte, el
malware recoge el bytecode Dalvik (dentro del map del archivo classes.dex),
llama a la funcion mprotect para cambiar la proteccion de las paginas de
memoria a escritura. Por cada parte del bytecode Dalvik cifrado, recoge cada
byte (LDRB), aplica un Exclusive OR (EORS) con bytes de su libreria, y guarda
el resultado (STRB) a la misma ubicacion. Cuando todas las partes estan
decifradas, el malware llama de nuevo a la funcion “mprotect” para cambiar las
paginas de memoria al modo lectura. Solo en modo lectura, porque es la maquina
Dalvik quien va a leer los byte codes, ejecutarlos y no el procesador ARM :=).
Ahora que sabemos donde descifra
el malware los bytecode, solo es necesario poner un breakpoint cuando ha
terminado, es decir a la funcion "mprotect". Con el comando "dump memory
/home/ubuntu/dump.bin 0x47c46000 0x47c53000" dentro de la consola de gdb, conseguimos un volcado de la
memoria. Solo falta abrir el volcado con
un intérprete de bytecode Dalvik como IDA para ver el código descifrado.
La misma función "onCreate" pero descifrada:
El desempaquetador APKProtect no fue diseñado por el autor de malware. En efecto,
APKProtect es un producto que se encarga de proteger los APKs ante ingeniería
inversa. Desafortunadamente, ayuda tanto a los buenos como a los malos.
Más
información:
SHA256 de la muestra analizada 3aee81db24540fb6b3666a38683259fd32713187ec6e0b421da9b91bd216205f
NDK,
Debugging
Apps with Native Code - part 1
Dalvik
Executable Format
ApkProtect,
Laurent Delosières
excellent post, very informative. 토토
ResponderEliminar"I think youve created some actually interesting points. 스포츠토토
ResponderEliminarThanks for posting this, it was unbelievably informative and helped me a lot. 슬롯
ResponderEliminarThank you for posting information. Have a nice day!
ResponderEliminarbankruptcy lawyer near me
I am very happy to visit your post and i really appreciated for your great effort. thank you!
ResponderEliminarpuntos de control de dui