El uso de Flutter en el malware para dificultar los análisis
Como ya hemos hablado en otras ocasiones, los creadores de malware tienen un objetivo primordial a la vista cuando están desarrollando una nueva pieza: no ser descubiertos. O al menos, retrasar todo lo que se pueda ese evento.
Para ello, intentan pasar desapercibidos, pero claro, en una campaña de intento infección de cientos de miles de equipos es prácticamente imposible. Así, la muestra de malware va a llegar tarde o temprano a la mesa de operaciones del analista de malware; dónde contará todos sus secretos.
Por lo tanto, habida cuenta de que el espécimen liberado tendrá una vida corta, se intenta dotarle de mecanismos que hagan complicada la tarea de extraer el funcionamiento y las comunicaciones que porten. Es decir, hacer sudar al analista antes de que este salga victorioso con los datos necesarios para crear reglas de bloqueo y detección.
____
En otras entradas hemos visto que empleaban lenguajes de programación nuevos para dificultar esta tarea. La razón, que repetimos aquí, es sencilla: hay poca información y herramientas sobre estos binarios y hasta que se suple dichas ausencias se aprovecha tal ventana de oportunidad.
En concreto sabemos del uso de Go y Rust (entre otros muchos). Lenguajes que además les permiten disponer de un tiempo de desarrollo menor al poseer mecanismos de abstracción y florituras de las que carecen otros lenguajes nativos (por excelencia, C y C++).
Hoy vamos a traer a la palestra un "tapado". Hemos escogido este término porque llamarlo desconocido sería injusto. Nos referimos a Dart, un lenguaje de programación orientado a objetos diseñado por Google pensado para la web.
Sin embargo, Dart no es un lenguaje popular como si lo es la plataforma Flutter en la que Dart tiene un papel protagonista. Flutter es ampliamente usado como marco de desarrollo de aplicaciones multiplataforma. Sobre todo en el mundo móvil, donde los programadores pueden usar Flutter para desplegar la misma versión tanto en Android como iOS, acortando los tiempos de desarrollo drásticamente.
Flutter es ampliamente usado como marco de desarrollo de aplicaciones multiplataforma, sobre todo en el mundo móvil.
En cualquier caso, los creadores de malware no emplean Dart principalmente por Flutter en el sentido de la portabilidad (que también, por ejemplo, el malware MoneyMonger) sino por una de las características de su compilador que veremos más adelante.
Fluhorse un ejemplo de malware escrito en Flutter para dificultar su análisis
Durante mayo del 2023 surgió una interesante familia de malware para Android denominada Fluhorse por los laboratorios. Aunque ya se había detectado y estudiado malware usando Flutter la novedad en Fluhorse era que las rutinas maliciosas estaban escritas para dicho framework.
Es decir, mientras que el uso de Flutter era considerado por su portabilidad a otras plataformas , esta vez era usado por sus capacidades anti-análisis; aprovechando conceptos que veremos más adelante.

Aconsejable la lectura del análisis estático por parte del laboratorio de Fortinet, donde se detalla la "lucha" para poder realizar ingeniería inversa sobre el binario generado por Flutter y como un despiste de los creadores de dicho malware, al incluir el binario para x86-64, facilitó su análisis.
En el post, desarrollan el imbricado estado de las distintas capas de protección que rodean al malware, desde el empaquetamiento del APK resultante, que dificulta una lectura "humana" y comprensiva de la estructura del contenido del paquete:

