Log

Bypass Jailbreak detection on iOS by using FRIDA(with Jailbreak)

1. Infromation

Hi, I'm yotti. Here I will explain about how to avoid Jailbreak Detection on iOS by using frida. If you find some mistakes on this content, please send me an E-mail or leave a comment on this blog. Recently, I prefer to use hooking tools such as FRIDA, VirtualHookingEx and others. However, I think that Frida is the easiest tool to use for me comcompared to any other tools. Please try using it, if you are interested in it.

※If your devices was broken by looking at this sites and executing, I will not cover your responsibility. By the way, my iPhone came to not to boot when I put Jailbreak into my iPhone as iOS application...^^;. Hence, you should take care and please don't misuse it.

Twitter:@yocchii_


2. Introduction

2-1. FRIDA

Before broaching the main subject, I will explain about FRIDA. FRIDA is dynamic toolkits that can be reverse engineering and discover security holes and other. FRIDA can be like this ...

  • the FRIDA by using Client/Server can inject Javascript to running process on the Operation System such as iOS, Windows, Android, LINUX.

  • the FRIDA is standalone flamework to be no dependent other devices.

  • the FRIDA can do API hook, memory dump, parameter and return value operation and others.

if you want to know more about the FRIDA, I recommend you to visit the sites below.

www.frida.re

https://www.frida.re/docs/presentations/ncn-2015-cross-platform-reversing-with-frida.pdf http://2015.zeronights.org/assets/files/23-Ravnas.pdf

very interesting!!

2-2. making environment for execute

It is my environment for execution.

Client Server
OS X mojave version 10.14.2(FRIDA12.2.18) iPhone version 11.4.1(with Jailbreak)

First, install on your Computer and devices.

Client Side
pip3 install frida-tools frida

if your device is not Jailbreak, you should look at below site. https://www.frida.re/docs/ios/

After installing on your Client side, then install to Server Side.(with Jailbreak)

screen1. frida-url

First, Open Cydia and add FRIDA repository by going to Manage->Source->Edit->Add and add this URL as follow "https://build.frida.re".

If you can see same image below on your screen, it is successfully installed.

screen2. FRIDA

2-3. Jailbreak Detection Application(Analysis Application)

I made an iOS applicaton to detection Jailbreak at Objective-C. It is simple iOS application that can detect Jailbreak. I have been uploaded this iOS Applications to Github so that you guys can use it.

github.com

by the way, if application is made by Swift, it is diffcent about how to hook and Swift is not support at official FRIDA. but @maltek(https://github.com/maltek) is working on it. but it have some problem such as can't hook by using it. if you want to hook it made up Swift , I recommend you to visit the sites below.

github.com

and I made it Swift version.

github.com

f:id:yottiii:20190517133816j:plain

As you can see and know image below, JailbreakDetection(I will call this iOS Application as JailbreakDetection after) is checking up to detect whether the device have been doing Jailbreak.

f:id:yottiii:20190517133754j:plain

Now,I will explain that how this application that can detect Jailbreak works.

ViewController.m

#import "JailbrakDetection.h"

@implementation JailbraekDetecvtion

+(BOOL)isJailbreak{
    isJB *check = [[JailbrakDetection alloc] init];
    if ([check check_cydia]||[check check_file_path_access]){
        return true;
    }
    return false;
}

-(BOOL)check_cydia
{
    FILE *check_cydia = fopen("/Applications/Cydia.app","r");
    if(check_cydia){
        fclose(check_cydia);
        return true;
    }
    else{
        return false;
    }
}

-(BOOL)check_file_path_access{
    NSArray *file_path = [[NSArray alloc] initWithObjects:
                          @"/Library/MobileSubstrate/MobileSubstrate.dylib",
                          @"/bin/bash",
                          @"/etc/apt",
                          @"/usr/sbin/sshd",
                          @"private/var/lib/atp",
                          nil];
    
    NSString *file_path_string;
    for(int i=0; i<file_path.count; i++){
        file_path_string = [file_path objectAtIndex:i];
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:file_path_string]){
            return true;
        }
    }
    return false;
}

@end

This is the class to detect whether devices is Jailbreak or not. Chekpoints are as follow.

  • Is Cydia.app installed at your devices?
  • Can the device access the Pash such as /bin/bash or /etc/apt and other?
  • Does devices exist the PATH such as /bin/bash or /usr/bin/ssh or /etc/apt and other ?

If the cases above apply to you, there are the possiblites of Jailbreak from the security point of view.

3. Detail of Bypass

First, we should check the process of the target application.

screen4. use frida command

"frida-ps -U" shows list of ruuning process(JailbreakDetection_Objective-C).

You can attach to process JailbreakDetection_Objective-C(process:1593) like the picture below and get some information such as class name, memory and other on the target process. screen5. attach

There are two methods for hooking. One is that working here(screen5) in the FRIDA shell and interacting with our process.

frida -U -l javascript(you make) processname

The other one is using python3 library. I will explain it later in the next blog.

3-1. Bypass Step

First, I will explain things to do in Baypass.

f:id:yottiii:20190315174110p:plain
flow

TO DO LIST

Step1) Is application available at frida?
Step2) Idetify Class
Step3) Identify methods
Step4) Find and rewrite return value

3-2. Detection Class infromation

This code is to extract class information from running process. I have published that Code into my Github.

github.com

if you want to know API that is using inside my program, I recommend you to visit and look the site below.

www.frida.re

get_available_information.py

#!/usr/bin/env python3
#!cording=utf-8

"""
Get information as available your devices
Tested on iOS 11.4.1(with Jailbreak)
Author: yotti
"""

import frida
import sys

def on_message(message, data):
    try:
        if message:
            print("[log] {0}".format(message["payload"]))
    except Exception as e:
        print(message)
        print(e)

def hook():
    get_available_information ="""
    console.log("[*]Start..");
    if(ObjC.available) {
        send("frida is available");
    } else {
        console.log("frida is not available on your devices");
    }
    console.log("[*]End");
    """

    return get_available_information

if __name__ == '__main__' :
    PACKAGE_NAME = "JailbreakDetection_Objective-C"
    try :
        
        session = frida.get_usb_device().attach(PACKAGE_NAME)
        print ("[log] devices info : {}".format(frida.get_device_manager().enumerate_devices()))
        script = session.create_script(hook())
        script.on('message', on_message)
        script.load()
        sys.stdin.read()
    except KeyboardInterrupt:
        sys.exit(0)

RESULT

w022571807479m:v3 yotti$ ./get_available_devices.py
[log] devices info : [Device(id="local", name="Local System", type='local'), Device(id="tcp", name="Local TCP", type='remote'), Device(id="3eccd7c7e82d959d7cf664e9e011d0d5632c862f", name="iPhone", type='usb')]
[*]Start..
[log] frida is available
[*]End

first, we want to know that the iphone is available with using frida.Obj.available is boolean specifying whether the current process has an Objective-C runtime loadded.

As explained in the previous chapter, if application is made by Swift and other, it is diffcent about how to hook and Swift is not support at official FRIDA.

next, I would like to find the Jailbreak Class and Method.

get_classess.py

def hook():
    get_classes_information = 
    """  
    console.log("[*]Start");
    if (ObjC.available){
        for (var className in ObjC.classes){
            if (ObjC.classes.hasOwnProperty(className)){
                console.log(className);
                }
            }
        }
    else{
        console.log("frida is not available on your device");
    }
    console.log("[*]End");
    """
    return get_classes_information

result

w022571807479m:v3 yotti$ ./get_classes.py | grep -i jail
JailbreakDetection

get_classes is to extract all class in the process of application. Perfect! I found the Jailbreak Detection Class!

3-3. Detection Method Information

I explained about how to exeract class information from running process. Based on this Class Information, I will find Method information.

def hook():
    get_method_information = """
    console.log("[*]Start");
    if(ObjC.available) {
        var class_checker = ObjC.classes.JailbreakDetection;
        var methods_checker = class_checker.$ownMethods;
        methods_checker.forEach(function(m) {
                send(m);
                });
        } else {
        console.log("frida is not availabe on your devices");
        }
    console.log("[*]End");
"""
    return get_method_information

Result

w022571807479m:v3 yotti$ ./get_method.py
[*]Start
[log] + isJailbreak
[log] - check_cydia
[log] - check_file_path_access
[*]End

Ok! I identifed target methods of iOS application class.

3-4. Find and Rewrite return value

This is the code that can rewrite return value from ruuning process.

def hook():
    return_value_rewrite = """
    if(ObjC.available) {
        var class_checker = ObjC.classes.JailbreakDetection;
        var methods_checker = class_checker.$ownMethods;
        var isApplication = class_checker['+ isJailbreak'];
        Interceptor.attach(isApplication.implementation, {
                onEnter: function(args) {
                    var target = new ObjC.Object(args[0]);
                    var sel = ObjC.selectorAsString(args[1]);
                    send("Target class : " + target.$className);
                    send("Target selector : " + sel);
                    },
                onLeave: function(retVal) {
                    send("Old return : " + retVal);
                    retVal.replace("0x0");
                    send("New return : " + retVal);
                    }
                });
        } else {
        console.log("frida is not available on your devices");
        }
"""
    return return_value_rewritee

result

w022571807479m:v3 yotti$ ./return_value_rewrite.py
[log] Target class : JailbreakDetection
[log] Target selector : isJailbreak
[log] Old return : 0x1
[log] New return : 0x0

If the return values is 0x0, function is returning false. Okay! I rewrote return value to 0x0 from 0x1.

f:id:yottiii:20190517133730j:plain

4. Conclution

I explained about how to avoid Jailbreak detection on iOS by using FRIDA.

Thank you for reading to the end. Next, I would like to write technical blog which avoids root detection for Android.

5. Reference & Bonus

5-1. Reference

www.frida.re

qiita.com