Photo by Oliver Quinlan
Last week we started talking about application security assessment — a vital aspect of mobile app development process. Our previous post covered the topic of iOS penetration testing any developer could — and should — perform if the iOS application he or she works on deals with confidential information, i.e. credit card numbers, account credentials, etc. Today we'll continue talking about mobile app security testing and focus on protecting user’s data.
Data security milestones
When analysing security of a mobile app, developers perform three major checks: client-side, server-side and the protocols by which data is transferred between them. These tasks could be further split into smaller ones:
- to check how information is sent via the Internet
- to check the Privacy settings
- to check how data is stored
- to evaluate security by simulating an external attack (pentesting)
Let's take a closer look.
Web traffic analysis
iOS apps use different ways to exchange or transfer data:
- Unencrypted protocols, like HTTP.
What to check: whether these protocols are used to transfer confidential data.
- Secure protocols, like HTTPS.
What to check: are SSL certificates validated? Does the app accept any SSL certificates?
- Non-standard protocols and low-level data transfer protocols.
Here we check if the app accesses any users data without asking.
During the standard app installation on an iOS device, the system creates a folder with a unique ID in /var/mobile/Applications. Typical folder structure inside a root folder of an application looks the following:
Here we should pay attention to:
- Plist files — What's the content? Are there any hidden options?
- Keychain — What is stored? Are all passwords securely encrypted?
- Cache — What's cached?
- Logs — Are the processes logged? Does any confidential data fall into logging?
A penetration test is a powerful tool that involves exploitation of the app’s potential vulnerabilities and helps to estimate the app's chances to stand against a real malicious attack. We strongly recommend that you do pentesting if your application works with bank cards or other confidential information. For some of types of apps, such as mobile payment apps, this test is a must. If you are new to the field, refer to our penetration test tutorial.
Case study: ‘Pay With a Card’ app security audit
For demonstration purposes, we’ll take a real app that is commonly used here in Russia, and perform a security audit. The app is called ‘Pay With a Card’ - it’s a mobile top-up app that allows users to make payments to their wireless carrier MegaPhone.
AppStore description: No time to pay for your mobile phone? Now you can do it fast and easy — with your smartphone. No queues*. No hidden fees! Just download this app and you could make payments to MegaPhone with a VISA or MasterCard card.
* Yes, in Russia when you’re paying for your wireless phone you might occasionally get into a queue and wait for a while.
Additional information: We'll use the MegaPhone Service Guide credentials as a login/password pair. The service address depends on a particular region, example for Novosibirsk region.
The testing device: iPhone 3G.
MegaPhone Service Guide is the system that allows customers of this wireless carrier to manage their MegaPhone accounts: to change tariffs, add and remove extra options, request reports for particular services like calls and SMS, spend bonus points, etc.
Consequently, the main security question is:
- How does the app ensure safety for users confidential account data? How can the app resist an unauthorized access to Service Guide?
- Where are the bank card numbers stored? Is this information encrypted?
- Is it possible to make an unauthorized payment with a card registered in this app?
Application traffic analysis
All's clean here. No unencrypted protocols are used to transfer secure data.
All's clean here as well. All certificates are verified.
I couldn't install PortSwiggerCA.crt on the device — the device rebooted each time I tried. That's why I've connected not via proxy but directly.
Channels to transfer bank card number
Since the device doesn't support multitasking, I couldn't check the channels for bank card data transmission. For this mission I had to login without proxy and simultaneously to check the send data with proxy.
Clean again. I haven't found any unauthorized access to users data.
The data storage analysis revealed several weaknesses the app’s users should be informed about:
- Security at risk! In the process of authorizing, an authData.xml file is created in the Documents folder, where the login/password pair to the service lies unencrypted.
- Security at risk! After restart the app logs in automatically.
- Security at risk! When the app is closed, the authData.xml file with unencrypted passwords still remains in the Document folder. The file is not deleted even if a user signs out of the account.
The above said happens because the ‘Remember the password’ option is on by default. If you press Exit, turn off the ‘Remember’ option and close the app, the app will still log in automatically after restart.
Probably, the ‘Remember’ option doesn't save data if the ‘Enter’ button has not been pressed.
When a malicious user tries to log in with wrong credentials, the app would show an error message. However, the hacker could simply restart the application and it will authorise the user automatically.
Good news: if you turn the ‘Remember’ option off at the beginning of authorization, the authData.xml file wouldn't be created.
Bank card data
The app rejected an old card and displayed an error message, saying that the card has expired. When I tried to send a bogus data with wrong expiry date, the app showed an error message, that the bank couldn't make the test purchase.
When I finally entered a valid card data, a confirmation screen appeared. There I had to enter the sum for a test payment. During that step I didn't know if the app had remembered the card data or not. Presumably, this data is stored on a remote server. Let's check this hypothesis with tcpdump.
Important! Add "-s o" to use the Follow TCP Stream Wireshark option (press Ctr + C to stop recording). This will also ensure that the packages aren’t cut.
iPhone-Viktor-Kotov:~ root# tcpdump -w /FILENAME.pcap -s 0 tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 68 bytes ^C1506 packets captured 1509 packets received by filter 0 packets dropped by kernel iPhone-Viktor-Kotov:~ root#
So, nothing criminal has been revealed: only the queries to ispay.megafon.ru/ via HTTPS.
Unfortunately, as we have just figured out the app under focus isn't secure enough. Any malicious user can access account data quite easily. The acquired login and password will allow hackers to change the profile parameters, like tariff and services for the wireless carrier and get access to confidential information like calls made and SMS messages sent.
Our verdict: We wouldn’t recommend this app to users. We would strongly encourage the developers of this app to pay more attention to security practices and make sure they don’t put MegaPhone users’ data at risk.