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.
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.
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.
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.
and I made it Swift version.
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.
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.
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.
if you want to know API that is using inside my program, I recommend you to visit and look the site below.
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.
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.