How to install IPA on an iOS device14 Nov 2019
During a recent pentest, I needed to test an iOS app. Since the app was not in the App Store yet, it was given to me in the form of an .ipa file. I had to figure out a way to load it to my test iPhone. Apparently, there are several instructions on the Internet on how to do that, but I couldn’t find the one that worked for me out of the box, so here is my own…
- An iOS app distributed as an IPA file.
- Non-jailbroken iPhone. In addition, the device has been enterprise provisioned and had all the “niceties” such as MDM.
- A Linux computer.
First, let’s take a look at the IPA file:
$ file FairyTailes.ipa FairyTailes.ipa: iOS App Zip archive data, at least v1.0 to extract
Hey, it looks like a zip… so let’s just unzip it!
$ unzip FairyTailes.ipa
This will create a subdirectory
Payload with all the app’s content in it. Open the app’s plist file
Payload/FairyTailes.app/Info.plist, search for
CFBundleVersion, and note their values:
In the directory where the IPA file is located, start an HTTP server:
$ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...
If you haven’t already, go ahead and get a free ngrok account (tip: ngrok is an amazing tool!) After you download and set up ngrok, expose your HTTP server to the Internet:
$ ngrok http 8000
In ngrok’s output, note the HTTPS forwarding address that looks something like
In the same directory where the IPA file is located, create a file called
download.html with the following content (of course, use your actual ngrok address, and make sure it’s the HTTPS one):
<html><body> <h1><a href="itms-services://?action=download-manifest&url=https://4c265f53.ngrok.io/FairyTailes.plist"> Download the app </a></h1> </body></html>
In the same directory, create
FairyTailes.plist and use the identifier and version values you obtained from
Info.plist earlier. Of course, also use the actual ngrok address.
<?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>items</key> <array> <dict> <key>assets</key> <array> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <string>https://4c265f53.ngrok.io/FairyTales.ipa</string> </dict> </array> <key>metadata</key> <dict> <key>bundle-identifier</key> <string>com.grimm.fairytales</string> <key>bundle-version</key> <string>1863</string> <key>kind</key> <string>software</string> <key>title</key> <string>Fairy Tales</string> </dict> </dict> </array> </dict> </plist>
On your iOS device, go to https://4c265f53.ngrok.io/download.html (make sure it’s HTTPS, and do I need to say again you must use the actual ngrok address?) and click the Download link. Confirm the prompt to install the app. It should silently install and appear on your home screen, so go ahead to the home screen and click on your new shiny app.
Oh no, you get an error Untrusted Enterprise Developer, don’t you? Don’t worry, this is easy to fix:
- Open the Settings app.
- Go to General -> Device Management and click on the name of the app’s developer (in my case it was “Brothers Grimm”).
- Click Trust “Brothers Grimm” and confirm the prompt.
Go back to the home screen and try to launch the app again - it should work now!!!
Bonus: proxy the app traffic through Burp
Assuming the machine where you run Burp Suite and your iOS device are on the same network: