☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks repo and hacktricks-cloud repo.
{% hint style="info" %} Perform this actions having connected the device to the computer via USB and having the device unlocked. {% endhint %}
The UDID is a 40-digit unique sequence of letters and numbers to identify an iOS device. You can find the UDID of your iOS device on macOS Catalina onwards in the Finder app, as iTunes is not available anymore in Catalina. Just select the connected iOS device in Finder and click on the information under the name of the iOS device to iterate through it. Besides the UDID, you can find the serial number, IMEI and other useful information.
If you are using a macOS version before Catalina, you can find the UDID of your iOS device via iTunes, by selecting your device and clicking on "Serial Number" in the summary tab. When clicking on this you will iterate through different metadata of the iOS device including its UDID.
It is also possible to get the UDID via various command line tools on macOS while the device is attached via USB:
-
By using the I/O Registry Explorer tool
ioreg
:$ ioreg -p IOUSB -l | grep "USB Serial" | "USB Serial Number" = "9e8ada44246cee813e2f8c1407520bf2f84849ec"
-
By using ideviceinstaller (also available on Linux):
$ brew install ideviceinstaller $ idevice_id -l 316f01bd160932d2bf2f95f1f142bc29b1c62dbc
-
By using the system_profiler:
$ system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p;/iPhone/,/Serial/p;/iPod/,/Serial/p' | grep "Serial Number:" 2019-09-08 10:18:03.920 system_profiler[13251:1050356] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be Serial Number: 64655621de6ef5e56a874d63f1e1bdd14f7103b1
-
By using instruments:
$ instruments -s devices
After jailbreaking the device you should have installed some new app manager like Cydia.
In order to enable SSH access to your iOS device you can install the OpenSSH package. Once installed, you can access your device via ssh running ssh root@<device_ip_address>
, which will log you in as the root user:
$ ssh root@192.168.197.234
root@192.168.197.234's password:
iPhone:~ root#
When accessing your iOS device via SSH consider the following:
- The default users are
root
andmobile
. - The default password for both is
alpine
.
Remember to change the default password for both users
root
andmobile
as anyone on the same network can find the IP address of your device and connect via the well-known default password, which will give them root access to your device.
During a real black box test, a reliable Wi-Fi connection may not be available. In this situation, you can use usbmuxd to connect to your device's SSH server via USB.
Connect macOS to an iOS device by installing and starting iproxy:
$ brew install libimobiledevice
$ iproxy 2222 22
waiting for connection
The above command maps port 22
on the iOS device to port 2222
on localhost. You can also make iproxy run automatically in the background if you don't want to run the binary every time you want to SSH over USB.
With the following command in a new terminal window, you can connect to the device:
$ ssh -p 2222 root@localhost
root@localhost's password:
iPhone:~ root#
Small note on USB of an iDevice: on an iOS device you cannot make data connections anymore after 1 hour of being in a locked state, unless you unlock it again due to the USB Restricted Mode, which was introduced with iOS 11.4.1
While usually using an on-device shell (terminal emulator) might be very tedious compared to a remote shell, it can prove handy for debugging in case of, for example, network issues or check some configuration. For example, you can install NewTerm 2 via Cydia for this purpose (it supports iOS 6.0 to 12.1.2 at the time of this writing).
In addition, there are a few jailbreaks that explicitly disable incoming SSH for security reasons. In those cases, it is very convenient to have an on-device shell app, which you can use to first SSH out of the device with a reverse shell, and then connect from your host computer to it.
Opening a reverse shell over SSH can be done by running the command ssh -R <remote_port>:localhost:22 <username>@<host_computer_ip>
.
On the on-device shell app run the following command and, when asked, enter the password of the mstg
user of the host computer:
ssh -R 2222:localhost:22 mstg@192.168.197.235
On your host computer run the following command and, when asked, enter the password of the root
user of the iOS device:
$ ssh -p 2222 root@localhost
If you forget your password and want to reset it to the default alpine
:
-
Edit the file
/private/etc/master.passwd
on your jailbroken iOS device using an on-device terminal or using apps like Filza or iFile -
Find the lines:
root:xxxxxxxxx:0:0::0:0:System Administrator:/var/root:/bin/sh mobile:xxxxxxxxx:501:501::0:0:Mobile User:/var/mobile:/bin/sh
-
Change
xxxxxxxxx
to/smx7MYTQIi2M
(which is the hashed passwordalpine
) -
Save and exit
As we know now, files from our app are stored in the Data directory. You can now simply archive the Data directory with tar
and pull it from the device with scp
:
iPhone:~ root# tar czvf /tmp/data.tgz /private/var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693
iPhone:~ root# exit
$ scp -P 2222 root@localhost:/tmp/data.tgz .
iFunbox is a GUI application that can be used for several things (uploading/downloading files among them).
Another GUI tool for this purpose is iExplorer.
{% hint style="info" %} Starting in iOS version 8.4, Apple has restricted the third-party managers to access to the application sandbox, so tools like iFunbox and iExplorer no longer display/retrieve files from apps installed on the device if the device isn't jailbroken. {% endhint %}
When you are starting objection (objection --gadget com.apple.mobilesafari explorer
) you will find the prompt within the Bundle directory.
org.owasp.MSTG on (iPhone: 10.3.3) [usb] # pwd print
Current directory: /var/containers/Bundle/Application/DABF849D-493E-464C-B66B-B8B6C53A4E76/org.owasp.MSTG.app
Use the env
command to get the directories of the app and navigate to the Documents directory.
org.owasp.MSTG on (iPhone: 10.3.3) [usb] # cd /var/mobile/Containers/Data/Application/72C7AAFB-1D75-4FBA-9D83-D8B4A2D44133/Documents
/var/mobile/Containers/Data/Application/72C7AAFB-1D75-4FBA-9D83-D8B4A2D44133/Documents
With the command file download <filename>
you can download a file from the iOS device to your host computer and can analyze it afterwards.
org.owasp.MSTG on (iPhone: 10.3.3) [usb] # file download .com.apple.mobile_container_manager.metadata.plist
Downloading /var/mobile/Containers/Data/Application/72C7AAFB-1D75-4FBA-9D83-D8B4A2D44133/.com.apple.mobile_container_manager.metadata.plist to .com.apple.mobile_container_manager.metadata.plist
Streaming file from device...
Writing bytes to destination...
Successfully downloaded /var/mobile/Containers/Data/Application/72C7AAFB-1D75-4FBA-9D83-D8B4A2D44133/.com.apple.mobile_container_manager.metadata.plist to .com.apple.mobile_container_manager.metadata.plist
You can also upload files to the iOS device with file upload <local_file_path>
.
During development, apps are sometimes provided to testers via over-the-air (OTA) distribution. In that situation, you'll receive an itms-services link, such as the following:
itms-services://?action=download-manifest&url=https://s3-ap-southeast-1.amazonaws.com/test-uat/manifest.plist
You can use the ITMS services asset downloader tool to download the IPA from an OTA distribution URL. Install it via npm:
$ npm install -g itms-services
Save the IPA file locally with the following command:
# itms-services -u "itms-services://?action=download-manifest&url=https://s3-ap-southeast-1.amazonaws.com/test-uat/manifest.plist" -o - > out.ipa
-
From an IPA:
If you have the IPA (probably including an already decrypted app binary), unzip it and you are ready to go. The app binary is located in the main bundle directory (.app), e.g.
Payload/Telegram X.app/Telegram X
. See the following subsection for details on the extraction of the property lists.On macOS's Finder, .app directories are opened by right-clicking them and selecting "Show Package Content". On the terminal you can just
cd
into them. -
From a Jailbroken device:
If you don't have the original IPA, then you need a jailbroken device where you will install the app (e.g. via App Store). Once installed, you need to extract the app binary from memory and rebuild the IPA file. Because of DRM, the app binary file is encrypted when it is stored on the iOS device, so simply pulling it from the Bundle (either through SSH or Objection) will not be sufficient to reverse engineer it (read next section).
Unlike an Android Application, the binary of an iOS app can only be disassembled and not decompiled.
When an application is submitted to the app store, Apple first verifies the app conduct and before releasing it to the app-store, Apple encrypts the binary using FairPlay. So the binary download from the app store is encrypted complicating ting the reverse-engineering tasks.
However, note that there are other third party software that can be used to obfuscate the resulting binaries.
In order to run the encrypted binary, the device needs to decrypt it in memory. Then, it's possible to dump the decrypted binary from the memory.
First, check if the binary is compiled with the PIE (Position Independent Code) flag:
otool -Vh Original_App #Check the last word of the last line of this code
Home:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 EXECUTE 47 6080 NOUNDEFS DYLDLINK TWOLEVEL PIE
If it's set you can use the script change_macho_flags.py
to remove it with python2:
python change_mach_o_flags.py --no-pie Original_App
otool -Vh Hello_World
Hello_World:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC ARM V7 0x00 EXECUTE 22 2356 NOUNDEFS DYLDLINK TWOLEVEL MH_NO_HEAP_EXECUTION
Now that the PIE flag isn't set, the OS will load the program at a fixed starting location every-time. In order to find this location you can use:
otool -l Original_App | grep -A 3 LC_SEGMENT | grep -A 1 __TEXT
segname __TEXT
vmaddr 0x00004000
Then, it's necessary to extract the the memory range that needs to be dumped:
otool -l Original_App | grep -A 4 LC_ENCRYPTION_INFO
cmd LC_ENCRYPTION_INFO
cmdsize 20
cryptoff 16384
cryptsize 17416192
cryptid 0
The value of cryptoff
indicated the starting address of the encrypted content and the cryptsize
indicates the size of the encrypted content.
So, the start address
to dump will be vmaddr + cryptoff
and the end address
will be the start address + cryptsize
In this case: start_address = 0x4000 + 0x4000 = 0x8000
__ and end_address = 0x8000 + 0x109c000 = 0x10a4000
With this information it's just necessary to run the application in the jailbroken device, attach to the process with gdb (gdb -p <pid>
) and dump the memory:
dump memory dump.bin 0x8000 0x10a4000
Congrats! You have decrypted the encrypted section in dump.bin. Now transfer this dump to your computer and overwrite the encrypted section with the decrypted one:
dd bs=1 seek=<starting_address> conv=notrunc if=dump.bin of=Original_App
There is one more step to complete. The application is still indicating in its metadata that it's encrypted, but it isn't. Then, when executed, the device will try to decrypt the already decrypted section and it's going to fail.
However, you can use tools like MachOView to change this info. Just open the binary and set the cryptid to 0:
You can use tools like frida-ios-dump to automatically remove the encryption and an app.
First, make sure that the configuration in Frida-ios-dump dump.py
is set to either localhost with port 2222 when using iproxy, or to the actual IP address and port of the device from which you want to dump the binary.
Now you can safely use the tool to enumerate the apps installed:
$ python dump.py -l
PID Name Identifier
---- --------------- -------------------------------------
860 Cydia com.saurik.Cydia
1130 Settings com.apple.Preferences
685 Mail com.apple.mobilemail
834 Telegram ph.telegra.Telegraph
- Stocks com.apple.stocks
...
and you can dump one of the listed binaries:
$ python3 dump.py -u "root" -p "<PASSWORD>" ph.telegra.Telegraph
Start the target app ph.telegra.Telegraph
Dumping Telegram to /var/folders/qw/gz47_8_n6xx1c_lwq7pq5k040000gn/T
[frida-ios-dump]: HockeySDK.framework has been loaded.
[frida-ios-dump]: Load Postbox.framework success.
[frida-ios-dump]: libswiftContacts.dylib has been dlopen.
...
start dump /private/var/containers/Bundle/Application/14002D30-B113-4FDF-BD25-1BF740383149/Telegram.app/Frameworks/libswiftsimd.dylib
libswiftsimd.dylib.fid: 100%|██████████| 343k/343k [00:00<00:00, 1.54MB/s]
start dump /private/var/containers/Bundle/Application/14002D30-B113-4FDF-BD25-1BF740383149/Telegram.app/Frameworks/libswiftCoreData.dylib
libswiftCoreData.dylib.fid: 100%|██████████| 82.5k/82.5k [00:00<00:00, 477kB/s]
5.m4a: 80.9MB [00:14, 5.85MB/s]
0.00B [00:00, ?B/s]Generating "Telegram.ipa"
After this, the Telegram.ipa
file will be created in your current directory. You can validate the success of the dump by removing the app and reinstalling it (e.g. using ios-deploy ios-deploy -b Telegram.ipa
). Note that this will only work on jailbroken devices, as otherwise the signature won't be valid.
In order to obtain the ipa file from an installed application you can also use the tool flexdecrypt or a wrapper of the tool called flexdump.
In any case you will need to install flexdecrypt in the device running something like:
wget https://github.com/JohnCoates/flexdecrypt/releases/download/1.1/flexdecrypt.deb
dpkg -i flexdecrypt.deb
rm flexdecrypt.deb
and in order to use flexdump:
apt install zip unzip
wget https://gist.githubusercontent.com/defparam/71d67ee738341559c35c684d659d40ac/raw/30c7612262f1faf7871ba8e32fbe29c0f3ef9e27/flexdump -P /usr/local/bin; chmod +x /usr/local/bin/flexdump
flexdump list #List apps
flexdump dump Twitter.app #Create .ipa file from app
r2flutch is a tool that uses radare and frida to decrypt and dump ios apps>
See the github for more information.
When you install an application without using Apple's App Store, this is called sideloading. There are various ways of sideloading which are described below. On the iOS device, the actual installation process is then handled by the installd daemon, which will unpack and install the application. To integrate app services or be installed on an iOS device, all applications must be signed with a certificate issued by Apple. This means that the application can be installed only after successful code signature verification. On a jailbroken phone, however, you can circumvent this security feature with AppSync, a package available in the Cydia store. It contains numerous useful applications that leverage jailbreak-provided root privileges to execute advanced functionality. AppSync is a tweak that patches installd, allowing the installation of fake-signed IPA packages.
Different methods exist for installing an IPA package onto an iOS device, which are described in detail below.
Please note that iTunes is no longer available in macOS Catalina. If you are using an older version of macOS, iTunes is still available but since iTunes 12.7 it is not possible to install apps.
Cydia Impactor was originally created to jailbreak iPhones, but has been rewritten to sign and install IPA packages to iOS devices via sideloading (and even APK files to Android devices). Cydia Impactor is available for Windows, macOS and Linux. A step by step guide and troubleshooting steps are available on yalujailbreak.net.
On Linux and also macOS, you can alternatively use libimobiledevice, a cross-platform software protocol library and a set of tools for native communication with iOS devices. This allows you to install apps over a USB connection by executing ideviceinstaller. The connection is implemented with the USB multiplexing daemon usbmuxd, which provides a TCP tunnel over USB.
The package for libimobiledevice will be available in your Linux package manager. On macOS you can install libimobiledevice via brew:
$ brew install libimobiledevice
$ brew install ideviceinstaller
After the installation you have several new command line tools available, such as ideviceinfo
, ideviceinstaller
or idevicedebug
.
# The following command will show detailed information about the iOS device connected via USB.
$ ideviceinfo
# The following command will install the IPA to your iOS device.
$ ideviceinstaller -i iGoat-Swift_v1.0-frida-codesigned.ipa
...
Install: Complete
# The following command will start the app in debug mode, by providing the bundle name. The bundle name can be found in the previous command after "Installing".
$ idevicedebug -d run OWASP.iGoat-Swift
The IPA can also be directly installed on the iOS device via the command line with ipainstaller. After copying the file over to the device, for example via scp, you can execute ipainstaller with the IPA's filename:
$ ipainstaller App_name.ipa
On macOS you can also use the ios-deploy tool to install iOS apps from the command line. You'll need to unzip your IPA since ios-deploy uses the app bundles to install apps.
$ unzip Name.ipa
$ ios-deploy --bundle 'Payload/Name.app' -W -d -v
After the app is installed on the iOS device, you can simply start it by adding the -m
flag which will directly start debugging without installing the app again.
$ ios-deploy --bundle 'Payload/Name.app' -W -d -v -m
It is also possible to use the Xcode IDE to install iOS apps by doing the following steps:
- Start Xcode
- Select Window/Devices and Simulators
- Select the connected iOS device and click on the + sign in Installed Apps.
Sometimes an application can require to be used on an iPad device. If you only have iPhone or iPod touch devices then you can force the application to accept to be installed and used on these kinds of devices. You can do this by changing the value of the property UIDeviceFamily to the value 1 in the Info.plist file.
<?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>UIDeviceFamily</key>
<array>
<integer>1</integer>
</array>
</dict>
</plist>
It is important to note that changing this value will break the original signature of the IPA file so you need to re-sign the IPA, after the update, in order to install it on a device on which the signature validation has not been disabled.
This bypass might not work if the application requires capabilities that are specific to modern iPads while your iPhone or iPod is a bit older.
Possible values for the property UIDeviceFamily can be found in the Apple Developer documentation.
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks repo and hacktricks-cloud repo.