JailBreak Detection
Jailbreak Detection en iOS
El Jailbreak Detection es un mecanismo implementado en las aplicaciones para detectar si un dispositivo iOS ha sido jailbreakeado (es decir, si ha sido modificado para eliminar restricciones impuestas por Apple). Esto es importante porque un dispositivo con jailbreak permite:
-
Ejecutar aplicaciones no autorizadas (fuera de la App Store).
-
Acceder a archivos del sistema y modificar configuraciones restringidas.
-
Ejecutar código arbitrario con permisos elevados.
-
Eludir mecanismos de seguridad en aplicaciones bancarias, de juegos o de trabajo.
El reto dice: Algunos desarrolladores comprueban si el dispositivo tiene jailbreak y permiten que la aplicación funcione sólo si no lo tiene. Su tarea consiste en ejecutar esta aplicación en un dispositivo con jailbreak y engañar a la aplicación para que piense que no tiene jailbreak.

Realizamos la validación de cada prueba, desde el Jailbreak Test 1 hasta el Jailbreak Test 4 sale el mismo mensaje indicando que el dispositivo tiene jailbreak

y en el Jailbreak Test 5, sale un mensaje diferente, indicando que el dispositivo tiene Jailbreak y despues de unos segundos cierra la aplicación

ahora debemos revisar si el dispositivo se encuentra conectado
┌──(root㉿angussMoody)-[/mnt/angussMoody]
└─# frida-ls-devices
Id Type Name OS
---------------------------------------- ------ --------------- ---------------------
local local Local System Kali GNU/Linux 2024.4
03565e409550be0e35e2a5f8704d573e3fc99565 usb iOS Device
barebone remote GDB Remote Stub
socket remote Local Socket
ahora vamos a buscar el identificador de la aplicación en este caso es com.highaltitudehacks.DVIAswiftv2
┌──(root㉿angussMoody)-[/mnt/angussMoody]
└─# frida-ps -Uai
PID Name Identifier
--- ----------------- ---------------------------------------
561 Calendario com.apple.mobilecal
584 Chrome com.google.chrome.ios
615 Configuración com.apple.Preferences
524 Cámara com.apple.camera
974 DVIA-v2 com.highaltitudehacks.DVIAswiftv2
554 Safari com.apple.mobilesafari
una vez que está confirmado vamos a hacer uso de la herramienta Objection para realizar el bypass al jailbreak
┌──(root㉿angussMoody)-[/mnt/angussMoody]
└─# objection
Checking for a newer version of objection...
Usage: objection [OPTIONS] COMMAND [ARGS]...
_ _ _ _
___| |_|_|___ ___| |_|_|___ ___
| . | . | | -_| _| _| | . | |
|___|___| |___|___|_| |_|___|_|_|
|___|(object)inject(ion)
Runtime Mobile Exploration
by: @leonjza from @sensepost
By default, communications will happen over USB, unless the --network option
is provided.
Options:
-N, --network Connect using a network connection instead of USB.
-h, --host TEXT [default: 127.0.0.1]
-p, --port INTEGER [default: 27042]
-ah, --api-host TEXT [default: 127.0.0.1]
-ap, --api-port INTEGER [default: 8888]
-g, --gadget TEXT Name of the Frida Gadget/Process to connect to.
[default: Gadget]
-S, --serial TEXT A device serial to connect to.
-d, --debug Enable debug mode with verbose output. (Includes
agent source map in stack traces)
--help Show this message and exit.
Commands:
api Start the objection API server in headless mode.
device-type Get information about an attached device.
explore Start the objection exploration REPL.
patchapk Patch an APK with the frida-gadget.so.
patchipa Patch an IPA with the FridaGadget dylib.
run Run a single objection command.
signapk Zipalign and sign an APK with the objection key.
version Prints the current version and exists.
ahora ejecutamos el comando objection -g com.highaltitudehacks.DVIAswiftv2 explore este comando inicia una sesión interactiva con la aplicación-g especifica el identificador del paquete de la app (com.highaltitudehacks.DVIAswiftv2) y explore lanza un entorno interactivo donde se pueden ejecutar comandos para analizar y modificar el comportamiento de la aplicación en tiempo real.
┌──(root㉿angussMoody)-[/mnt/angussMoody]
└─# objection -g com.highaltitudehacks.DVIAswiftv2 explore
Using USB device `iOS Device`
Agent injected and responds ok!
_ _ _ _
___| |_|_|___ ___| |_|_|___ ___
| . | . | | -_| _| _| | . | |
|___|___| |___|___|_| |_|___|_|_|
|___|(object)inject(ion) v1.11.0
Runtime Mobile Exploration
by: @leonjza from @sensepost
[tab] for command suggestions
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] #
una vez estemos ahí ejecutamos el comando ios jailbreak disable este comando desactiva la detección de jailbreak en la app.
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios jailbreak disable
(agent) Registering job 279031. Type: ios-jailbreak-disable
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] #
ahora cada que llamemos a estos Jailbreak test, realizará el proceso Objection intercepta los métodos usados por la app para detectar jailbreak. Cada verificación (como buscar archivos o abrir la URL de Cydia) es marcada como fallida, engañando a la app para que crea que el dispositivo no está liberado.
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # (agent) [612933] fileExistsAtPath: check for /Applications/Cydia.app was successful with: 0x1, marking it as failed.
(agent) [612933] fileExistsAtPath: check for /Library/MobileSubstrate/MobileSubstrate.dylib was successful with: 0x1, marking it as failed.
(agent) [612933] fileExistsAtPath: check for /bin/bash was successful with: 0x1, marking it as failed.
(agent) [612933] fileExistsAtPath: check for /usr/sbin/sshd was successful with: 0x1, marking it as failed.
(agent) [612933] fileExistsAtPath: check for /etc/apt was successful with: 0x1, marking it as failed.
(agent) [612933] canOpenURL: check for cydia://package/com.example.package was successful with: 0x1, marking it as failed.
y cuando vemos el mensaje del dispositvo nos dice que no cuenta con Jailbreak, esto ocurre para las 5 pruebas. Esta sería la forma más fácil de realizar ese bypass, pero vamos a ver otra forma más manual

