Common vuls in Mobile Apps

Introduction

During the time doing mobile pentest, I've realized that developers are often implementing an insecure code which makes an application exposed to security risks. By abusing those ones, it opens up an opportunity for an a bad guy to steal users' credentials or users' personal data by just getting into the phone, rooting them (or NOT) , and start being a cockeyed at your data.

Of course, in some cases, there is no need to be a rooted phone!

They are so many times I've seen these type of vuls in any apps during my mobile pen testing (especially in Android) as such, saving password without encryption, expose users credentials, data to logcat, or just storing users credentials (keystore,..) in /shared_prefs/ directory and so on. Therefore, in this article I'll be listing and explaining the common vuls/mistakes that developers are often suffer:

1.Storing users' credentials in plain text

The most common security concern for an application on Android is whether the data that you save on the device is accessible to other apps. There are three fundamental ways to save data on the device:

  • Internal storage.

  • External storage.

  • Content providers.

The following paragraphs describe the security issues associated with each approach.

Use internal storage

By default, files that you create on internal storage are accessible only to your app. Android implements this protection, and it's sufficient for most applications.

Generally, avoid the MODE_WORLD_WRITEABLE or MODE_WORLD_READABLE modes for IPC files because they do not provide the ability to limit data access to particular applications, nor do they provide any control of data format. If you want to share your data with other app processes, instead consider using a content provider, which offers read and write permissions to other apps and can make dynamic permission grants on a case-by-case basis.

To provide additional protection for sensitive data, you can encrypt local files using a key that is not directly accessible to the application. For example, you can place a key in a KeyStore and protect it with a user password that is not stored on the device. While this does not protect data from a root compromise that can monitor the user inputting the password, it can provide protection for a lost device without file system encryption.

Many apps that do not encrypt the users data before writing into the file whereas it's placed in the internal storage. For an instance:

The user's password is stored in plain-text.

Many people think that the attackers have no ways to exploit and read this type of critical data due to the Android sandbox and moreover the phone is hard to be rooted. They could be wrong ?!. Except the root case, I've found out another sneaky trick that allow me to achieve this data without rooting the device by just using backup.

Case 1:

If the app is debug-able you could do:

$ adb shell
$ run-as <app-package-id>
$ cat /data/data/<app-package-id>/shared_prefs/prefs.xml

Run grep " 1 /" /data/system/packages.list to list all debug-able apps

Case 2:

Otherwise....

$ adb backup -f ~/data.ab -noapk com.bplus.vtpay

or

adb backup "-noapk com.innogames.enterprise.elvenar"

$ java -jar abe.jar unpack ~/data.ab vtpay.tar "" (abe)

$ apps/com.bplus.vtpay/sp/vtp_shared_user_info.xml

Use external storage

Files created on external storage, such as SD cards, are globally readable and writable. Because external storage can be removed by the user and also modified by any application, don't store sensitive information using external storage.

You should Perform input validation when handling data from external storage as you would with data from any untrusted source. You should not store executables or class files on external storage prior to dynamic loading. If your app does retrieve executable files from external storage, the files should be signed and cryptographically verified prior to dynamic loading.

Use content providers

Content providers offer a structured storage mechanism that can be limited to your own application or exported to allow access by other applications. If you do not intend to provide other applications with access to your ContentProvider, mark them as android:exported=false in the application manifest. Otherwise, set the android:exported attribute to true to allow other apps to access the stored data.

When creating a ContentProvider that is exported for use by other applications, you can specify a single permissionfor reading and writing, or you can specify distinct permissions for reading and writing. You should limit your permissions to those required to accomplish the task at hand. Keep in mind that it’s usually easier to add permissions later to expose new functionality than it is to take them away and impact existing users.

If you are using a content provider for sharing data between only your own apps, it is preferable to use theandroid:protectionLevel attribute set to signature protection. Signature permissions do not require user confirmation, so they provide a better user experience and more controlled access to the content provider data when the apps accessing the data are signed with the same key.

Content providers can also provide more granular access by declaring the android:grantUriPermissions attribute and using the FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION flags in the Intentobject that activates the component. The scope of these permissions can be further limited by the <grant-uri-permission> element.

When accessing a content provider, use parameterized query methods such as query(), update(), and delete() to avoid potential SQL injection from untrusted sources. Note that using parameterized methods is not sufficient if the selection argument is built by concatenating user data prior to submitting it to the method.

Don't have a false sense of security about the write permission. The write permission allows SQL statements that make it possible for some data to be confirmed using creative WHERE clauses and parsing the results. For example, an attacker might probe for the presence of a specific phone number in a call log by modifying a row only if that phone number already exists. If the content provider data has predictable structure, the write permission may be equivalent to providing both reading and writing.

2. Print users' credentials to logcat

Android applications may leak sensitive information either inherently or as a result of harmful influence. When this happens, it's called an Information disclosure vulnerability. This recipe talks about how to check an application for potential leaks of sensitive information by inspecting the Android logcat, which is used by the application developers as a debugging tool. We will also talk about how you can take advantage of one of Android's built-in benchmarking tools to help make logcat inspection a little more rewarding.

