Back

Reverse Engineering iOS Applications in a Fun Way

Analyzing iOS application files to manipulate objective C functions is not a trivial process. The most common way to perform reverse engineering is by class dumping ipa files to discover all the class names and methods present in an application. This can be done using Cycript. Cycript is present within Cydia, and Cydia is installed by default when we jailbreak an iOS device.

A common way to manipulate the run time environment is by calling methods present within an application. Any process can be hooked with Cycript using the following steps:

  • Attach to the process using Cycript
  • Print all the method and class names
  • Replacing existing Objective-C methods using MobileSubstrate framework.

A more technical and step by step process to perform the above process is given on the iPhone Dev Wiki.

The most difficult and time consuming part is recognizing the classes and the objects used to call required methods. The traditional approach is to perform a class dump of the binary to get the methods that can be invoked.

We can use ‘Crackulous‘ to dump out the unencrypted version of the application and use ‘class-dump-z‘ to spit out the method names present in the _OBJC segment. There are also a couple of tools (iNalyzer and Snoop-it) that save a lot of time and perform reverse engineering and function hooking for the entire application.

I have analyzed the TWCSportsNet application in this blog. The reason why I choose this application is because it has two security controls implemented. It does not work if the following conditions are not met:

  1. The device is a non jailbroken device.
  2. The live streaming option is not available for any other region except Southern California and Nevada.

We will bypass those restrictions by using two modern tools called iNalyzer and Snoop-it.

iNalyzer:

iNalyzer is a handy tool developed by AppSec Labs. It creates an entire mapping of the application and dumps outs a doxygen script which is used to create an html page that shows all the method and class names. It also creates a graphical view of classes and functions using Graphviz.

In order to use this, we have to download a client side application on a jailbroken device. When the application is started, it will create a web listener on port 5544. We can connect to the port through our laptop by visiting https://iphoneIPaddress:5544.

Next we point iNalyzer to the application that we want to reverse engineer. iNalyzer will extract the entire application and create a zip file. After unzipping the file, there is a dox.template file present in appname/ Payload/Doxygen/ folder. This file can be given as an input to Doxygen and it will output an html file that consists of the mapping of the entire application.

Limits of iNalyzer:

It does not let us dynamically analyze the work flow of the application. For example, if we click a send button on an iOS application, we do not get to see the classes and the various methods that will be invoked.

Vk Ios

Fig 1: Showing iNalyzer output for the TWCSportsNet application.

iNalyzer helps in interacting with applications by dynamically and invoking methods. It uses Cycript as the base to do so. However, I was not able to perform any dynamic interaction with the application using iNalyzer. I used a different tool called Snoop-It to interact and invoke different methods.

Snoop-it

Snoop-it is an amazing tool developed by Neso Labs. It is used to perform comprehensive dynamic analysis. We can trace and manipulate internal state and the processing logic of iOS application. We can install Snoop-it by adding the https://repo.nesolabs.de/ repository via Cydia on a Jailbroken device.

Snoop-it has various features within it such as avoiding detection of a jailbroken iOS device.

Most of the applications detect jailbroken devices by looking for common paths like the Cydia installation directory (/Applications/Cydia.app) or /private/var/stash. Normal methodology without using any new tools like iNalyzer or Snoop-it would consist of identifying the functionality which detects jailbroken devices, and then performs function hooking using MobileSubstrate tweak.

Bypass jailbreak detection:

Vk Ios

Fig. 2: Before and After using Snoop-It

Analyzing Objective-C Classes.

Vk Ios

Fig 3: BestEffortLocation method contains my actual latitude and longitude

When I looked at the class LocationServicesManager there is a BestEffortLocation method which stores my current location.

Vk Ios

Fig 4: Function which sets a Boolean flag depending on user’s current location.

Monitor application activity via Method Tracing.

The location has been updated and sent to the server through an HTTP request which sends my current latitude and longitude. We can trace the calls and corresponding methods when any kind of activity is performed by enabling the Method Tracing functionality.

Vk Ios

Fig 5: Longitude and latitude been send via footprint service.

Intercept the request and change the location via Burp.

Vk Ios

Fig 6: Intercepted and modified request using burp.

Vk Ios

Fig. 7: Before and After changing the location

The request can be intercepted and by changing the longitude and latitude to a location in Los Angeles, we can view live television and bypass the location restriction. Although this could be performed directly via manipulation of parameters via a proxy, Snoop-it and iNalyzer gives us an in-depth view about the inner functionality of the application.

Spoof location and Fake UDID, Mac address of the device.

Vk Ios

Fig 8: Fake location and fake UDID.

There are various other functionalities like monitoring the file system, checking out stored values in keychains and looking at the network traffic which can come in handy to save time during penetration testing of iOS applications.

Conclusion:

To conclude, Snoop-it and iNalyzer make reverse engineering fun and less time consuming. It gives a gray box approach to penetration testing of iOS applications.

References:

Back