si la aplicación está escrita en Objective-C (es un lenguaje usado por Apple para crear apps, basado en C y orientado a objetos) podemos realizar una busqueda de las clases relacionadas con la detección de jailbreak. Identificamos dichas clases mediante búsqueda por palabras clave y luego intervenimos los métodos, para realizar la busqueda es con el comando ios hooking search classes jailbreak y esto nos da como resultado 2 clases, llamadas:
JailbreakDetection DVIA_v2.JailbreakDetectionViewController
┌──(root㉿angussMoody)-[/mnt/angussMoody]
└─# objection -g com.highaltitudehacks.DVIAswiftv2 explore
Checking for a newer version of objection...
Using USB device `iOS Device`
Agent injected and responds ok!
_ _ _ _
___| |_|_|___ ___| |_|_|___ ___
| . | . | | -_| _| _| | . | |
|___|___| |___|___|_| |_|___|_|_|
|___|(object)inject(ion) v1.11.0
Runtime Mobile Exploration
by: @leonjza from @sensepost
[tab] for command suggestions
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking search classes jailbreak
JailbreakDetection
DVIA_v2.JailbreakDetectionViewController
Found 2 classes
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] #
Ahora vamos a listar todos los métodos utilizados en las clases que encontramos con los siguientes comandos, para la primera clase es el comando ios hooking list class_methods JailbreakDetection que nos devuelve un metodo
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking list class_methods JailbreakDetection
+ isJailbroken
Found 1 methods
y para la otra clase el comando es ios hooking list class_methods DVIA_v2.JailbreakDetectionViewController que nos devuelve 13 métodos
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking list class_methods DVIA_v2.JailbreakDetectionViewController
- menuTapped:
- readArticleTapped:
- jailbreakTest1Tapped:
- jailbreakTest2Tapped:
- jailbreakTest3Tapped:
- jailbreakTest4Tapped:
- jailbreakTest5Tapped:
- initWithCoder:
- .cxx_destruct
- initWithNibName:bundle:
- viewWillAppear:
- viewDidLoad
- prepareForSegue:sender:
Found 13 methods
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] #
Los símbolos más(+) y menos(-) delante del nombre del método indican el valor de retorno del método. Un signo más(+) significa que se trata de un método de clase que devuelve un tipo BOOL. Un signo menos(-) significa que se trata de un método de instancia. Ahora vamos a modificar el valor de isJailbroken, lo primero que debemos hacer, es saber cuando se llama, para eso vamos a ejecutar el comando
ios hooking watch method "+[JailbreakDetection isJailbroken]" --dump-args --dump-return
Este comando permite interceptar y observar las llamadas al método +[JailbreakDetection isJailbroken], mostrando los argumentos y el valor de retorno. Se usa para analizar cómo una app detecta si el dispositivo está liberado (jailbroken).
y en el dispositivo empezamos a llamar cada uno de los retos, cuando llamamos a Jailbreak Test 2, vemos la respuesta Return Value: 0x1 (que equivale a true) así que sabemos que en este momento es que se está llamando.
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking watch method "+[JailbreakDetection isJailbroken]" --dump-args --dump-return
(agent) Found selector at 0x10123d27c as +[JailbreakDetection isJailbroken]
(agent) Registering job 568660. Type: watch-method for: +[JailbreakDetection isJailbroken]
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # (agent) [025046] Called: +[JailbreakDetection isJailbroken] 0 arguments(Kind: class) (Super: NSObject)
(agent) [675052] Called: +[JailbreakDetection isJailbroken] 0 arguments(Kind: class) (Super: NSObject)
(agent) [568660] Called: +[JailbreakDetection isJailbroken] 0 arguments(Kind: class) (Super: NSObject)
(agent) [025046] Return Value: 0x1

ahora ya sabemos en cual Test realiza el llamado y el valor que retorna, lo que devemos hacer el cambiar el valor a 0x0 o lo que es lo mismo a false, eso lo realizamos con el siguiente comando
ios hooking set return_value "+[JailbreakDetection isJailbroken]" false lo que realiza el cambio del valor de true a false
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking set return_value "+[JailbreakDetection isJailbroken]" false
(agent) Found selector at 0x100f3927c as +[JailbreakDetection isJailbroken]
(agent) Registering job 794294. Type: set-method-return for: +[JailbreakDetection isJailbroken]
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # (agent) [794294] +[JailbreakDetection isJailbroken] Return value was: 0x1, overriding to 0x0
o el comando ios hooking set return_value "+[JailbreakDetection isJailbroken]" 0x0
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # ios hooking set return_value "+[JailbreakDetection isJailbroken]" 0x0
(agent) Found selector at 0x10090127c as +[JailbreakDetection isJailbroken]
(agent) Registering job 990078. Type: set-method-return for: +[JailbreakDetection isJailbroken]
....highaltitudehacks.DVIAswiftv2 on (iPad: 13.3.1) [usb] # (agent) [990078] +[JailbreakDetection isJailbroken] Return value was: 0x1, overriding to 0x0
volvemos al dispositivo y tocamos Jailbreak Test 2 de nuevo, y ahora el mensaje cambia a “Device is Not Jailbroken”, confirmando que el override funcionó