With this type of security weakness, the attackers do not need to perform "rooting device" as long as the USB Debugging to be enabled on victims Android device.

For simple & efficient way to trace the log, we will use trivial adb command without installing any 3rd party such as pidcat or so.

adb shell ps -A | grep "<name of the application"

adb logcat | grep "<PID>"

The results are shown as

User personals information are shown in log
User password is traced in plain-text through log

3. Allow rooted devices

I really do not want to talk about this because it's already so obvious by itself. Allowing rooted device to install and experience your application, IMHO it does not help your app rating or its popularity get higher. It just reduces your app reputation and apparently takes your resources by solving those ridiculous security issues like "why am I losing my money?, why my password got stolen?". This is not worthy at all, or the worse case is that some users trying to exploit in order to get their own personal benefits from your app, later on their account gets crashed or something. So what?!, your team does not ever know what's happening and start speeding time, money for a research "why"?.

Therefore, first of all please make a warning banner pops up if your application detects a rooted device like

Your phone is rooted, we are not responsible for .....

Or better case:

You're not allowed to install this app due to your device is rooted!!!!

4. Server Side Controls (weak)

For those who are non-techie, it is imperative to know whatever communication happens between the app and the user outside is through a server. As a result, hackers target the server on a primary basis. So what can be done is, ensure server-side security. Whether you wish to hire a specialized security expert in-house or make use of a manual test or testing tool or think of considering general precautions.

I have to admit that this is a large topic that's why I've made a separated article for it. With my humble experience in pen test. I'd like to divide it into 02 different cases (you might be in one of them).

Case 01: The application interacts with the server constantly

This common case happens in none-game apps because the users related data is minor, thus the requests are always made every single time the functions are called. I hope that you've already known what is "data validation" in security point of view. Yes, what I want to talk to is tampering data requests, indeed it happens in both Request & Response, GET or POST. If you are confused what this is, just wandering around google that could be helpful to know.

The tampering data requests happens when the server side does not re-verifies the input when propagated to end users (Reponse). And, the server side does not re-verifies the data between user input and server when propagated to end server (Request).

Attackers tamper the request and change the actual value to an arbitrary value

Case 02: The application data is loaded at first time when created.

This often happens in gaming apps more than other apps due to the huge data have to be propagated to the users as such gold, points, time to build, and other number values that makes the game run. Thus, talking with the server constantly in the real time is painful. Developer always choose to load all of these values once at the first time the application created.

Similarly to the case 01, attackers just need to tamper the data (RESPONSE) that are propagated by the servers to the end users and change them to whatever they want. For an example:

The players will get 500 Gold for first time play, the server will response with value {Gold: 500} to the clients. The attackers are able to replace this value to an arbitrary amount they want.

{Gold: 500} replace to {Gold: 700}, at here the players will get 700 gold instead of 500 for first time the character created.

Match and Replace function help to change the response parameters

5. Lack of Binary Protections

This one is for those who are techies. In case of absence of binary protection, you can reverse engineer the code of app to inject malware or redistribute the pirated application possibly with a threat. One of the significant concerns in mobile app security is that it can result in confidential data theft, brand and trust damage, frauds, revenue losses, etc.

Use binary hardening techniques where files can be easily analyzed and modified to protect against common exploits. As a result, the vulnerability can be fixed in the legacy code itself without the need for source code. Along with this, secure coding techniques for jailbreak detection controls, checksum controls, certificate pinning controls, and debugger detection controls.

6. Poor Authorization

Unfortunately, mobile internet connections are not as reliable as web connections. This means they might require offline authentication to maintain the uptime. Moreover, it might end up creating security loopholes that must be taken into consideration by developers.

So what can be done is- make use of an adversary that can brute force through the security logins in the offline mode and make operations on the app easier. Besides, you can even limit login only in the online mode; this will prevent operation on sensitive information. In case, if there is a specific business requirement to allow for offline authentication, then you can encrypt the app data that can be opened only with specific operations.

7. Improper Session Handling

In a layman’s language, the continuance of the previous session for a long period even if the end user has switched from the app is what improper session handling is all about. This practice can be dangerous especially if the phone is stolen. The person who gains access to this device can undertake control over the application and steal or manipulate important data.

So how to find a mid-way between speed and privacy protection? Again, use re-authentication for important actions like purchases or access to priority marked documents. Amazon mobile app is the best example of this issue.

8. Broken Cryptography

Mainly arises due to bad encryption or incorrect implementation; Broken cryptography allows hackers to decrypt the sensitive data to its original form and manipulate or steal it as per his/her convenience. Try using superior encryption protocols and proper implementation process to avoid any mistakes and perform encryption properly.

Refs

https://www.hostreview.com/blog/190422-tips-for-better-mobile-app-security

https://developer.android.com/training/articles/security-tips