Following this week’s hype of HTTP Request Hijacking presented at RSA Europe 2013, I began experimenting with iOS apps that use HTTP instead of HTTPS. In this post I will summarize the presented attack vector and focus on the iOS Stocks App.
Summary of HTTP Request Hijacking
HTTP Request Hijacking should only work on apps that don’t use SSL and cache 301 Moved Permanently HTTP responses; apps using SSL that enforce valid certificates should not be vulnerable. HTTP Request Hijack requires a man-in-the-middle position, i.g. you connect to my wireless access point or a malicious, often “free wifi”, network. Then when an HTTP GET request is sent from the mobile app, the response is attacker manipulated to be a 301 redirect to the attacker’s malicious site. Now the app will always go there, if it cached the redirect, and the malicious attackers web server would host whatever they wanted the app to show. From an end user perspective, you would see attacker manipulated data on your app and not know why. I decided to look into this and see exactly what can be done.
iOS Stocks App
The iOS Stocks App is an app that uses only HTTP (no SSL). What is the worst that can happen? Show an end user fake data? I tried this and was able to modify the stock prices as they were displayed on the iOS App. Here is an example of Facebook loosing 40 points or 80% of it’s value today (obviously it did not):
How the iOS Stocks App Works
To understand how the iOS Stocks App works you have to capture the traffic. I did this by pointing my iOS device to an HTTP proxy running on my laptop (I used OWASP ZAP). This is the request the app sends to update stock prices:
POST http://iphone-wu.apple.com/dgw?imei=7FA848CF-8A32-487C-9D65-6D74EA8DF2DC&apptype=finance HTTP/1.1
User-Agent: Apple iPhone v6.1.3 Stocks v3.0.10B329
<?xml version=”1.0″ encoding=”utf-8″?><request devtype=”Apple iPhone v6.1.3″ deployver=”Apple iPhone v6.1.3″ app=”YGoiPhoneClient” appver=”188.8.131.52B329″ api=”finance” apiver=”1.0.1″ acknotification=”0000″><query id=”13″ timestamp=”0″ type=”getquotes”><list><symbol>FB</symbol></list><parts>symbol,open,high,low,volume,averagedailyvolume,peratio,yearrange,dividendyield,link</parts></query></request>
As you can see, the app sends a POST request with the victim’s unique IMEI number and the symbol it is looking to update in the payload. Since the traffic is being sent in clear text through HTTP, anyone sitting in the middle can modify the response. Establishing the man in the middle position can be performed in multiple ways and is out of scope of this post.
Changing Stock Prices
I modified the request to be as follows:
HTTP/1.1 200 OK
Date: Fri, 01 Nov 2013 19:07:02 GMT
<?xml version=”1.0″ encoding=”UTF-8″?><response><result type=”getquotes” timestamp=”1383332770″><list count=”1″ total=”1″><quote><symbol>FB</symbol><price>9.900002</price><change>-40.305000</change><marketcap>21.52B</marketcap><status>1</status><realtimets>1383332762</realtimets><realtimeprice>9.900002</realtimeprice><realtimechange>-40.305000</realtimechange></quote></list></result></response>
This modification results in the app providing false information to the end user:
IMEI in POST Request
Not only does the iOS Stocks App send and receive data over HTTP instead of HTTPS but it also sends the end user’s unique IMEI number in the post request. Therefore, anyone capturing traffic can know what stocks are being watched by a particular user and Apple knows what stocks any unique use is requesting. Now why would Apple want to know what stocks you follow?
Not Vulnerable to HTTP Request Hijacking
I also attempted to send a 301 Permanently Moved response to the app to see if it would request this information from another web server. This was not possible as it seems the POST requests are hard coded to go to the Apple URL: http://iphone-wu.apple.com/
Apple should use HTTPS for the stocks app and stop sending the end user’s IMEI number in the URL