Early July 2012, I reported to Apple numerous vulnerabilities related to their App Store iOS app. Last week Apple finally issued a fix for it and turned on HTTPS for the App Store. I am really happy that my spare-time work pushed Apple to finally enabled HTTPS to protect users. This post discuss the vulnerabilities I found. As a bonus, I made several video demos of the attacks described in this post so you can see by yourself how dangerous not having full HTTPS is.
The Apple App Store and associated applications, such as the Newsstand, are native applications provided by default with iOS to access/purchase content from the Apple App Store.
The following attacks are carried out by an active network attack that is able to read, intercept and manipulate non-encrypted (HTTP) network traffic. Hence those attacks can be carried on any public Wifi networks including airport or coffee-shops networks. Being on the same networks as the victims is all it takes.
By abusing the lack of encryption (HTTPS) in certain parts of the communication with the App Store, the dynamic nature of the App Store pages, and the lack of confirmation, an active network attacker can perform the following attacks:
- Password stealing: Trick the user into disclosing his or her password by using the application update notification mechanism to insert a fake prompt when the App Store is launched.
- App swapping: Force the user to install/buy the attacker’s app of choice instead of the one the user intended to install/buy. It is possible to swap a free app with a paid app.
- App fake upgrade: Trick the user into installing/buying the attacker’s app of choice by inserting fake app upgrades, or manipulating existing app upgrades.
- Preventing application installation: Prevent the user from installing/upgrading applications either by stripping the app out of the market or tricking the app into believing it is already installed.
- Privacy leak: The App Store application update mechanism discloses in the clear the list of the applications installed on the device.
The prompt injection and password stealing is performed by injecting the following code into the update page (http://ax.su.itunes.apple.com/WebObjects/MZSoftwareUpdate.woa/wa/viewSoftwareUpdates)
Note that the App Store uses a templating system so it is probably possible (albeit not tested) to add the App Store username by using the @@username@@ variable into the code.
The attacker and the victim are on the same network (e.g., the airport). The attacker performs a man-in-the-middle attack to intercept the traffic between the App Store app and the iTunes backend.
Abusing the lack of encryption on the application detail pages, the attacker is able to swap application purchase/download parameters with the those of his choice. As a result, the attacker is able to force the victim to install/buy an app of his choice when the victim tries to install/upgrade any application.
The attacker would be able to monetize this attack by having his own (benign) very expensive application available through the market and forcing the user to install it using the app swapping attack.
When the user clicks on a given application “page”, the App Store sends a request in clear of the following form: (http://itunes.apple.com/us/app/captain-antarctica/id512922449?mt=8)
Where idxxxxxxxx is the application ID. Following this request the server returns in the clear a page that contains the app details/rating … In particular this page contains the “buy/install application” button which is encoded as an HTML div that looks like this:
<div class="button-bar"> <div confirm-text="BUY APP" action-params="productType=C&price=990&salableAdamId=512922449&pricingParameters=STDQ&appExtVrsId=7196225" item-title="Captain Antarctica" artist-name="FDG Entertainment" item-id="512922449" item-type="software" artwork-url="http://a1.mzstatic.com/us/r1000/086/Purple/v4/0c/7f/9f/0c7f9f4a-fdcd-e6ab-0403-7a542f42efb4/mza_5538029909718374393.114x114-75.jpg" bundle-id="com.FDGEntertainment.CaptainAntarctica" icon-is-prerendered="true" required-capabilities="armv7 " minimum-os-version="4.2" versionID="7196225" file-size="43895924" class="buy">
To perform the swapping, the attacker intercepts all the application pages’ requests and replaces the content of the buy Div with the values that correspond to the app he wants the user to install.
In particular, to be successful the attacker needs to replace the following parameters of the action-params attribute:
- AdamId (application id) with the value of the application id that the attacker wants to install.
- appExtVrsId (application version) with the value of the application version that the attacker want to install.
- price with the price of the app.
The following DIV attributes need to be replaced as well:
- item-id with the application id that the attacker wants to install.
- versionID with the application version of the application that the attacker wants to install.
- file-size with the size of the application that the attacker wants to install.
- item-bundle with the name of the bundle of the application that the attacker wants to install.
Failing to replace any of these parameters results in the swapping being unsuccessful: either the download does not work or the app is not installed once the download is completed.
It is important to note here that there is no buying confirmation prompt which could have mitigated this attack. Regardless of whether the application is free or not, the only confirmation dialog that might pop-up is the one that asks for a password if the user hasn’t authenticated for a long time. There is no indication of which app is downloaded/purchased.
Recall here that it is trivial to launch the AppStore application using a specific protocol handler from any html page (which are also subject to man in the middle attack).
Finally, it is interesting to note that the attribute artwork-url controls the icon that is displayed during the download/installation process. Accordingly, by leaving it unchanged the victim will not know that the app is being swapped until the installation is completed.
App fake upgrade
The scenario is almost identical to the one described in the app swapping case. The only difference is that the user is nudged into installing the app by inserting a fake upgrade.
Similarly to the application information page, the upgrade page: http://ax.su.itunes.apple.com/WebObjects/MZSoftwareUpdate.woa/wa/viewSoftwareUpdates is sent in clear and contains the upgrade button in form of HTML content that can be rewritten by the attacker.
To inject a fake upgrade, the attacker simply needs to add extra HTML content that replicates what a real upgrade contains with the value of his choice.
The only subtlety is to change the number of available updates available in the notification button. This is done by rewriting the special HTML attribute update-count present in the body tag to match the number of fake upgrade injected:
<body update-count="42" cn-cookie-name="mz_at1" data-country="usa" disable-personalized-purchase-check="true" disable-personalized-install-check="true" class="usa application room software-updates">
Preventing application installation
Simply rewrite the buying button or replacing the app ID / version with one for an app already installed to prevent the user from installing the app.
When contacting the upgrade server, the device sends in the clear a PList that contains all the applications installed on the phone. This is a privacy leak as it allows an attacker to know which bank/doctor/services the user uses.
It can also allow an attacker to track users, as a list of installed applications is pretty unique to each user (it seems likely that it will generate more than the 31 bits of entropy needed to uniquely identify a user.)
Here is an Example of the PLIST leaked when contacting the following url: http://ax.su.itunes.apple.com/WebObjects/MZSoftwareUpdate.woa/wa/viewSoftwareUpdates
<?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>dsids</key> <string>273145163;143441</string> <key>local-software</key> <array> <dict> <key>adam-id</key> <integer>289316916</integer> <key>installed-version-identifier</key> <integer>3004080</integer> </dict> <dict> <key>adam-id</key> <integer>284035177</integer> <key>installed-version-identifier</key> <integer>7074860</integer> </dict> <dict> <key>adam-id</key> <integer>284910350</integer> <key>installed-version-identifier</key> <integer>6844249</integer> </dict>
I decided to render those attacks public, in the hope that it will lead more developpers (in particular mobile ones) to enable HTTPS. Enabling HTTPS and ensuring certificates validity is the most important thing you can do to secure your app communication. Please don’t let your users down and do the right thing: use HTTPS !