Además, la parte del payload (el conjunto de acciones del código que intentan ocultar a los analistas) está cifrado (lo hace el mismo packer) dentro del clásico "classes.dex" el cual, una vez descifrado, despliega otro "classes.dex" con la funcionalidad maliciosa.
Este objeto final es el "snapshot" de Flutter y aquí vuelven a poner otro muro (casi) insalvable. Es lo que veremos a continuación, el por qué es usado Flutter como barrera o mecanismo anti-análisis.
Flutter como medida anti-analítica
En primer lugar, la intención, por supuesto, de los creadores de Flutter no era dificultar el análisis sino realizar un producto final con optimización en tamaño y rendimiento. Máxime tratándose de un marco de desarrollo móvil, donde cada byte y ciclo le pega un pequeño bocado a la batería.
Dicho esto, como otros frameworks que permiten obstaculizar la ingeniería inversa para proteger la propiedad intelectual, Flutter posee opciones para ofuscar el código, que básicamente, lo que hace es cambiar el nombre de variables, métodos y clases cambiándolos por cadenas aleatorias (ver imagen de arriba). Pero no es esta la característica que buscan los creadores de malware.
Dart, el lenguaje en el que se programa Flutter, permite compilar la aplicación en diversos formatos, con el objeto de flexibilizar y adaptarse a los requerimientos de los desarrolladores respecto del contexto donde la aplicación va a ser desplegada.
Entre los distintos formatos de salida de compilación podemos encontrar dos grupos: Dart para la web y Dart nativo. Este último, a su vez, tiene el modo JIT y el modo AOT:
- El modo JIT (Just In Time execution) compila el código que se va a ejecutar "al vuelo", es decir, durante la ejecución del programa.
- En el modo AOT (Ahead Of Time compilation) el código ya ha sido compilado por el creador de la aplicación y se inyecta en la máquina virtual de Dart.

En resumen, AOT ahorra el trámite de compilar para la plataforma pero por contraparte, debes pre-compilar la aplicación para las distintas arquitecturas en las que la aplicación va a correr.
Recordemos que los móviles poseen varios tipos de arquitecturas, lo que hace que un binario AOT de Dart posea un sobrepeso al tener que portar todo el código para cada arquitectura. Recordemos lo que les pasó, por fortuna, a la gente del laboratorio de Fortinet: "se encontraron con el código de la versión x86-64...".
AOT Snapshots
Aquí viene el quid de este post. Este formato es en realidad una serialización del estado de la máquina virtual de Dart y como tal posee un estructura propia y muy optimizada cuyo formato cambia de una versión a otra con relativa rapidez y la documentación producida para realizar ingeniería inversa es escasa aún.
A esto, debemos sumarle el hecho de que cuando se compila una aplicación carga estáticamente con todas las librerías necesarias (no hay enlace dinámico) con lo que el espacio a estudiar dentro de este snapshot es amplio.
Además de todo eso, recordemos que no es código que se vaya a ejecutar directamente sino que será la máquina virtual de Dart la que se encargará de ello (recordemos, es multiplataforma) con lo que el código, aun desensamblado, carece de sentido a simple vista.
Por último, la ingeniería inversa se basa en aplicar el conocimiento que se posee del objeto para realizar un análisis (separar las partes del todo) sobre este. Y todo este proceso se apoya indefectiblemente en un arsenal de herramientas muy probadas y optimizadas por la comunidad o empresas especializadas. Pero, ¿qué ocurre si las herramientas no existen o aún se encuentran en un estado muy elemental?
Es precisamente la foto del estado del reversing sobre los snapshots AOT de Dart: formato optimizado y cambiante, poco documentado y con escasez de herramientas. La tormenta perfecta para un laboratorio de análisis y una ventana de oportunidad para el malware, como hemos visto.
¿Qué tenemos para hacer frente al malware que emplea Flutter (Dart)?
Hay algo, por supuesto. En este mundillo no faltan curiosos y la fortuna de que compartan sus hallazgos. Por ejemplo, el proyecto "reFlutter" que es una versión parcheada del framework original para ayudar en el traceo de la aplicación y que podemos emplear para trabajar con ella en Frida o examinar su tráfico con un proxy de interceptación http.
Además, también podemos ver, cada vez más, publicaciones acerca del tratamiento de los snapshot AOT de Dart respecto de la ingeniería inversa. Como por ejemplo, el excelente artículo y recientemente publicado "Reversing Dart AOT Snapshot" en el mítico ezine Phrack.
Conclusión
Sin duda, se trata de otro nuevo desafío para los analistas de malware. Terreno no cubierto anteriormente que es aprovechado como abono por los creadores de malware.
Sin embargo, la comunidad es rápida y el flujo de publicación de hallazgos mantiene el caudal constante con el riego de nuevas herramientas o conocimiento que hacer recortar el espacio disponible por los atacantes.
Imagen: Freepik.