
Esta es una serie de blogs de varias partes sobre ingeniería inversa, un bloque de construcción fundamental en la cadena de herramientas de cada pirata informático para comprometer las aplicaciones móviles. A lo largo de diferentes blogs de esta serie, explicaré los principales tipos de ingeniería inversa (incluidos el análisis estático y el análisis dinámico), incluso por qué los piratas informáticos lo hacen, qué información obtienen de él y cómo usan esa información para atacar su aplicación. sus usuarios y su negocio. También explicaré cómo los atacantes combinan métodos de inversión para romper las defensas de una aplicación móvil y comprender cómo funcionan su código y su aplicación. Cubriré algunas de las herramientas y métodos más utilizados por los piratas informáticos para revertir aplicaciones y proporcionaré ejemplos de escenarios de ataques reales utilizando diferentes métodos. También cubriré algunas de las diferentes opciones que los desarrolladores tienen para protegerse contra la reversión y explicaré los pros y los contras de cada una.
Y, por último, explicaré cómo puede utilizar la automatización para ofrecer una protección más completa contra la ingeniería inversa que la que ofrece actualmente, pero con mucho menos trabajo.
Primero, aclaremos algunas definiciones:
Ingeniería inversa es el proceso de desglosar algo para entender cómo funciona. En el contexto de las aplicaciones móviles, la ingeniería inversa (también conocida como inversión) implica deconstruir, analizar y observar aplicaciones compiladas para comprender el código, la lógica y la función subyacente de la aplicación. Los 2 tipos principales de ingeniería inversa son Análisis estático y Análisis dinámico. Con el análisis estático, los atacantes analizan el código fuente de la aplicación y controlan los flujos (lógica de la aplicación) para comprender qué hace el código y cómo funciona la aplicación, sin ejecutarla realmente.
El análisis dinámico es la evaluación de una aplicación móvil mientras se ejecuta, lo que implica ejecutar e interactuar con la aplicación para comprender o cambiar su comportamiento.
En esta primera publicación de la serie, me centraré en Análisis estático. Cubriré el análisis dinámico en un próximo blog de esta serie. Puede saltar a nuestros recursos en Análisis dinámico si quieres empezar por ahí.
Puedes aprender mucho sobre una aplicación simplemente analizando el código fuente y esto puede hacerse tanto con buenas como con malas intenciones. Por ejemplo, los evaluadores de penetración usan análisis estáticos para probar el modelo de seguridad de la aplicación, descubrir debilidades en las defensas de la aplicación e incluso desactivar las protecciones de seguridad (como antimanipulación o detección de jailbreak/raíz). Y los piratas informáticos de sombrero negro usan métodos similares para comprender el código fuente, excepto que sus intenciones siempre son maliciosas. Su objetivo es utilizar la ingeniería inversa para comprender qué, dónde y cómo atacar su aplicación. En algunos casos, pueden buscar datos confidenciales sobre la aplicación o los usuarios, que los desarrolladores suelen almacenar en el código de la aplicación (cadenas internas, archivos de preferencias, carpetas de recursos, etc. en texto claro). También usan la inversión para revelar la lógica de la aplicación, encontrar archivos/datos críticos, analizar y cambiar flujos de trabajo, o encontrar y explotar código vulnerable o bibliotecas de terceros utilizadas en la aplicación, entre otras cosas.
La inversión también ayuda a los piratas informáticos a aumentar el alcance o el impacto de sus ataques y aumentar su probabilidad de éxito. Los piratas informáticos suelen acumular una gran cantidad de información detallada sobre la aplicación y sus usuarios, que luego utilizan en ataques posteriores o para crear malware especialmente diseñado. En términos generales, cuanto más sepa un atacante sobre su aplicación, más efectivos serán sus ataques.
Los piratas informáticos combinan métodos de inversión para romper las defensas de una aplicación móvil y comprender cómo funcionan su código y su aplicación.
A continuación se muestran algunas de las formas en que los ciberdelincuentes utilizan la información que obtienen del análisis estático. Hay muchos más aspectos de la ingeniería inversa de los que se pueden cubrir aquí, por lo que no pretende ser una lista exhaustiva.
- Para obtener información sobre cómo la aplicación se conecta a su backend, que se puede usar para realizar ataques contra los servidores de la aplicación (p. ej.: Credential Stuffing, ataques de botnet, tomas de control de cuentas, ataques DoS, etc.)
- Para encontrar debilidades en el modelo de cifrado de la aplicación, como cifrados débiles, claves de cifrado almacenadas en la aplicación de forma insegura. Esto se puede usar para descifrar el cifrado de la aplicación o para encontrar datos valiosos almacenados dentro de la aplicación de forma insegura.
- Para recopilar o robar datos sobre los usuarios mediante la búsqueda de información codificada en la aplicación, o datos sobre los usuarios que están almacenados en texto sin formato en cadenas, dentro de las preferencias de la aplicación, los valores predeterminados del usuario u otras carpetas de recursos o activos que la aplicación necesita. orden de correr.
- Comprender los permisos e intenciones de la aplicación y otros componentes que rigen cómo la aplicación comparte datos con otras aplicaciones e interactúa con el sistema operativo u otros componentes. Estos permiten que las aplicaciones externas accedan a los datos de su aplicación, lo que potencialmente puede filtrar los datos del usuario a otras aplicaciones. Se puede abusar de esto para crear ataques específicos que abusan de la funcionalidad legítima o para crear malware que se hace pasar por una aplicación legítima y engaña a los usuarios para que otorguen permisos excesivos, revelando información confidencial (por ejemplo: ataques de superposición de pantalla, StrandHogg)
- Para obtener inteligencia, realice modificaciones de código posteriores (como omitir o deshabilitar los controles de seguridad o modificar la lógica comercial o los flujos de trabajo).
- Para robar propiedad intelectual o crear versiones falsas, clones o modificaciones de aplicaciones
Entonces, ahora que sabemos algunas de las cosas que se pueden lograr a través del análisis estático, exploremos cómo lo hacen los piratas informáticos. Cubriré algunos de los conceptos básicos del análisis estático usando ejemplos (en esta primera publicación, me centraré en las aplicaciones de Android en los ejemplos. Cubriré iOS en una publicación separada de esta serie). Para comenzar el análisis estático, un atacante generalmente comienza descargando aplicaciones de Android e iOS de varias tiendas de aplicaciones, donde las aplicaciones están empaquetadas en formato binario (.APK y .IPA). Un APK o IPA es realmente solo una forma de archivo ZIP comprimido que contiene la aplicación, su código y todos los recursos que la aplicación necesita para ejecutarse. Para ver el contenido del binario de una aplicación, todo lo que tiene que hacer es extraer (descomprimir) el archivo. Para las aplicaciones de Android, simplemente puede cambiar el nombre de la extensión del archivo a .zip, abrir la carpeta y ver el contenido. Si la aplicación solo está ofuscada superficialmente o no hace un uso generalizado del cifrado, entonces el trabajo del pirata informático será bastante fácil porque simplemente podrá leer el código o usar un desensamblador o descompilador para acceder y analizar la fuente. código.
Debido a que los humanos no pueden entender el código binario, los piratas generalmente desensamblarán o descompilarán la aplicación móvil para recrear y analizar el código fuente en el formato original en que lo escribió el desarrollador.
Las herramientas populares utilizadas para tales fines son baskmali, APKTool, JD-GUI, jadx, IDA-Pro, Hopper y muchas otras.
No se requiere ni exactitud ni integridad para que un atacante alcance su objetivo de comprender el código fuente. Según el objetivo del hacker, puede causar mucho daño con solo comprender bloques de código específicos.
Entonces, ¿cómo encuentra un hacker el código fuente en la aplicación? Hay muchas maneras de hacerlo, y ninguna de ellas es muy difícil de hacer. ¿Por qué? Bueno, todas las aplicaciones móviles se construyen y empaquetan de acuerdo con una estructura definida y bien entendida.
En las aplicaciones iOS nativas, el código es parte del ejecutable de la aplicación (C/C++/Objective-C/Swift). En las aplicaciones nativas de Android, el código se puede encontrar en archivos DEX (Java/Kotlin) y/o en bibliotecas nativas (C o C++). Con las aplicaciones nativas de iOS y Android, el código fuente se convierte a formato binario cuando se compila la aplicación.
En las aplicaciones de Xamarin, que están escritas en C#, el código fuente («C Sharp») se encuentra en archivos DLL (bibliotecas de vínculos dinámicos). En aplicaciones no nativas (aplicaciones híbridas) como las aplicaciones Cordova y React Native, el código fuente viene en forma de archivos JavaScript, CSS o HTML, y no se compila en formato binario de la misma manera que con las aplicaciones nativas. En su lugar, el código fuente de las aplicaciones no nativas suele ser almacenado dentro de la aplicación en una carpeta cuando se compila la aplicación. Por lo tanto, para leer el código fuente de las aplicaciones no nativas, no siempre es necesario descompilar la aplicación si la aplicación no está ofuscada. Uno solo necesita extraer el contenido (es decir, cambiar el nombre de la carpeta y abrirla y podrá ver el código fuente).
A continuación, se muestran algunas de las áreas principales en las que se centran los piratas informáticos cuando realizan un análisis estático de las aplicaciones de Android.
- Manifiesto de Android: (por ejemplo, AndroidManifest.xml) contiene los metadatos, la configuración y los componentes de la aplicación. Al invertir un .apk, el manifiesto es un buen punto de partida para que el pirata informático determine el mejor «punto de entrada» (es decir, qué clases son los objetivos más atractivos para analizar primero. También puede obtener información sobre las actividades de la aplicación, los servicios en ejecución, los permisos, intenciones, receptores de transmisión y más).
- Clases: La carpeta de clases (p. ej., clases.dex) contiene el código fuente (clases ejecutables de Java, también conocidas como archivos DEX) que, en última instancia, ejecuta Android Runtime. Cada APK tiene un único archivo classes.dex, que hace referencia a cualquier clase o método utilizado dentro de una aplicación.
- Instrumentos de cuerda: (p. ej., cadenas de Java o strings.xml) contiene recursos de cadena de la aplicación de Android, que a menudo se utilizan para almacenar y compartir información basada en texto, como nombres de usuario/contraseñas, información de autenticación, claves API y más. En muchas aplicaciones, esta información se almacena en texto sin formato y es un objetivo favorito de piratas informáticos de todo tipo debido a la gran cantidad de información valiosa que se puede encontrar aquí.
- Preferencias: (p. ej., SharedPreferences): contiene información persistente sobre el usuario y la aplicación, los gustos y las preferencias. Por ejemplo, algunas aplicaciones pueden almacenar números de tarjetas de crédito, información de identificación personal (PII), moneda local, información de ubicación, etc. en las preferencias.
- Activos: contiene imágenes, videos y otro contenido interactivo. Con aplicaciones y marcos no nativos, la carpeta de activos puede incluir archivos de código fuente y otros datos. Por ejemplo, las aplicaciones Cordova o React Native almacenarán código JavaScript en la carpeta de activos. Las aplicaciones de Xamarin pueden almacenar archivos DLL en la carpeta «ensamblajes» (que tiene un propósito similar al del manifiesto).
- Recursos: contiene recursos, imágenes, diseño, directorios para íconos de inicio y puede contener recursos de cadena o código o recursos precompilados (cadenas, colores, estilos, etc.)
- libre/: bibliotecas nativas (C o C++) utilizadas en la aplicación.
- META-INF: Metadatos de APK, información de firma que se puede usar para volver a firmar, reempaquetar y redistribuir clones o aplicaciones pirateadas

