REX logo

LEARN

HOW TO USE REX AND WRITE SECURE CODE
8 bit drawing of Jay

Secure Mobile Application
Development

Part 7: Root/Jailbreak Detection

Jahmel Harris, Technical Director

One security control to consider is root and jailbreak (Android and iOS respectively) detection. This control will limit applications to only run on non rooted or non Jailbroken devices. Users will often root or jailbreak their device in order to run applications that require higher privileges than that provided natively to applications, however this weakens the security controls provided by the Operating System.

On a device that has been rooted or jailbroken, malware running with higher than normal privileges will be able to access the application sandbox and attackers can take advantage of the weakened security controls to perform advanced binary/dynamic analysis.

Attackers will often run applications on a rooted or jailbroken device in order to have a better understanding of how the application works by bypassing the Operating System controls and so by detecting when a rooted or jailbroken device is in use, the application can decide whether it should be run in a potentially untrusted environment. Care should be taken when implementing this security control. Like all binary protection controls, an attacker will be able to bypass root/jailbreak detection with enough time. This control will also limit the install base to users not running on compromised devices. Depending on the implementation of this of control, there may be false positives, frustrating users.

An alternative approach to jailbreak and root detection is to detect and send the status to a remote server. The server can then decide whether the application should be disabled based on the risk profile of the application. Care should be taken that an attacker cannot intercept and modify the response, allowing the application to run on a rooted or jailbroken device.

To increase the effectiveness of these controls, it is recommended that all checks are performed in many locations throughout the application and before any sensitive operations occur. All checks should be inline (i.e. no single function an attacker can modify) and use a mix of layers e.g. both within the main application and within libraries.

iOS

iOS provides no standard way of performing jailbreak detection. Several common ways to detect the presence of a Jailbroken device will be shown here, however it is likely that any common technique can be easily bypassed by an experienced attacker. Because of this, it is important to look for and discover new techniques for detecting the presence of a jailbroken device.

Some common techniques that can be used:

  • Looking for the presence of files which are created during the jailbreak process.
  • Looking for read/write permissions on the root partition.
  • Changes in size to the /etc/fstab file.
  • Symbolic links in use, replacing the original files
  • Looking at the return value of the fork() system call.
  • Looking at the return value of the system() system call with a NULL arguments.
  • Using _dyld_image_count() and _dyld_get_image_name() to see the currently loaded dylibs.
  • Looking for an open SSH port on the device.
  • Looking for the cydia:// URI scheme.
Android

Android provides no standard way of performing root detection. Several common ways to detect the presence of a rooted device will be shown here, however it is likely that any common technique can be easily bypassed by an experienced attacker. Because of this, it is important to look for and discover new techniques for detecting the presence of a rooted device.

Some common techniques that can be used:

  • Checking the BUILD tag (ro.build.tags) for “test-keys” which is present on emulated or unofficial Google builds.
  • Looking for the presence of files required for rooting a device – such as Superuser.apk or the su binary.
  • Looking for packages required for rooting or commonly installed on rooted devices.
  • Looking for write permissions normally write protected directories.
  • Executing binaries that are only present on rooted devices such as su or busybox.
  • SafetyNet API.

To increase the time needed to bypass this control, it is recommended that the checks are implemented in native code (i.e. in c) and protected with other binary protections such as runtime integrity checks, hooking prevention and obfuscation.