Security

Application Security Testing on non-Jailbroken iOS from Linux

How to perform security checks of an iOS application file on a non-jailbroken iPhone from a Linux Machine.

Tue 08 October 2019

Overview

iOS application security testing do not require a jailbroken iPhone or iPad. This article is a living document that lists how to assess aspects of a Mobile Application on non-jailbroken phone.


NOTE

This assumes access to a non-encrypted IPA.


Apple Developer Account

For the purposes of security testing, we only require a free Apple developer account. To enroll see link on requirements.

For an individual, we only need an Apple ID and enable two factor authentication.

Paid Apple Developer Account provides features for application creators and for application distribution.

The Easy Method: Installation with Cydia Impactor

The easiest way to install an IPA application on an iOS device is to use Cydia Impactor. Cydia Impactor a free but not open source tool.

First, make sure to reset the certificate for the apple developer account, make sure your iOS or iPad device is detected and then select install package to install your application.

While Cydia is really simple to use, installation will fail if the application is not in debug mode or will fail at runtime because the entitlement was not proplerly patched

Full Control Method: ideviceinstaller and Manual Patching

Ths method is manual and consists of patching the IPA entitlements and then using ideviceinstaller to install the patched application.

Patch IPA to enable Debug Mode

The first issue you might run into is attempting to install a non-debug enabled application. iOS will complain about invalid signature.

To enable debug mode, first extract the entitlements from the IPA:

This might be done using jtool:

unzip app.ipa
./jtool.ELF64 -arch arm64 --ent Payload/myOstorlabApp.app/myOstorlabApp > /tmp.ent.xml

The generated entitlements will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>4ZX4Z3MVHG.com.appleseedinc.MyProject</string>
    <key>com.apple.developer.team-identifier</key>
    <string>4ZX4Z3MVHG</string>
    <key>get-task-allow</key>
    <true/>
    <key>keychain-access-groups</key>
    <array>
        <string>4ZX4Z3MVHG.com.appleseedinc.MyProject</string>
    </array>
</dict>
</plist>

Applications in debug mode, have the key get-task-allow set to <true/>. If it is not, modify the entilements and patch your binary with the newly created entitlements.

To do so, on Linux, use the following forked version of isign with support for alternate entitlements. isign is Python2 only:

from isign import isign
isign.resign("file.ipa", output_path="/tmp/new_ipa.ipa", alternate_entitlements_path="/tmp/ent.xml")

If you have an OpenSSL error, trying resinstall pyOpenSLL:

sudo python2 -m pip install pyOpenSSL

In case of an error, to see logs of isign, use the following code

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

isign might fail in a construct check, the check is incorrect, simply comment it out and retry.

Installation with ideviceinstaller

For ideviceinstaller, we first need to provision a developer certficate, to do so, use tools in the following repo:

 ./genProvisioningProfileFree.sh <AppleID> <Password> <Device UUID>

The UUID of your device can be retrieved using lsusb.

Once the developer account is provisioned, inspect the generated file in your home folder in .isign/isign.mobileProvision file and look for the value of <TeamIdentifier> which should look something like 4ZX4Z3MVHG. Use that value to modify the entitlements file replacing all occurrences of the previous team indentifier with your team value.

Sign the application with the modified entitlementent:

from isign import isign
isign.resign("file.ipa", output_path="/tmp/new_ipa.ipa", alternate_entitlements_path="/tmp/ent.xml")

Finally using ideviceinstaller to install the newly generated IPA.

ideviceinstaller -i /tmp/new_ipa.ipa

Miscellaneous Actions

The following is a list of useful actions to perform during an assessment:

Retrieve Developer Disk Image

Several imobiledevice tools requires mounting a Developer Disk Image. To downolad the disk image matching your OS version , see repo.

To mount the Disk Image, use ideviceimagemounter:

ideviceimagemounter -t Developer DeveloperDiskImage.dmg DeveloperDiskImage.dmg.signature

To check the disk is mounted properly:

ideviceimagemounter -l                                                                                                                                                                                     2 ↵
ImageSignature[1]: 
 0: OIrMZfwD5TcdgVaizBMAaImjwDXsrldgRDbsiSWbtafuf1t0BSJR9tDycyYPG3E+wmUY8fmP0l0S3UkMkQpJksFOx2fn0h1lAuhAiP9bJBjZ6PvbetHE/A2XJNVu78obBZl9dAzgpIEHPSvu6HJM7mdZrdFjA7GG7QJOnCL4Vnc=

Access Device Logs

To access the iOS device log, use idevicesyslog after mounting the Developer Disk Image.

Take Screenshot

To take a screenshot, use the idevicescreenshot after mounting the Developer Disk Image.

Attaching LLDB Debugger

LLDB debugger on Linux do not support remote-ios as a target.