IOS ApplicationSecurity Part 24 J ailbreak DetectionandEvasion.html[25.05.201418:09:25]
In this article, we will look at the checks a developer can incorporate in his application to check whether the device on which the application is running is jailbroken or not. Checking whether a device is jailbroken or not can have many advantages for your application. As we have already seen, an attacker can run tools like Cycript, GDB, Snoop-it etc to perform runtime analysis and steal sensitive data from within your application. If you are really looking to add an extra layer of security for your application, you should not allow your application to be run on a jailbroken device. Please note that millions of users jailbreak their devices and hence not allowing an application to be run on a jailbroken device could have a significant impact on your user base. Another thing you can do is instead block some of the features in your application rather than disabing it entirely. We will also look at how hackers can bypass the check for jailbreak detection in your application using Cycript. Once a device is jailbroken, a lot of other files and applications are installed on the devcice. Checking for these files in the filesystem can help us identify whether the device is jailbroken or not. For e.g, most of the jailbreak softwares install Cydia on the device after jailbreaking. Hence just a simple check for the file path of Cydia can determine whether the device is jailbroken or not. NSSt r i ng *f i l ePat h = @" / Appl i cat i ons/ Cydi a. app" ; i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: f i l ePat h] ) { / / Devi ce i s j ai l br oken } However, not all devices that are jailbreaked have Cydia installed on them. In fact, most hackers can just change the location of the Cydia App. Checking for many other files related to J ailbroken devices can make this method much more efficient. For e.g, one can check if Mobile Substrate is installed on the device or not, which many applications require to run on a jailbroken device. One can also check for the location of the SSH Daemon, or the shell interpreter. Combining all these checks, we get a method like this. +( BOOL) i sJ ai l br oken{ IOS Application Security Part 24 J ailbreak Detection and Evasion Source: http://highaltitudehacks.com/2013/12/17/ios-application-security-part-24-jailbreak-detection-and-evasion/ IOS Application Security Part 24 J ailbreak Detection and Evasion Dec 17th, 2013 Posed by Prateek Gianchandani EvernoteExport IOS ApplicationSecurity Part 24 J ailbreak DetectionandEvasion.html[25.05.201418:09:25]
i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / Appl i cat i ons/ Cydi a. app" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / Li br ar y/ Mobi l eSubst r at e/ Mobi l eSubst r at e. dyl i b" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / bi n/ bash" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / usr / sbi n/ sshd" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / et c/ apt " ] ) { r et ur n YES; } r et ur n NO; } We have also learnt from the previous articles that applications that run as a mobile user run in a sandboxed environment and go inside the directory /var/mobile/Applications whereas applications that run with the root user (e.g Apples preloaded applications) arent subject to any sandbox environment and go inside the directory /Applications. A user running a jailbroken device can install your application in the /Applications folder thereby giving it root privileges. Hence, adding a check to see whether the application follows sandboxing rules can help the user identify whether the application is jailbroken or not. A good way to check for it would be to see if we can modify a file in some other location outside the application bundle. NSEr r or *er r or ; NSSt r i ng *st r i ngToBeWr i t t en = @" Thi s i s a t est . " ; [ st r i ngToBeWr i t t en wr i t eToFi l e: @" / pr i vat e/ j ai l br eak. t xt " at omi cal l y: YES encodi ng: NSUTF8St r i ngEncodi ng er r or : &er r or ] ; i f ( er r or ==ni l ) { / / Devi ce i s j ai l br oken r et ur n YES; } el se { / / Devi ce i s not j ai l br oken [ [ NSFi l eManager def aul t Manager ] r emoveI t emAt Pat h: @" / pr i vat e/ j ai l br eak. t xt " er r or : ni l ] ; }
We know that a skilled hacker can just modify the location of the application. However, we know that 80% or more of the devices that are jailbroken have Cydia installed on them, and even if the hacker can change the location of the Cydia app, he most probably wont change the URL scheme with which the Cydia app is registered. If calling the Cydias URL scheme (cydia://) from your application gives a success, you can be sure that the device is jailbroken. i f ( [ [ UI Appl i cat i on shar edAppl i cat i on] canOpenURL: [ NSURL URLWi t hSt r i ng: @" cydi a: / / package/ com. exampl e. package" ] ] ) { / / Devi ce i s j ai l br oken } Lets also add a condition to make sure this code does not execute if we are testing our application on a simulator and not an actual device. After combining all the above techniques, our method looks like this. EvernoteExport IOS ApplicationSecurity Part 24 J ailbreak DetectionandEvasion.html[25.05.201418:09:25] +( BOOL) i sJ ai l br oken{
#i f ! ( TARGET_I PHONE_SI MULATOR)
i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / Appl i cat i ons/ Cydi a. app" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / Li br ar y/ Mobi l eSubst r at e/ Mobi l eSubst r at e. dyl i b" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / bi n/ bash" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / usr / sbi n/ sshd" ] ) { r et ur n YES; }el se i f ( [ [ NSFi l eManager def aul t Manager ] f i l eExi st sAt Pat h: @" / et c/ apt " ] ) { r et ur n YES; }
NSEr r or *er r or ; NSSt r i ng *st r i ngToBeWr i t t en = @" Thi s i s a t est . " ; [ st r i ngToBeWr i t t en wr i t eToFi l e: @" / pr i vat e/ j ai l br eak. t xt " at omi cal l y: YES encodi ng: NSUTF8St r i ngEncodi ng er r or : &er r or ] ; i f ( er r or ==ni l ) { / / Devi ce i s j ai l br oken r et ur n YES; } el se { [ [ NSFi l eManager def aul t Manager ] r emoveI t emAt Pat h: @" / pr i vat e/ j ai l br eak. t xt " er r or : ni l ] ; }
i f ( [ [ UI Appl i cat i on shar edAppl i cat i on] canOpenURL: [ NSURL URLWi t hSt r i ng: @" cydi a: / / package/ com. exampl e. package" ] ] ) { / / Devi ce i s j ai l br oken r et ur n YES; } #endi f
/ / Al l checks have f ai l ed. Most pr obabl y, t he devi ce i s not j ai l br oken r et ur n NO; } Honestly speaking, there is no foolproof method of detecting jailbroken devices. A skilled hacker will always find a way to bypass these checks. He can simply find the instructions in the binary and replace all instructions with No-op. He can also swizzle your method implementation with his own using Cycript. He can first find the class information of the application using Class-dump-z. Over here, he can see a method named +(BOOL)isJ ailbroken in the J ailbreakDetector class. Note that it is a class method as it begins with positive sign. It obviously means this method checks whether a device is jailbroken or not and returns YES if the device is jailbroken. If you are not getting any of this, you should consider reading previousarticles. EvernoteExport IOS ApplicationSecurity Part 24 J ailbreak DetectionandEvasion.html[25.05.201418:09:25] He can then hook into this application using Cycript. And then print out all the methods for the J ailbreakDetector class. Please note that we are using J ailbreakDetector->isa.messages because isJ ailbroken is a class method. To find the instance methods, just using J ailbreakDetector.messages would have worked for us. EvernoteExport IOS ApplicationSecurity Part 24 J ailbreak DetectionandEvasion.html[25.05.201418:09:25] And then he can swizzle the method implementation with his own that always returns a NO. If you are not getting this, i suggest that you read the article on Method Swizzling. As a developer, what we can do is change the method name to something that doesnt look quite appealing to the hacker. For e.g, the className J ailbreakDetector could be renamed as ColorAdditions and the method +(BOOL)isJ ailbroken could be replaced by +(BOOL)didChangeColor with the implementation being the same. Something like this wouldnt attract the attention of the hacker. He can always look at the calls that are being made inside this method using Snoop-it, GDB etc, but a small change like this can surely help in confusing him.