Dumping iOS app using Frida on Jailbroken device

Monday, June 28, 2021


 Components used:

  • Jailbreak (e.g., checkra1n is already done) completed already and installed Cydia (for checkra1n)
  • iproxy
  • Frida (version will be specified in a bit)
  • Jailbreak (e.g., checkra1n is already done) completed already and installed Cydia (for checkra1n)
  • frida-ios-dump (https://github.com/AloneMonkey/frida-ios-dump or my tweaked version https://github.com/kxynos/frida-ios-dump)
  • Ubuntu/Kali Linux system.. or anything similar.

Communicate with the iPhone 

I will assume you have jailbroken the iPhone and installed Cydia. I will also assume you are communicating with the device using iproxy and usbmuxd and not over local network (if so skip this section).

On you Ubuntu system get the following installed. 

Install libusbmuxd-tools usbmuxd
$ sudo apt install libusbmuxd-tools usbmuxd 
Run the proxy to listen on port 2222 and forward traffic to port 22. 
$ iproxy 2222 22
If you need to ssh to the device:
$ ssh -p 2222 root@127.0.0.1 
If you need to sftp to the device:
$ sftp -P 2222 root@127.0.0.1 
If you want to connect to Frida server that is listening only locally on the iPhone:
$ iproxy 27042 27042

Frida Server

We need Frida server running on the iPhone. There are two ways to do this, on demand and via a permanent service. If you install it via Cydia you can't pick the version of Frida to run. Also it is always running on the device (maybe something that you don't want.) but only listening on localhost (127.0.0.1) and port 27042. 

The other way is to download the server binary and run it when needed. Keep in mind that after version 14.2.13 the different server binaries don't have an option for arm/arm64. It has now moved to frida_14.2.14_iphoneos-arm.deb which is architecture agnostic (i.e., arm 32/64-bit). With this new file if you want to run a different version you can try the following to get you going.

If you want to extract the deb file into a custom directory (will assume /var/root for simplicity), you can try the following. 

These commands will change directory to '/var/root' , create a Frida directory and extract the files into that folder.  
$ cd /var/root
$ mkdir /var/root/frida
$ dpkg-deb -x ./frida_14.2.14_iphoneos-arm.deb /var/root/frida 

Create the frida library directory 
$ mkdir /usr/lib/frida
Symbolic link to the our version of the library (make sure Cydia version is removed or not installed. Also keep in mind that if you install the version from Cydia it will remove the symbolic link and it might use that library instead or at least try.)
$ ln -s /var/root/frida/usr/lib/frida/frida-agent.dylib /usr/lib/frida/frida-agent.dylib
You can then run Frida server as a process (can kill with CTRL+C)
$ ./frida/usr/sbin/frida-server 
As a process with access from your local network (assuming it is 192.168.1.0/24). With this method you can have latest version of Frida running via Cydia on localhost and another test version running on the local network one. 
$ ./frida/usr/sbin/frida-server -l 192.168.1.123 
As a daemon (you can safely disconnect from the phone)
$ ./frida/usr/sbin/frida-server -D

Frida Client test

So now you should be able to connect to the service. Let's test that with the client. 

Install Frida via pip. Be warned, I noticed that pip3 installs a different version. Make sure the version of client and server matches. If they don't you can always try and see if it works, I have had older versions work. It will depend on how drastic the changes between the versions are. Tread with care.
$ pip install frida
List the processes running over usb:
$ frida-ps -U

PID Name
---- --------------------------------------------------------
4001 Cydia
4437 Mail
2143 Settings
3085 iGoat-Swift
4376 AppPredictionWidget
4381 AppleCredentialManagerDaemon

List the install apps over localhost and iproxy (see above to setup iproxy on port 27042):
$ frida-ps -a -R 127.0.0.1
List the install apps over local network (see above):
$ frida-ps -a -R 192.168.1.123 

iOS Dump using Frida

It is possible to dump an iOS application using Frida. Using git clone get frida-ios-dump onto your Ubuntu System. Note, that frida-ios-dump uses SSH to connect to the phone (and alpine as a user. You can change this.) and dump the process locally first. 

Using frida-ps we can find the process name of the ipa we want to dump. Next we will use a command similar to the following (you will need iproxy listening on 2222 for it to work):
$ python dump.py -o CustomName.ipa PROCESS_NAME 
So an example of dumping the test app iGoat-Swift would be as follows:
$ python dump.py -o iGoat-Swift-dump.ipa iGoat-Swift
Or if you are going over your local network (add -p for port, when needed). 
$ python dump.py -H 192.168.1.123 -p 22 -o iGoat-Swift-dump.ipa iGoat-Swift 
If it fails to dump the process, try it a second and third time (CTRL+Z and kill -9 %1). I am not sure why it has issues. 

Example of extraction process getting stuck and I exit via CTRL+Z : 
$ python dump.py -o test1 iGoat-Swift
Start the target app iGoat-Swift
Dumping  to /tmp
[frida-ios-dump]: dlopen libswiftDarwin.dylib success. 
[frida-ios-dump]: dlopen libswiftUIKit.dylib success. 
[frida-ios-dump]: dlopen libswiftCoreImage.dylib success. 
[frida-ios-dump]: dlopen libswiftos.dylib success. 
[frida-ios-dump]: dlopen libswiftObjectiveC.dylib success. 
[frida-ios-dump]: dlopen libswiftCoreGraphics.dylib success. 
0.00B [00:00, ?B/s]
^C^Z
[1]+  Stopped                 python dump.py -o test1 iGoat-Swift



