Boolean-Based iOS Jailbreak Detection Bypass with Frida- Corellium

Boolean-Based iOS Jailbreak Detection Bypass with Frida- Corellium

Jailbreak detection algorithms serve as a powerful barrier in the world of iOS security, preventing users with jailbroken devices from accessing particular apps. While this protects app developers and improves device security, it can also make exploring and testing iOS applications difficult, constricting the scope of analysis.

This blog post explores the start of an interesting topic, avoiding jailbreak detection for iOS applications. This post will use the iOS DVIA-2 (Damn Vulnerable Application). We will start with a beginner method for jailbreak bypasses by looking at the app's classes and using the capabilities of Corellium's virtualized platform rather than relying on physical devices with unstable public scripts.

In this article, we'll walk you through the process of setting up Corellium's virtualized device environment, examining the pertinent DVIA-2 classes, and implementing changes to get around jailbreak detection. By following along, you'll discover approaches that may be used with different apps and useful insights into how iOS applications function.

Please be aware that this blog post's sole goal is education, written with researchers, developers, and iOS security enthusiasts in mind. Respecting the limits set by developers and application providers and abiding by ethical standards are crucial.

Setup and Configuration

To get started with the DVIA-2 application, we must download the iPA and set up a virtualized iOS jailbroken device for us to work with.

The DVIA-2 application can be downloaded here.

Once you have the iPA in Corellium, you will need to set up an iOS device, for this exercise, I will be using an iPhone 7 Plus on 15.7.1.

Once the device is created and booted up, we can install the DVIA-2 iPA that we obtained above. That can be installed easily through the “Files” tab on the left of Corellium.

Screenshot 2023-05-22 at 4.11.58 PM

Identifying Classes – Jailbreak Test 2

You can now launch the DVIA-2 application from your device and navigate to the “Jailbreak Detection” menu. We will be working on challenge 2 to look at classes. The other challenges require more in-depth reverse engineering, which I will cover in a separate blog post.

The first thing we need to do is identify the classes within the DVIA application that are responsible for jailbreak detection. The following Frida script can be used to either dump all class names (if the search field is blank) or search for a specific search time like I am below (looking for Jailbreak).

var search_class = ['Jailbreak'];

 

if (ObjC.available)

{

     for (var className in ObjC.classes) {

          if (Array.isArray(search_class) && search_class.length) {

               for (var i = 0; i < search_class.length; i++) {

                    if

(className.toLowerCase().includes(search_class[i].toLowerCase())) {

 

                    console.log(className)

                }

            }

        }

        else {

            console.log(className);

        }

    }

The above script can be added into the Frida console within Corellium. From the Frida tab attach to the DVIA application (make sure the app is running) and execute the script. 

Screenshot 2023-05-22 at 4.12.35 PM

Screenshot 2023-05-22 at 2.41.23 PM

Once the script has been executed, you should see the following classes within the DVIA-2 application relating to “Jailbreak”

Screenshot 2023-05-22 at 2.42.57 PM

Identifying Methods

Now that we have a good idea of what class is being used for Jailbreak detection (JailbreakDetection), we can start looking at the methods that are used. The following script can be used to enumerate methods to a specific class name (set at the beginning of the script). 

var search_class = ['JailbreakDetection'];

var search_method = [''];

 

function print_methods(className) {

    var methods = ObjC.classes[className].$ownMethods; 

    if (Array.isArray(search_method) && search_method.length) { //search_method not empty

        for (var j = 0; j < search_method.length; j++) {

            if (methods.join('

').toLowerCase().includes(search_method[j].toLowerCase())) { 


                console.log('[*] ' + className);

                for (var i = 0; i < methods.length; i++){

                    if

(methods[i].toLowerCase().includes(search_method[j].toLowerCase())) {

                        console.log('   ' + methods[i]);

                    }

                }

            }

        }

    }

    else {

        console.log('[*] ' + className);

        var methods = ObjC.classes[className].$ownMethods;

        for (var i = 0; i < methods.length; i++){

            console.log('   ' + methods[i]);

        }

    }

} 
 

if (ObjC.available)

{

    for (var className in ObjC.classes) {

        if (Array.isArray(search_class) && search_class.length) { // search_class not empty

            for (var i = 0; i < search_class.length; i++) {

                if

(className.toLowerCase().includes(search_class[i].toLowerCase())) {

                    print_methods(className);

                }

            }

        }

        else {

            print_methods(className);

        }

    }

}  

We need to run this script against the DVIA-2 application in the Frida console within Corellium using the same methods we did above. The results should be similar to the following: 

Screenshot 2023-05-22 at 2.59.10 PM

The one we are looking for in this situation is the following method under the JailbreakDetection class: 

+ isJailbroken

Hooking Methods to Modify Results

So now that we have the class and the method, we need to hook it to see what is being returned. Below is a script we can use: 

Note: This script can be utilized for multiple apps. Just make sure to update the class and function to reflect the app you are testing. 

if (ObjC.available) {  

 

try { var className = "JailbreakDetection";  

var funcName = "+ isJailbroken";  

var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]'); 
 

Interceptor.attach(hook.implementation, {

    onLeave: function(retval) { console.log("[*] Class: " + className);

    console.log("[*] Method: " + funcName);

    console.log("\t[-] Return value Type: " + typeof retval);

    console.log("\t[-] Value: " + retval); } }); }

catch(err) { console.log("[!] Exception: " + err.message); } }  

else { console.log("Objective-C Runtime is not available"); } 

We can run this script within the Corellium platform; unlike the two scripts we ran above, this script will require user interaction after it is run. When running it, click the “Jailbreak Test 2” within the DVIA-2 application to see the results (should be similar to below).

 Screenshot 2023-05-22 at 3.56.35 PM

If you selected any other test within the DVIA-2 application, you won’t see the results because their implementations require some more in-depth reverse engineering. Sticking to the “Jailbreak Test 2” will ensure it continues to work. 

Modifying the Values

Now that we got a Boolean value of 1 getting returned, we need to focus on writing a script to flip that to bypass that jailbreak detection. Below is the script we can use: 

Note: similar to the above script, this can be used for other apps if you change the class name, function name and the value to modify. 

if (ObjC.available) {  

 

try {

var className = "JailbreakDetection";  

var funcName = "+ isJailbroken";  

var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]'); 

var newretval = ptr("0x0"); 

 

Interceptor.attach(hook.implementation, {

    onLeave: function(retval) { console.log("[*] Class: " + className);

    console.log("[*] Method Name: " + funcName);  

    console.log("\t[-] Return Value Type: " + typeof retval);  

    console.log("\t[-] Original Value: " + retval);

    retval.replace(newretval)  

    console.log("\t[-] New Value: " + newretval) } }); }  

catch(err) { console.log("[!] Exception: " + err.message); } }  
 

 

else { console.log("Objective-C Runtime is not available"); }

When you run this script and click “Jailbreak Test 2” you will notice that the device is no longer shown as jailbroken. 

 Screenshot 2023-05-22 at 3.56.24 PM

Conclusion

Hopefully, this helps you learn the basics of Frida scripting for iOS applications. Please watch for upcoming webinars and blog posts to go more in-depth with Frida scripting, reverse engineering, and more.