Thursday, May 15, 2014

Jailbreak Detection Methods

The purpose of this post is to summary methods used for iOS jailbreak detection.

1. Using the Filesystem

The jailbreak process modifies the filesystem by adding, moving and changing files and directories. These changes can be used to detect if the device is jailbroken or not.
All methods presented in this point can be easily detected (it is very easy to find appropriate string in the application) and can be very easily bypassed (simple file name change can bypass this detection).
  • Existence of file

Some of the files are related to jailbroken device. Detection is achieved by means of checking if these files are accessible. The most popular files are listed below:

  • Size of /etc/fstab file

The /etc/fstab file contains mount points for the system. Many jailbreaking tools modify this file by adding some entries. As a result file size is modified. Even thought it is not possible to read the file, the application can attempt to check the file size.
The size of the file can be changed when new updates are installed.
  • Read/Write permission to the root partition

During the jailbreaking process the access to the root partition is amended. This can be checked in order to detect if device has been jailbroken.
  • Existence of symbolic links

Some of the directories are originally located in the small system partition. During the jailbreak process this partition is overwritten. The data must be relocated to the large, data partition. Because the old file location must be valid, symbolic links are created. The following list contains files/directories which are symbolic links on the jailbroken devices.

  • Directory permissions

Similar to checking existence of files/directories, the permissions can be checked.
  • Writing file

On the jailbroken device the applications are installed the /Applications folder thereby are given root privileges. It can be checked, if the application is able to modify files outside of its sandbox. This can be done by simply creating a file in the /private directory.

2. API Calls detection

Some API calls provided by the iOS system behave differently if run on the jailbroken device.
Appropriate implementation can be very difficult to detect and bypassed.
  • fork()

The sandbox denies process forking on devices in jail. By checking the returned pid on fork(), the application can detect if it has successfully forked or not, at which point it can determine if it is running on a jailbroken device.
  • system()

Calling the system() function with a NULL argument on a device in jail will return 0; doing the same on a jailbroken device will return 1. This is since the function will check whether /bin/sh exists, and this is only the case on jailbroken devices.
  • vm_protect() - obsolete

On the iOS device prior or equal to  iOS 4.3.3 the page of the memory could not be marked as executable if device is not jailbroken. Later versions of iOS have fixed this.
  • dyld functions

By far the hardest to get around. Calling functions like _dyld_image_count() and _dyld_get_image_name() to see which dylibs are currently loaded. Very difficult to patch, as patches are themselves part of dylibs.

3. Services detection

The jailbroken device mainly runs some services. The can be check in order to detect if device is jailbroken.
This method can be very time consuming (if ssh is not installed, the connection must be timeout). It is also very easy to bypass by changing the port for the OpenSSH service.
  • OpenSSH

Due to the very large portion of jailbroken devices that have OpenSSH installed, some rogue apps will attempt to make a connection to on port 22. If the connection succeeds, it should mean that OpenSSH is installed and running on the device, which obviously indicates that it is jailbroken.

4. Scheme detection

It is difficult to change scheme for the iOS however the Cydia can be removed during the testing process.
  • Cydia

Most of the devices that are jailbroken have Cydia installed. Notwithstanding the fact that the hacker can change the location of the Cydia app, he won’t change the URL scheme the Cydia app is registered with.
If calling the Cydia’s URL scheme (cydia://) from your application gives a success, you can be sure that the device is jailbroken.

5. Summary

The more complicated jailbreak detection is, the more difficult is to detect and bypass it. It is important not to create the detection runtime which returns true or false. It is very easy to locate this runtime and modify it.