En esta serie de entradas, vamos a ver como realizar pruebas de pentesting en aplicaciones para iOS. En este segundo artículo vamos a ver como evadir el control anti-jailbreak que pueden existir en ciertas aplicaciones.
Advertencia: La información y las técnicas compartidas en este post son sólo con fines educativos o para realizar pruebas debidamente autorizadas. Atacar aplicaciones sin consentimiento, puede ser considerado ilegal. Utilice este conocimiento bajo su propio riesgo.
Antes de iniciar, te sugerimos leer la primera parte de esta serie, la cual contiene conceptos básicos para iniciar con el pentesting de aplicaciones en iOS:
https://labitacoradelhacker.com/pentesting-de-aplicaciones-ios-parte-1-fundamentos-y-escaneo-inicial
Bien, comencemos:
Una de las medidas de seguridad que suele encontrarse en las aplicaciones móviles, es el control que previene la ejecución de aplicaciones en dispositivos que tengan privilegios elevados, es decir que hayan sido previamente rooteados o jailbrekeados. Esto es un obstáculo en el proceso de pentesting, ya que no solo nos evitará interactuar con la aplicación, sino que cualquier información que pueda ser descargada dentro del dispositivo, tales como configuraciones, bases de datos, y demás, no estará disponible.
Por esa razón, es importante conocer algunas técnicas que nos permitirán evadir este control. En este artículo veremos algunas. Antes, es importante tener instalada la herramienta Frida; si quieres aprender a instalar y usar Frida, puedes ver el siguiente artículo: https://labitacoradelhacker.com/pentesting-en-aplicaciones-moviles-instalacion-de-frida/.
¿Cómo evadir el control de altos privilegios (Jailbreak)?
Para evadir el control de detección de Jailbreak en una aplicación móvil, seguimos cuatro pasos fundamentales:
- Identificar la clase responsable de la detección: Se analiza el código de la aplicación para encontrar la clase que maneja las verificaciones de seguridad. Generalmente, estas clases tienen nombres como JailbreakDetection, SecurityManager o DeviceCheck.
- Localizar el método que realiza la validación: Dentro de la clase identificada, se debe encontrar el método que ejecuta la lógica de detección. Algunos métodos comunes son isJailbroken(), checkSecurity(), detectJailbreak(), o cualquier otro que verifique la integridad del sistema.
- Determinar el valor de retorno del método: Se analiza cómo el método devuelve la información sobre la detección de Jailbreak. Normalmente, devuelve un valor booleano (true si detecta Jailbreak, false si no).
- Modificar el valor de retorno para evitar la detección: Una vez identificado el método y su comportamiento, se modifica el valor de retorno para engañar a la aplicación. Esto se puede hacer a través de técnicas como hooking con Frida, modificación de binarios con Hopper o IDA Pro, o interceptación de llamadas a funciones del sistema. El objetivo es forzar el retorno de un valor que indique que el dispositivo no está comprometido, permitiendo así el funcionamiento normal de la aplicación.

Algunas herramientas utilizadas en este proceso incluyen:
- Frida: Para inyectar scripts y modificar el comportamiento de la aplicación en tiempo de ejecución.
- Hopper / IDA Pro: Para analizar el binario y encontrar las funciones relacionadas con la detección de Jailbreak.
- Cycript: Para manipular directamente la memoria y probar modificaciones en tiempo real.
Veamos como realizar este proceso:
- Vamos a tomar la aplicación DVIA-2 para nuestro escenario de ejemplo. Puedes descargar la aplicación desde acá: https://github.com/prateek147/DVIA-v2.


Evadiendo el control de Jailbreak con Frida
- La primera forma de evasión, la haremos utilizando Frida. Lo primero que debemos hacer es buscar el identificador de la aplicación:

- Una de las capacidades de Frida, es que podemos realizar ataques de instrumentación dinámica sobre una aplicación. Estos ataques consisten en inyectar de manera dinámica a los métodos y funciones que se ejecutan cuando la aplicación está en tiempo de ejecución. Una de las formas de ejecutar este tipo de ataque es a través de códigos javascript, por lo que vamos a construir nuestro primer script, que nos permitirá listar las clases de la aplicación. El script contiene el siguiente código:

