Decrypting iOS Apps

This Writeup belongs to: (its just pasted here for my quick reference, I dont own this writeup)

Scenario

jailbreak -> select tool -> dump

Instruments

You have 3 options:

Additionally, you need SSH (OpenSSH) installed on a jailbroken iPhone to be able to copy dumped files.

Overview

An application from Apple App Store is encrypted with a hardware-backed cryptographic scheme. More precisely, an executable section of the O-Mach binary inside the IPA package is encrypted, and the decryption key is accessible only on a particular device on the hardware level (Secure Enclave). But if you wonder whether it is possible to decipher an application downloaded from Apple App Store to carry out static analysis - yes, it is possible.

In the annex, you can find How To Jailbreak iPhone 12.x and How to Fix Entitlements.

How Tools Work

All tools leverage a simple principle: these tools dump a decrypted binary from the running context in the memory. It is possible because the binary MUST be decrypted before it could be even run, and the binary is dumped into a file.

You MUST jailbreak iPhone to dump decrypted executable region to the filesystem. There is no way to easily decrypt an application by any kind of magic tool on a personal computer.

There are 2 approaches to dump deciphered executable region from memory to the filesystem. All of them require superuser privileges either to trace a process, or to inject a dynamic library.

Approach #1: attach to a process

Clutch and frida-ios-decrypt work this way.

  1. The tool (tracer) attaches to a running process (tracee).

  2. The deciphered executable is dumped from the memory into a file.

Step 1 (tracing the process) needs superuser privileges, that's why iPhone must be jailbroken.

Approach #2: library injection

dumpdecrypted.dylib works this way (through DYLD_INSERT_LIBRARIES).

  1. An application starts with a dynamic library linked into it.

  2. The dynamic library dumps decrypted executable right from the application user space memory.

Superuser privilege is needed to inject a custom dynamic library into the process memory.

How to Use "frida-ios-decrypt"

Prepare USB and SSH

The main script of "frida-ios-decrypt" dump.py uses the frida package which communicates with the device via USB. When the application is successfully dumped, files will have been copied from the device via SSH (scp) to the temporary folder. To summarize, your iPhone must be accessible via both USB and SSH.

An official guide suggests to set up SSH over USB, but that way seems to be a bit complicated. I found the easier way which is to connect an iPhone to your local network (connect to the same WiFi network) and modify dump.py as the following to allow the script to connect to the phone directly over your local network:

User = 'root'
Password = 'alpine'
Host = '192.168.88.102' # Fix the Host IP to a real iPhone IP
Port = 22

Steps

  1. frida-ios-dump looks for a device using SSH. Use "SSH over USB" approach, or connect your device to a local network and fix dump.py (see Preparation above).

  2. List running processes:

    python2 ./frida-ios-dump-master/dump.py -l
  3. Dump the target process:

    python2 ./frida-ios-dump-master/dump.py "TargetApp"

    or

    python2 ./frida-ios-dump-master/dump.py <pid>

Successful log

Start the target app TargetApp
Dumping TargetApp to /some/temp/path
[frida-ios-dump]: libswiftUIKit.dylib has been dlopen.
[frida-ios-dump]: libswiftIntents.dylib has been dlopen.
[frida-ios-dump]: libswiftCoreImage.dylib has been dlopen.
...
...A lot of noisy log may follow here
...
Generating "TargetApp.ipa"

Troubleshooting

Device is not found via USB

Waiting for USB device...

Ensure that you installed USB drivers for iPhone.

Also, if you're on Windows Subsystem for Linux (WSL), you would be unable to run "frida-ios-dump", because there is no USB drivers for iPhone under WSL, therefore iPhone cannot be enumerated. (Not sure about WSL 2 though).

Device is not found via SSH

Either way, if dump.py cannot connect to a device, you will see the following error:

*** Caught exception: <class 'socket.error'>: [Errno 11] Resource temporarily unavailable

or

*** Caught exception: <class 'socket.error'>: [Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Check whether you use a correct IP address in dump.py for your iPhone.

  1. On iPhone: go to Settings -> WiFi -> (i) -> get the IP.

  2. Verify the connection:ssh root@192.168.88.101

  3. Password: alpine

How to Use "Clutch"

IMPORTANT: On iPhone 12.x you need to fix entitlements ⬇️.

  1. Build and install the Clutch tool.

  2. List the processes:

    Clutch -i
  3. Dump the process obtaining decrypted binaries:

    Clutch -d 3

    "3" is the number of the application from the Clutch -i output.

How to Use "dumpdecrypted.dylib"

IMPORTANT: On iPhone 12.x you need to fix entitlements ➡️.

  1. Download dumpdecrypted.dylib to a computer.

  2. Copy dumpdecrypted.dylib to the system path on the phone via SSH using scp tool:

    scp dumpdecrypted.dylib root@192.168.88.101:/usr/lib/dumpdecrypted.dylib

    Choose a path, kind of /usr/lib, not $HOME, to evade problems with kernel sandboxing.

  3. Run the application with dumpdecrypted.dylib:

    DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/targetapp/targetapp

How to Jailbreak iPhone 12.x

  1. Download Cydia Impactor.

Sileo marketplace app appears after the jailbreak is installed.

  1. Go to the Sileo application.

  2. Find and install Frida and OpenSSH (sshd).

How to Fix Entitlements

The big advantage of "frida-ios-dump" against the "Clutch" and "dumpdecrypt.dylib" is that it doesn't need to fix entitlements of the target app.

Entitlements are special properties assigned to each application in iOS. Entitlements are signed and basically, it's not possible to change them without a jailbreak.

In iOS 12.x default entitlements of application don't allow tracing. In the case of Clutch you are going to see the following error:

Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed!

Steps to fix entitlements:

  1. Dump the current entitlements of the target application:

    ldid -e /var/containers/Bundle/Application/F8809B92-7794-4540-A4E2-0F541D78CF5A/TaretApp.app/TargetApp > ~/targetapp-ent.xml
  2. Fix entitlements adding the following line to targetapp-ent.xml:

    <key>platform-application</key>
    <true/>
    <key>get-task-allow</key>
    <true/>
    <key>run-unsigned-code</key>
    <true/>
    <key>com.apple.private.skip-library-validation</key>
    <true/>
    <key>com.apple.private.security.no-container</key>
    <true/>
  3. Assign new entitlements:

    ldid -S~/targetapp-ent.xml /var/containers/Bundle/Applicati

Last updated