La ofuscación de código es uno de los principales métodos para evitar el análisis de código estático. La ofuscación es la práctica de ocultar el código fuente y la lógica de la aplicación para evitar que los atacantes comprendan el significado, la intención o la función de su código fuente, incluida la forma en que ejecuta las instrucciones o la lógica, todo sin cambiar la función o el comportamiento subyacente de la aplicación. La ofuscación es una de las ‘primeras líneas de defensa’ más importantes contra la inversión maliciosa.
Existen múltiples técnicas para ofuscar el código, y una solución integral requiere implementar varias técnicas que se complementen y refuercen entre sí. La razón por la que debe combinar varias técnicas es para evitar que los atacantes puedan eludir cualquier protección individual fácilmente al sortear la ofuscación.
Una solución de ofuscación sólida facilitará la implementación de la ofuscación de nombres (cambio de nombre de métodos, objetos, variables, clases, bibliotecas), cifrado de cadenas y recursos, cifrado de preferencias de la aplicación y valores predeterminados del usuario. Además, una protección importante para las aplicaciones de Android es el empaquetado de código (ofuscación y/o cifrar archivos DEX también conocido como. Clases Java). Además, no solo es importante ofuscar el código y las librerías, sino también los flujos de control de la aplicación (app logic), incluyendo técnicas tan diversas como inserción de código ficticio, reemplazando los destinos de las llamadas a funciones, insertando rutas arbitrarias en el flujo o haciendo que el árbol de funciones parezca roto para los atacantes al ocultar la ruta u objetivos del código original en una ubicación cifrada. Y, por último, siempre se recomienda eliminar la información de depuración, para que los piratas informáticos no puedan filtrar los rastros de la pila y comprender fácilmente el comportamiento de la aplicación.
Con Appdome, puede implementar una o varias de estas técnicas juntas para reforzar y fortalecer la defensa general a través de un enfoque de varias capas. Por ejemplo, muchos de nuestros clientes combinan ofuscación de código nativo con reubicación del flujo de control para proteger el código, las bibliotecas y los flujos lógicos de la aplicación. Si su aplicación tiene código o bibliotecas que no son nativos, puede agregar Ofuscación de código no nativo. Y siempre se recomienda Eliminar información de depuración para eliminar símbolos y toda la información descriptiva de los archivos binarios de la aplicación, como identificadores (nombres de variables y funciones) y nombres de código fuente/números de línea.
Y con Appdome, puede implementar una defensa integral en minutos para prevenir tanto la estática como la análisis dinámico, todo sin codificación manual, sin simbolizar su código, sin usar un compilador especializado y sin un SDK. Así es como los clientes de Appdome pueden ofuscar y proteger una gran mayoría de su código al instante, sin la complejidad, la inflexibilidad o la ardua codificación línea por línea de las soluciones de ofuscación tradicionales que están vinculadas a un lenguaje de codificación específico.
Además, Appdome cubre todos los marcos, todos los lenguajes de programación (Java, Kotlin, Swift, C++, Objective C), todas las plataformas de SO y todos los marcos no nativos o híbridos (como React Native, Cordova, Flutter, Xamarin, Ionic o cualquier otro). de los marcos de desarrollo de código bajo en el mercado actual) todo con una única solución.
La complejidad de las soluciones tradicionales de ofuscación se explica en este artículo de investigación líder, que estudió millones de aplicaciones de Android para comprender por qué una gran mayoría de las aplicaciones no contenían ofuscación u ofuscación superficial (solo ofuscación de nombre de clase). La razón simple: complejidad.
La conclusión es que para lograr un progreso significativo en la mejora de los resultados de ofuscación móvil, se requieren soluciones automatizadas simples que los desarrolladores puedan implementar sin ralentizar los lanzamientos o romper su código.