- Hemos llamado a nuestro archivo find-classes.js. Ejecutaremos el siguiente comando en Frida. Recuerda que el dispositivo ya debe tener conexión con Frida.
frida -U -l find-classes.js -f [identificador_app] > [find_class.txt]
- Este script de Frida busca y lista todas las clases cargadas en la memoria del proceso de una aplicación iOS que utiliza el runtime de Objective-C. Su propósito es identificar posibles clases relacionadas con detección de jailbreak o mecanismos de seguridad similares. En la siguiente imagen se observa que el script encontró la clase «JailbreakDetection», lo que indica que la aplicación tiene implementado un sistema para detectar si el dispositivo está liberado o modo Jailbreak. Además, el aplicativo continúa su carga mostrando el logo de la app, lo que sugiere que aún no se han aplicado modificaciones en tiempo de ejecución:


- Después de identificar la clase «JailbreakDetection», el siguiente paso es listar los métodos que contiene para analizar cuál de ellos realiza la verificación del jailbreak. Utilizando Frida, es posible inspeccionar los métodos estáticos (+) y de instancia (-) de la clase. Al analizar su implementación, es posible entender qué técnicas utiliza la app para la detección, como la búsqueda de archivos del jailbreak (/bin/bash, /Applications/Cydia.app), comprobaciones de permisos de escritura o el uso de llamadas a APIs restringidas. Para hacerlo utilizaremos otro script, el contiene lo siguiente:

- Como puedes ver, en la línea 7 hemos indicado la clase sobre la que queremos obtener los métodos. Ten en cuenta que podrían existir más clases que se encarguen de ejecutar el control, por lo que es importante repetir el procedimiento en caso que las identifiquemos. Ejecutamos el script a través del siguiente comando:
frida -U -l show-all-methods-of-specific-class.js -f [Identificado_app]

- Este script de Frida busca y lista todos los métodos de una clase específica en una aplicación iOS escrita en Objective-C. Primero, verifica si el runtime de Objective-C está disponible. Luego, intenta obtener la lista de métodos de la clase «JailbreakDetection» accediendo a ObjC.classes.<className>.$methods, que almacena los nombres de los métodos de la clase. Si la clase existe, itera sobre la lista de métodos e imprime cada uno en la consola. Se incluyen bloques try-catch para manejar posibles excepciones, como en caso de que la clase no exista o si hay restricciones en el acceso a sus métodos. Finalmente, el script imprime mensajes indicando el inicio y la finalización del proceso. Este enfoque es útil para analizar funciones que podrían estar realizando la detección de jailbreak, como “+ isJailbroken”.
- Después de identificar la clase «JailbreakDetection» y el método + isJailbroken, el siguiente paso es determinar el valor de retorno de este método. Esto nos permitirá analizar cómo la aplicación detecta un dispositivo con jailbreak y evaluar qué modificación es necesaria para evadir dicha detección. Como ya podrás imaginar, utilizaremos otro script:
frida -U -l find-value-return.js -f [Identificado_app]

- Este script de Frida intercepta el método «+isJailbroken» de la clase «JailbreakDetection» en una aplicación iOS escrita en Objective-C para capturar y mostrar su valor de retorno. Primero, verifica si el runtime de Objective-C está disponible y luego localiza la implementación del método mediante ObjC.classes[«JailbreakDetection»][«+ isJailbroken»]. Utiliza Interceptor.attach() para engancharse al método y ejecuta la función onLeave(), la cual se activa justo antes de que el método retorne un valor. Dentro de onLeave(), imprime en la consola el nombre de la clase, el nombre del método y su valor de retorno. Esto permite analizar si el método está detectando un dispositivo con jailbreak (true o 1) y, en caso necesario, modificar su comportamiento para evadir la detección.
Acción final: Evasión de Jailbreak
- Una vez identificados la clase «JailbreakDetection», el método + isJailbroken y su valor de retorno, el siguiente paso es modificar dicho valor para evadir la detección de jailbreak. Para lograrlo, utilizamos Frida para interceptar la ejecución del método y forzar su retorno a false o 0, impidiendo que la aplicación detecte que el dispositivo está liberado. Al ejecutar el script de hooking, la aplicación continuará funcionando como si estuviera en un entorno legítimo, evitando restricciones o bloqueos asociados a la detección de jailbreak.
- Vamos a utilizar un nuevo script, con el siguiente código:

- Este script de Frida intercepta y modifica el método “+ isJailbroken” de la clase «JailbreakDetection» en una aplicación iOS para evadir la detección de jailbreak. Primero, verifica si el runtime de Objective-C está disponible y localiza el método objetivo. Luego, usa Interceptor.attach() para engancharse a su implementación y captura el valor de retorno original en onLeave(), antes de que el método finalice. Posteriormente, reemplaza el valor de retorno con 0x0 (equivalente a false o 0), asegurando que la aplicación crea que el dispositivo no está liberado. Finalmente, imprime en la consola el nombre de la clase, el método interceptado, el valor de retorno original y el nuevo valor modificado, permitiendo confirmar que el bypass ha sido aplicado correctamente. Vamos a ejecutar el script con el siguiente comando:
frida -U -l bypass-jailbreak-detection.js -f [Identificado_app]

- Y finalmente, hemos evadido el control de Jailbreak:

Evadiendo el control de Jailbreak con Objection
- La forma de evasión anterior, basa en instrumentación dinámica, una técnica ampliamente utilizada para modificar el comportamiento de una aplicación en tiempo de ejecución. Es el enfoque más común debido a su flexibilidad y control detallado sobre el código en ejecución. Sin embargo, también existe Objection, una herramienta que automatiza muchas de las tareas que normalmente se realizan con Frida, simplificando el proceso de manipulación de aplicaciones sin necesidad de escribir scripts manualmente. Aunque Objection depende de Frida, su uso es más accesible, permitiendo a los analistas de seguridad evadir detecciones de jailbreak, manipular métodos y extraer información de forma más rápida y sencilla.
- Para realizar la evasión del Jailbreak utilizando objection, ejecutaremos el siguiente comando desde nuestro equipo (Recuerda que debes tener instalado Frida y Objection):
objection -g [identificador_app] explore

- A continuación, buscaremos las clases que puedan estar ejerciendo el control anti-jailbreak. Objection permite buscar clases dentro de la aplicación que contengan una palabra clave específica, como “jailbreak”. Esto es útil para identificar posibles clases relacionadas con la detección de jailbreak, facilitando el análisis y la posterior manipulación de su comportamiento. Ejecutamos el siguiente comando:
ios hooking search classes [palabra_clave]

- Objection monitorea en tiempo real las llamadas a los métodos de una clase específica mientras se interactúa con la aplicación. Esto permite identificar qué métodos se ejecutan en diferentes escenarios, facilitando el análisis y la manipulación de funciones clave, como la detección de jailbreak. Como ya hemos identificado la clase «JailbreakDetection», listemos los métodos:
ios hooking watch class [Nombre de clase]

- Ahora que hemos identificado la clase y el método que potencialmente puedan estar evitando la ejecución de la aplicación en un sistema con Jailbreak, vamos a capturar el valor de retorno a través de Objection. Para esto, ejecutamos el siguiente comando:
ios hooking watch method “+-[clases metodo]” –dump-return

Acción final: Evasión de Jailbreak
- Ahora que ya tenemos todos los elementos necesarios, vamos a modificar el valor de retorno para poder desactivar la detección de jailbreak. Esto hará que el valor cambie de 0x1 a 0x0. Para ello ejecutaremos el siguiente comando:
ios hooking set return_value “+-[clases metodo]” 0x0
- Y finalmente conseguimos evadir el jailbreak en la aplicación

Cualquiera sea el método que vayas a utilizar, evadir el control de detección anti-jailbreak va permitir que podamos ejecutar la aplicación con normalidad, lo cual es fundamental para continuar con el pentest.
Eso ha sido todo por este post. En el siguiente, veremos como interceptar el tráfico para ver las tramas HTTP, y evadir el control de SSL Pinning.