El pasado sábado por la tarde en la conferencia Andsec, luego de un rico almuerzo que incluyó panchos (o perros calientes, según cómo los llames), pizzas y cerveza, comenzó la segunda parte de charlas y, en el salón principal, tuvimos la oportunidad de aprender cómo se podrían llegar a alterar algunas aplicaciones que corren en nuestros dispositivos móviles.
Durante esta presentación, Gustavo "Puky" Sorondo nos explicó cómo a partir de la técnica de hooking una persona podría llegar a modificar la entrada o la salida de una función o un método en una aplicación móvil, ya sea de Android o iOS.
con el código fuente de la aplicación se puede analizar cómo se comporta y qué validaciones hace
Esta técnica es posible en Android gracias a que Java, lenguaje que se utiliza para programar las aplicaciones, es un lenguaje interpretado. Es decir, la máquina interpreta línea a línea las instrucciones y luego las ejecuta, sin necesidad de compilarlas en lenguaje de máquina. Esto permite que la aplicación pueda ser desempaquetada fácilmente y, por lo tanto, se tenga acceso al código fuente.
Una vez que alguien obtiene el código fuente de la aplicación instalada y, entre otras cosas, los métodos y clases que lo componen, puede comenzar a analizar cómo se comporta, cómo está desarrollado su funcionamiento e, incluso, qué validaciones hace.
Por ejemplo, si se encontrara un método llamado “ValidarPassword()” que retorna verdadero o falso, se podría suponer que se trata del método que valida que la contraseña sea correcta. En este caso, imagina qué pasaría si alguien pudiese alterar este método para que devuelva siempre “true”.
Existen diversas aplicaciones que permiten descargar un apk, decompilarlo, analizarlo e incluso modificarlo y volverlo a compilar. Sin embargo, esto no es necesariamente hooking.
Entonces, ¿qué es el hooking?
Es el conjunto de técnicas utilizadas para alterar el comportamiento de un software mediante la intercepción de las llamadas a funciones, mensajes o eventos entre componentes. O sea que mediante el uso de herramientas como Frida, Intropsy o Xposed Framework se puede modificar el comportamiento del sistema sin necesidad de modificar el APK.
estas técnicas permiten alterar el comportamiento de un software mediante la intercepción de llamadas, mensajes o eventos
Veamos un ejemplo: imaginemos que alguien instala un nuevo juego, supongamos de shooter. Cada vez que el personaje recibe un disparo, la aplicación llama al método "Personaje.restarVida(int puntosDeVida)". Ese método, como te puedes imaginar, resta puntos de vida al personaje.
Ahora, imaginemos que alguien quiere hacer trampa y lograr que el personaje sea inmortal. Siguiendo la técnica de hooking, lo que tendría que hacer es descargar el APK en la computadora, descompilarlo y revisar el código. Luego de analizarlo –y con un poco de suerte– podría encontrar el método "restarVida(int puntosDeVida)" de la clase “Personaje” y, con base en el análisis del algoritmo y un poco de prueba y error, podría entender el funcionamiento del método y determinar que el personaje muere cuando se le restan todos los puntos de vida.
El siguiente paso sería analizar si le conviene modificar la entrada o la salida de este método. Para este ejemplo, podría modificar la entrada, de forma tal que los puntos de vida que resten sean siempre 0 (cero).
Aquí es donde entran en juego las herramientas de hooking, como Xposed Framework, que permite crear un módulo que se registra y “engancha” al método que se quiere alterar, pudiendo cambiar los parámetros de entrada o salida de la función hookeada. Entonces, cuando la aplicación invoque al método original, se ejecutará también el módulo programado, ya sea antes o después del método invocado.
Siguiendo con el ejemplo, el supuesto tramposo crea entonces un módulo que cambie los parámetros de entrada de método "restarVida(int puntosDeVida)" y reemplace el valor de la variable entera “puntosDeVida” por 0; luego, compila el módulo y lo instala en su dispositivo móvil como otro APK.
De esta forma, cada vez que se ejecute el método “restarVida” de la aplicación original, Xposed Framewok se encargará de ejecutar también la lógica del módulo programado y, por lo tanto, restará siempre 0 puntos.
En el caso de iOS, el funcionamiento es similar, ya que también se podría alterar completamente el funcionamiento de un método. Sin embargo, dado que en iOS se trabaja con lenguajes compilados (y no interpretados como en Android) el proceso de descompilación se vuelve más tedioso y difícil de analizar. Además, iOS maneja DRM (Digital Rights Management) que resguardan los derechos de autor de la aplicación, agregando una capa más de protección mediante el cifrado. Aun así, con paciencia y perseverancia se puede llegar a listar los métodos de una clase y luego hookearlos como vimos anteriormente.
¿Qué hacemos, como desarrolladores, para evitar el hooking?
En primera instancia, la técnica de hooking que explicamos únicamente funciona con aplicaciones locales que corren las validaciones dentro del dispositivo. Por lo tanto, si eres desarrollador, te recomendamos trabajar con métodos cliente-servidor y aislar las funcionalidades críticas del lado del servidor, validando que las entradas no hayan sido alteradas e intentando garantizar la autenticidad del cliente.
Otra técnica que complica la instrumentación de aplicaciones es la utilización de más de un lenguaje de programación, pudiendo utilizar otras librerías de código nativo y scripts de carga dinámica.
Además, te recomendamos utilizar técnicas de ofuscación de código para agregar una capa más de protección a tu código fuente y que sea más difícil analizar las clases y métodos que lo conforman.
También es importante tener en cuenta que esta técnica funciona únicamente cuando el dispositivo móvil esta rooteado (o se le hizo jailbreak en el caso de iOS). Es decir, para que las herramientas de hooking funcionen es necesario ser “root” en el dispositivo, una práctica que desde el laboratorio de investigación recomendamos evitar por los inconvenientes de seguridad que puede causar en el dispositivo.
Le agradecemos a Puky por la excelente explicación y demostraciones que nos brindó en #Andsec17 y por compartirnos el material para seguir aprendiendo y experimentando en el laboratorio.
Sigue leyendo: 10 consejos para el desarrollo seguro de aplicaciones