Android Root Detection Techniques

Introduction

I have taken a look at a lot of Mobile Device Management (MDM) solutions lately to figure out how they are detecting rooted Android devices. Through some research I have discovered that many of these MDM solutions use similar methods to detect rooted devices. This usually involves looking for specific packages and files, directory permissions, and running certain commands. I won’t be disclosing which MDMs use which methods, but I will provide a list of packages, files, folders, and commands that I have found to be used in root detection. All the commands I will be running are on a stock rooted Nexus 4 running Android 4.2.2.

Default Files & Configurations

The first root detection checks are for default files and configurations that should be present on a non-rooted device. These may also be present in rooted devices with non-custom roms.

  1. Checking the BUILD tag for test-keys. By default, stock Android ROMs from Google are built with release-keys tags. If test-keys are present, this can mean that the Android build on the device is either a developer build or an unofficial Google build. My Nexus 4 is running stock Android from Google’s (Android Open Source Project) AOSP. This is why my build tags show release-keys.
    root@android:/ # cat /system/build.prop | grep ro.build.tags
    ro.build.tags=release-keys
  2. Checking for Over The Air (OTA) certs. By default, Android is updated OTA using public certs from Google. If the certs are not there, this usually means that there is a custom ROM installed which is updated through other means. My Nexus 4 has no custom ROM and is updated through Google. Updating my device however, will probably break root.

    root@android:/ # ls -l /etc/security/otacerts.zip
    ls -l /etc/security/otacerts.zip
    -rw-r--r-- root     root         1733 2008-08-01 07:00 otacerts.zip

Installed Files & Packages

There are many files and packages that MDMs look for when detecting if a device is rooted. I have compiled a list of ones that I know for sure are being detected.

  1. Superuser.apk. This package is most often looked for on rooted devices. Superuser allows the user to authorize applications to run as root on the device.
  2. Other packages. The following list of packages are often looked for as well. The last two facilitate in temporarily hiding the su binary and disabling installed applications.
    com.noshufou.android.su
    com.thirdparty.superuser
    eu.chainfire.supersu
    com.koushikdutta.superuser
    com.zachspong.temprootremovejb
    com.ramdroid.appquarantine
  3. The following command lists packages that are currently installed on your device.
    root@android:/ # pm list packages
    package:com.android.backupconfirm
    package:com.android.bluetooth
    package:com.android.browser.provider
    package:com.android.calculator2
    package:eu.chainfire.supersu
  4. Any chainfire package. One MDM looks for any package that is developed by chainfire. The most notable one being SuperSU.
  5. Cyanogenmod.superuser. If the Cyanogenmod ROM is installed, the cyanogenmod.superuser activity may be in the com.android.settings package. This can be detected by listing the activities within com.android.settings.
  6. Su Binaries. The following list of Su binaries are often looked for on rooted devices.
    /system/bin/su
    /system/xbin/su
    /sbin/su
    /system/su
    /system/bin/.ext/.su
    /system/usr/we-need-root/su-backup
    /system/xbin/mu

Directory Permissions

Sometimes when a device has root, the permissions are changed on common directories. I have never seen this personally, but it is being checked for.

  1. Are the following directories writable.
    /data
    /
    /system
    /system/bin
    /system/sbin
    /system/xbin
    /vendor/bin
    /sys
    /sbin
    /etc
    /proc
    /dev
  2. Can we read files in /data. The /data directory contains all the installed application files. By default, /data is not readable.

Commands

A few MDMs execute common commands to detect if a device is rooted.

  1. Su. Execute su and then id to check if the current user has a uid of 0 or if it contains (root).
    shell@android:/ $ su
    shell@android:/ # id
    uid=0(root) gid=0(root) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),1028(sdcard_r)
  2. Busybox. If a device has been rooted, more often then not Busybox has been installed as well. Busybox is a binary that provides many common linux commands. Running Busybox is a good indication that a device has been rooted.
    root@android:/ # busybox df
    Filesystem           1K-blocks      Used Available Use% Mounted on
    tmpfs                   958500        32    958468   0% /dev
    tmpfs                   958500         0    958500   0% /mnt/secure
    tmpfs                   958500         0    958500   0% /mnt/asec
    tmpfs                   958500         0    958500   0% /mnt/obb

Conclusion

This is probably no where near a complete list, but it does show the many different ways root can be detected on Android devices. Blacklisting packages and binaries seems to be the simplest and most effective way to detect root. This is especially true if your device is running a stock ROM from Google that has been rooted like mine where the only difference is the addition of su and a couple packages. At some point in the future I would like to create an app that will provide all these checks before installing an MDM. I touch on bypassing AirWatch root detection in my blog here:  https://www.netspi.com/blog/entryid/192/bypassing-airwatch-root-restriction, however, AirWatch has made some changes so it may not work anymore depending on your environment.

Discover how NetSPI ASM solution helps organizations identify, inventory, and reduce risk to both known and unknown assets.

X