En este artículo vamos a destripar una aplicación de Android construida con Xamarin.
¿Qué es Xamarin?
Xamarin “is an open-source platform for building modern and performant applications for iOS, Android, and Windows with .NET” (https://learn.microsoft.com/en-us/xamarin/get-started/what-is-xamarin).
Básicamente, sirve para crear aplicaciones móviles con visual studio.net. Esto me ha traído bastantes problemillas a la hora de depurar/reversear la aplicación y poder obtener el código fuente original de la aplicación.
¿Cómo se compila una aplicación con Xamarin mediante Unbundled Build?
Xamarin realiza dos métodos de compilación, una a través del Unbundled Build donde observamos un empaquetado de las DLL y una compresión en LZ4, y otra a mediante Bundled Build.
En esta ocasión vamos a extraer el código fuente de la compilación mediante Unbundled Build.
Es la opción más segura, pero la más complicada de depurar. Se me convirtió en un calvario, pero no estaría escribiendo esto si no lo hubiera conseguido.
Lo primero desempaquetar el APK con el clásico apktool (https://apktool.org/docs/install/):
apktool -f d <app.apk> -o <destino-unpack>
Lo siguiente es descubrir dónde están los assemblies. En nuestro caso, en una carpeta llamada unknown/assemblies/.
Si buscáis más ficheros dentro del apk no hay nada más, solo módulos genéricos y constructores, temas de iconos y contenido estático, pero el código de la aplicación como tal está en los assemblies.
Este directorio contiene 2 ficheros, uno que es el assemblies.manifest (un índice que relaciona direcciones en hex y desplazamientos) y otro donde están “embedidas” las DLL dentro del fichero assemblies.blob.
Ahora hay que sacar estas DLL del assemblies.blob, de manera que con hexdump se puede realizar. Al intentarlo te topas con que la DLL está comprimida en LZ4, porque al extraer y hacer el hexdump del fichero extraído sale lo siguiente:
¿Qué es la compresión LZ4?
LZ4 is lossless compression algorithm, providing compression speed > 500 MB/s per core, scalable with multi-cores CPU. It features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. (https://github.com/lz4/lz4)
Esto se puede descomprimir con lz4 en linux (https://manpages.ubuntu.com/manpages/impish/man1/lz4.1.html#:~:text=lz4%20will%20default%20to%20decompression,which%20depends%20on%20stdout%20status), pero era demasiado trabajo ir una por una, así que he encontrado la siguiente solución en este programa en Python que ya lo extrae y lo descomprime:
https://github.com/jakev/pyxamstore/
Ejecutamos este programa de la siguiente manera:
pyxamstore.exe unpack -d <carpeta donde están los assemblies>
Una vez hecho esto obtienes una carpeta /out/ que contiene todas las DLL ya extraídas y descomprimidas:
Por último, para poder “ver” el código de estas librerías usamos el programa ILSpy.exe (https://github.com/icsharpcode/ILSpy/releases). Podremos ver en texto claro todo el código de las DLL:
Aquí se puede apreciar que el código de la aplicación ya es legible y podríamos empezar nuestra auditoría de código o buscar lo que necesitáramos mirar.
Espero que esta explicación sirva para saber cómo es este proceso, dado que en muchas ocasiones usando herramientas como mobsf (https://github.com/MobSF/Mobile-Security-Framework-MobSF) no vamos a poder profundizar en el análisis de este tipo de aplicaciones y vamos a tener que recurrir a la manera manual.
Un saludo y ¡happy hacking!
Contribución gracias a Carlos Antonini