iPhone 6 on iOS 12.3.1 - checkra1n jailbreak - getting past error -31 (timeout error)

Thursday, January 28, 2021

I was having some fun trying to jailbreak an old iPhone 6 on iOS 12.3.1. I tried checkra1n 0.12.2 (https://checkra.in/) and some previous versions in GUI mode and was getting an error -31. 
It recommends the CLI. I tried that too but it didn't work as I only got the GUI in a text format. Then I used -h and found the CLI is actually enabled with the -c flag. I added -v to be verbose. 
I got then some more details about my error -31. It is a timeout issue. I also read online that it will re-attempt the jailbreak once you connect and in DFU mode.  (N.B: this is not the case when it is in GUI mode.) 
$ cd /Applications/checkra1n.app/Contents/MacOS
$ ./checkra1n -v -c
#
#
# Checkra1n beta 0.12.2
#
# Proudly written in nano
# (c) 2019-2020 Kim Jong Cracks
#
#======== Made by =======
# argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV
# never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza
#======== Thanks to =======
# haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini
# Cellebrite (ih8sn0w, cjori, ronyrus et al.)
#==========================


- [01/21/21 21:03:42] <Info>: Waiting for DFU devices
- [01/21/21 21:04:51] <Verbose>: DFU mode device found
- [01/21/21 21:04:52] <Info>: Exploiting
- [01/21/21 21:04:52] <Verbose>: Attempting to perform checkm8 on xxx xx...
- [01/21/21 21:04:52] <Info>: Checking if device is ready
- [01/21/21 21:04:52] <Verbose>: == Checkm8 Preparation stage ==
- [01/21/21 21:04:52] <Verbose>: DFU device disconnected
- [01/21/21 21:04:52] <Verbose>: DFU mode device found
- [01/21/21 21:05:17] <Error>: Timed out in state 1, assuming we are back to square one with this device. (error code: -31)

So I removed the USB from the iPhone and reconnected. I had to kill iTunes, hence the extra disconnect attempts. But once iTunes was closed it continued the jailbreak process. In the end use CTRL+C to exit. 
$ ./checkra1n -v -c
#
# Checkra1n beta 0.12.2
#
# Proudly written in nano
# (c) 2019-2020 Kim Jong Cracks
#
#======== Made by =======
# argp, axi0mx, danyl931, jaywalker, kirb, littlelailo, nitoTV
# never_released, nullpixel, pimskeks, qwertyoruiop, sbingner, siguza
#======== Thanks to =======
# haifisch, jndok, jonseals, xerub, lilstevie, psychotea, sferrini
# Cellebrite (ih8sn0w, cjori, ronyrus et al.)
#==========================

- [01/21/21 21:06:14] <Info>: Waiting for DFU devices
- [01/21/21 21:06:14] <Verbose>: DFU mode device found
- [01/21/21 21:06:14] <Info>: Exploiting
- [01/21/21 21:06:14] <Verbose>: Attempting to perform checkm8 on xxxx xx...
- [01/21/21 21:06:14] <Info>: Checking if device is ready
- [01/21/21 21:06:14] <Verbose>: == Checkm8 Preparation stage ==
- [01/21/21 21:06:14] <Verbose>: DFU mode device found
- [01/21/21 21:06:16] <Info>: Setting up the exploit (this is the heap spray)
- [01/21/21 21:06:16] <Verbose>: == Checkm8 Setup stage ==
- [01/21/21 21:06:16] <Info>: Right before trigger (this is the real bug setup)
- [01/21/21 21:06:16] <Verbose>: Entered initial checkm8 state after 0 steps, issuing DFU abort..
- [01/21/21 21:06:17] <Verbose>: DFU device disconnected
- [01/21/21 21:06:17] <Verbose>: DFU mode device found
- [01/21/21 21:06:17] <Verbose>: == Checkm8 Trigger stage ==
- [01/21/21 21:06:17] <Verbose>: Checkmate!
- [01/21/21 21:06:18] <Verbose>: DFU device disconnected
- [01/21/21 21:06:18] <Verbose>: DFU mode device found
- [01/21/21 21:06:20] <Verbose>: == Checkm8 Trying to run payload... ==
- [01/21/21 21:06:20] <Verbose>: If everything went correctly, you should now have code execution.
- [01/21/21 21:06:20] <Verbose>: DFU device disconnected
- [01/21/21 21:06:21] <Info>: Entered download mode
- [01/21/21 21:06:21] <Verbose>: Download mode device found
- [01/21/21 21:06:23] <Info>: Booting...
- [01/21/21 21:06:23] <Verbose>: Setting bootargs to: rootdev=md0
- [01/21/21 21:06:24] <Verbose>: Download mode device disconnected
- [01/21/21 21:06:48] <Info>: Uploading bootstrap...
- [01/21/21 21:06:48] <Verbose>: Uploading bootstrap... 6
- [01/21/21 21:06:49] <Info>: All Done
- [01/21/21 21:06:49] <Verbose>: Bootstrap upload done

Finally, you will need to connect to a network (check in General-Software Update-Automatic Updates-OFF). Within checkra1n, install Cydia. From Cydia install OpenSSH (if that is the aim). 

Enjoy !