Another client side: mobile app security through the eyes of an attacker

Man

Professional
Messages
3,070
Reaction score
604
Points
113
cd5325d53e330f6ebbb26a1a9d7f04b9.jpg


Hello! Today I want to talk about the security of mobile applications from the attacker's side.

Mobile applications actively use data, which means they need proper protection. Therefore, over the past few years, the number of projects related to the analysis of their security has grown significantly. The interest of companies in the security of mobile applications can also be seen in the bug bounty market. For example, on BI.ZONE Bug Bounty, mobile applications are included in 19 public programs.

Let's take a closer look at what vulnerabilities are found in mobile applications

This text is based on my speech at VolgaCTF.

Example of vulnerability​

Further we will talk specifically about Android, since it is more accessible for security research.

Client-side vulnerabilities are less critical than server-side ones, since they affect a specific user, not a service. But there is one key feature that makes vulnerabilities in mobile clients a tasty morsel for attackers. Unlike web applications, they directly interact with the device's operating system, which means they have much more capabilities.

Mobile applications can interact directly:
  • with the device's file system,
  • OS via system calls,
  • sh shell,
  • camera, microphone, gyroscope and other peripheral devices,
  • other applications on the device.

Let's experiment and see what we can do on the device using RCE. To emulate the presence of RCE on the device, I used AndroRAT and the Android Studio device emulator.

The capabilities of Interpreter AndroRAT out of the box are already amazing.

460c8e92ed7ed5266d6aa754c20e18bd.png


With RCE on the device we get access to the following data:
  • Information about the device.
    0181db9124d45e07b8574d096b73a4cf.png
  • Information about the IP and MAC address of the device.
    a1e517a7d977efe0aa55ac08fd2b4332.png
  • Camera (due to the emulator's features, it was not possible to connect to it).
  • History of messages, incoming and outgoing calls.
    f46e03c9a55237b4f1c94ebbe52cc25d.png
  • Device location.
    9d0067a4b208701d87a450fbe74a8563.png
  • Information about the SIM card and provider.
    7997d5a3331065de9e70dd0cd14687da.png
  • Microphone.
    594db4e43457749e0c76e1794af4a2e8.png
  • Clipboard.
    6d44cfc5542077b3f1e8dbae853846a3.png

Often, applications have access to the SD card, where many interesting things can be stored: from application cache to user photos.

d4ece786b8465dd4975a7a53d02dbed7.png


There is nothing stopping an attacker from uploading their own utilities and then using them for post-exploitation and persistence. For demonstration purposes, I compiled and uploaded my own version of the URL, and used it to access the resource from the internal network.

75816e2726b920ba27d4f2217b94b09c.png


In the same way, an attacker can compile and download to the device:
  • utilities for reconnaissance and network scanning,
  • utilities for proxying traffic through the device,
  • Malware: miners, botnet backends, etc.

Not every RCE will give you so many options. It all depends on the flexible mechanism of setting permission in Android or specifying property in iOS. Thanks to this, you can specify what the application should have access to and what it should not.

With a strict policy, you can reduce the impact of RCE to approximately zero, limiting the application's access as much as possible, up to interaction over the network. But in this case, the application will be cut down in functions, which is not always convenient.

For example, the Habra app on Android doesn’t request that many permissions.

d99f1101420bb1a9ff7436b1b00370a9.png


When a theoretical RCE is detected, the maximum we can do is write and execute arbitrary files in the application directory (regardless of permissions), and interact with the device network. That's all.

But if you look at how many permissions a given Telegram requests, one screenshot won’t be enough to fit everything.

100679b85aec50a595a46aaf3e7a4200.png


And Telegram is no exception. According to statistics from Cybernews, it is easy to see that 3 out of 4 applications request access to external data storage, and every third one requests access to the microphone and camera. Applications often request rights that they do not need. This is due to the fact that some developers ask to give extended rights to the application by default. So the exception is rather the Habra application with a relatively small set of rights.

The impact of vulnerabilities does exist, but it depends on the type of vulnerability, as well as the permissions set for the application. But on average, the criticality in mobile applications will be higher than that of client-side vulnerabilities in web applications.

Vulnerability classification​

There are several opinions on how to classify vulnerabilities in mobile applications. Let's consider these.

By the vector of exploitation
0ac2c682311eab2b08b22bcc6998b3be.png

  • 0-click. To exploit the vulnerability, no action is required from the user, be it any interaction or installation of additional applications. It is enough to send the user a message with a payload, which will be processed by the application without additional interaction from the person.
    01f269b14d5027a3086c98637d05021a.png
  • 1-click. To operate, the user must perform one action: follow a link, open an attachment, etc.
    db4061d13eacc55028420eb234028034.png
  • Malware app: Exploitation requires the user to install a malicious application that exploits an interprocess communication vulnerability in another application.
    39d547abaeb87ad9ed5ad09efbffef07.png
  • MITM: To be exploited, the attacker must have implemented a man-in-the-middle attack and be able to control network traffic.
    fa5461f758a19b7a1bf7957ad81385d7.png
  • Physical access: Physical access to the device is required to exploit the vulnerability.

The first three types have a real vector for mass exploitation, so they can be considered the most critical. For such vulnerabilities, in most cases, you can get a bounty in bug bounty programs that have mobile applications.

The last two, while seemingly harmless, can still pose serious risks. No one wants to see a notice about a charge on their bank account after briefly leaving their phone in the office kitchen or connecting to public Wi-Fi.

Injections
An injection is a vulnerability in which an attacker introduces malicious data into an application to change its behavior, bypass protection, or execute unwanted commands.

Unlike web applications, where CSS, HTML and JS can be embedded in the client-side, here the list is much wider.

380248881586b9b6ceb3309f84aa1373.png
08104fb71f061c88faef726695522fe9.png


In some places the mobile application uses WebView, which is essentially an internal browser, so we can find the same client-side vulnerabilities in it as in the web application.

To allow XSS, it is enough to enable javascript support in WebView. In my experience, it is enabled in 99 cases out of 100. When was the last time you saw a web page without JS?
Code:
 webView.getSettings().setJavaScriptEnabled(true);

It's not enough to just escape user input: it's just like a web app.

One of the interesting features: in some cases, developers can implement a javascript interface that will allow calling java code from javascript and thus get the ability to interact with the OS.

So, you can write a simple interface where the getDeviceInfo and getBatteryLevel functions will be implemented:
Code:
 public class WebAppInterface { private Context mContext;
private LocationManager locationManager; private LocationListener locationListener;
public WebAppInterface(Context context) { mContext = context;
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
}
@JavascriptInterface
public String getDeviceInfo() {
return "Device: " + Build.MODEL + ", OS Version: " + Build.VERSION.RELEASE;
}
@JavascriptInterface
public String getBatteryLevel() {
BatteryManager batteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
int batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
return "Battery Level: " + batteryLevel + "%";
}

Then connect it to WebView:
Code:
 webView.addJavascriptInterface(new WebAppInterface(this), "os");

In this case we will be able to use these functions from javascript, which is especially interesting when there is XSS.

fe3d3310f01e7619f34df1574797dc96.png
bd7919b338eaa753639853e6a77f1a76.png


Any code implemented by the developer, which may also contain vulnerabilities, can be executed in this way.

8c556a0e87cdccd725249364275ebae6.png


SQLi
Mobile applications may be vulnerable to SQL injections due to the use of SQLite for data storage and improper filtering of user input.

Example of vulnerable code:
Code:
 public void search(View view) { 
 EditText srchtxt = (EditText) findViewById(R.id.ivi1search); 
 try { 
 Cursor cr = this.mDB.rawQuery("SELECT * FROM sqliuser WHERE user
= '" + srchtxt.getText().toString() + "'", null);

The impact of SQLi is significantly less than that of a server-side vulnerability, but it can still be noticeable.

b1eb22884f2513d2e13a44dbcf3bb6c3.png

This injection can be used to steal user personal data, spoof data, bypass local verification, or cause denial of service to the application client by corrupting or deleting data.

8c66502a03ddb792f85ea94c3582789e.png


Path traversal
The application interacts directly with the device's file system, so path traversal allows reading and rewriting arbitrary files that the application has permission to access.

4152e44cc6db71ca5a54e3187bb43e7a.png

By default, a regular user cannot view the contents of the application directory and, as a result, access the data stored there without root rights. So, if we have found path traversal, which allows reading any files on behalf of the application, this is already a fairly serious vulnerability.

Example of vulnerable code:
Code:
 public String readFileContent(String fileName) throws IOException { 
String BASEDIR = getFilesDir().getAbsolutePath(); 
File file = new File(BASEDIR + "/notes/"+ fileName); 
StringBuilder content = new StringBuilder(); 
 
try (BufferedReader reader = new BufferedReader(new
FileReader(file))) { 
String line; 
while ((line = reader.readLine()) != null) { 
content.append(line).append(System.lineSeparator());
} 
} 
return content.toString().trim(); 
}

However, the criticality increases significantly if it is path traversal when writing a file, as it can directly lead to RCE on the device. To do this, it is enough to overwrite one of the libraries used by the application with your own, which will contain the necessary code.

If you're interested in how this is used in real life, I recommend checking out the Hackerone report on RCE in Evernote's Android client.

a3b1d0615f5a559140363f91a35c40da.png


Insecure deserialization
Most Android apps are developed using Java/Kotlin, and if input data is not properly validated, unsafe deserialization of data can occur.

Example of vulnerable code:
Code:
private void deserialize(InputStream inputStream) throws IOException,
ClassNotFoundException { 
ObjectInputStream ois = new ObjectInputStream(inputStream); 
MyObject obj = (MyObject) ois.readObject(); 
TextView outputTextView = findViewById(R.id.deserOutput);
outputTextView.setText(obj.toString()); 
}

In this case, a potential attacker will be able to influence the serialized object, change its property or method implementation, as in the example:
Code:
private static void Exploit() throws IOException { 
MyObject hackedObject = new MyObject("OriginalName") { 
@Override 
public String toString() { 
return "hacked " + UUID.randomUUID().toString(); 
} 
}; 
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream("/tmp/exploit.bin")); 
oos.writeObject(hackedObject); 
oos.close(); 
}

In the example, I changed the toString implementation to return a randomly generated value of "hacked + UID".

dcfdffe2af76f13b6aac54081c2e8025.png

Although in this way it is possible to inject any other code and get its remote execution on the device.

A more detailed analysis of the vulnerability is beyond the scope of this article. For a deeper understanding, I recommend reading what serialization is in java, as well as how the tool for generating payloads using the ysoserial gadget chain is structured.

2dc3fe6f2f18886851d372e2c2dc0ac8.png


Code Execution
Standard code execution vulnerabilities are also possible.

Example of vulnerable code:
Code:
private String executeCommand(String command) { try {
Process process = Runtime.getRuntime().exec(command);
...

bbd496e31456afd7011e57f61cfee22b.png


This is rare, as the modern SDK contains enough options to completely eliminate the use of exec.

7687f4a2fc0a4e444e0bf203452460eb.png


Inter-process communications (IPC)
Android has many built-in features for inter-app communication. On the one hand, this gives developers greater flexibility when building an app architecture, but on the other hand, it significantly increases the attack surface for attackers.

1a0fb718cf76fc46a0a9b35ed1642b51.png


Explaining all the IPC mechanisms is not the main topic of this article, so I will only talk about the main entities that are used to exploit IPC vulnerabilities:
  • An Intent is an interprocess communication mechanism in Android that allows application components such as an Activity, Service, or BroadcastReceiver to communicate with each other or with other applications.
  • Broadcast receivers are an Android component that allow applications to respond to system broadcasts, such as events like receiving an SMS or changing network status.
You can initiate broadcast messages using the am utility:
Code:
am broadcast -n com.test.package/.NotificationReceiver -a package.newnotification --es "text" "YOU HAVE BEEN HACKED"
  • A content provider is a component for managing access to structured application data, such as databases or files within an application directory.
  • Deeplinks are schemes that allow applications to open specific actions through link handling, for example an application can be launched through a link like myapp://open?param=value.

This category is difficult to break down into subgroups like injections, so I'll give a few examples of IPC-related vulnerabilities.

abf08d8ff2b3bcc05736cb41bfeb2ad7.png


Exported content provider
One of the most common vulnerabilities in Android applications is incorrectly configured access rights to application entities. As an example, I will give Content Provider.

When a Content Provider is marked as exported, it becomes accessible to other applications. This means that external applications can query and modify the data unless proper access control is in place.

4db31e1e2a47314aaebcbbe45660f8e8.png


In my case, the ISP provided access to the application database, so I wrote a proof of concept (POC) of the application that would contact the ISP and retrieve passwords from the user's database.

An example of a function that implements a call to a third-party content provider:
Code:
public static List<Map<String, String>> getPassword(Context context) {
    Uri parse = Uri.parse("content://com.test.app.contentprovider/pwds");
    ArrayList arrayList = new ArrayList();
    Cursor query = context.getContentResolver().query(parse, null, null, null, null);
    if (query != null && query.moveToFirst()) {
        do {
            try {
                HashMap hashMap = new HashMap();
                String string = query.getString(query.getColumnIndex("pwd"));
                hashMap.put("name", query.getString(query.getColumnIndex("name")));
                hashMap.put("pwd", string);
                arrayList.add(hashMap);
            } finally {
                query.close();
            }
        } while (query.moveToNext());
    }
    return arrayList;
}

While searching for similar cases in the bug bounty, I came across a report in the Nextcloud program. True, here the data was obtained using the drozer software, but the meaning is about the same.

a6df3275f994556b7a4a620ff4ce43f4.png


Local auth bypass via deeplink
Deeplink is used to handle an action in the application when a certain type of link is followed. Often, this action is the launch of an application activity. In some cases, deeplink handling misses application security checks, such as local user authorization checks.

The vulnerable application implemented PIN code authorization:
Code:
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 if (!isPinCodeVerified()) {
 Intent intent = new Intent(this, PinCodeActivity.class); 
 startActivity(intent); finish();
 } else {
 setContentView(R.layout.activity_main); 
 } 
}

251ce60eced64efc70ce4d5c767fbcc3.png


However, the application allowed access to other activities via a link, in particular viewing the user's profile.
Code:
<activity android:name=".ProfileActivity"> 
 <intent-filter> 
 <action android:name="android.intent.action.VIEW" /> 
 <category android:name="android.intent.category.DEFAULT" /> 
 <category android:name="android.intent.category.BROWSABLE" /> 
 <data android:scheme="https" android:host="www.example.com" android:path="/profile" /> 
 </intent-filter> 
</activity>

Moreover, in .ProfileActivity they forgot to implement the isPinCodeVerified() check. To bypass local authorization, it is enough to open the link `https://host[.]com/account` in the browser.

Or run the application via deeplink using the am utility:
Code:
am start –n com.package.example –d "https://host.com/account”

9e119282ce7f5ab8dddc44978006adb3.png
1285dc049f997160264c847f64c89433.png


Information leak via URL-scheme
Another vulnerability is related to URL schemes - when an application transmits sensitive information in cleartext using a URL scheme.

4bfb8563a344a5fe6a8e942bd75ed0d5.png


The problem is that any application can register to handle any URL scheme. We can write our own application that will handle the required URL scheme, for example testapp://createtask:
Code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.evil.app">
<application
 android:allowBackup="true"
 ... 
 >
 <activity android:name=".MailtoAppActivity"> 
 <intent-filter> 
 <action android:name="android.intent.action.VIEW" /> 
 <category android:name="android.intent.category.DEFAULT" /> 
 <category android:name="android.intent.category.BROWSABLE" /> 
 <data android:scheme="testapp" android:host="createtask" /> 
 </intent-filter> 
 </activity>

And it will allow interception of data when accessing the URL scheme from the original application.

6b458a0aaa7279c211c0bd80d339984b.png


So, on Hackerone I came across an account takeover in the Shopify app using this vulnerability. You can read the details in the report itself.

581344fcfb5a7f1a71c15a405497046c.png


Binary vulns
Mobile applications under the hood may use native libraries, often written in C/C++ languages, which are not memory safe.

0c7638c0c9d364594b3907c3490a6769.png


This opens the door to vulnerabilities such as:
  • Buffer Overflow Integer Overflow.
  • Use-After-Free.
  • Double-free.

So fans of the pwn category should definitely appreciate it.

A few articles are unlikely to be enough to fully dive into this category, so I'll give examples of discovered in-the-wild vulnerabilities:

Getting Started​

Reading about vulnerabilities, large attack surface and other features, someone might decide that it is difficult to start researching mobiles. I think that the main thing here is to start. Therefore, I have collected what can help at the start.

bd7a5cfa8a5a7531af8b92f0fe307e1b.png


To get basic knowledge and study the theory, it is worth looking at OWASP and their MASTG and MASVS. I would also recommend paying attention to the free course from Mobile hacking lab. On GitHub you can find collections of resources with task analyses, bug bounty reports and other content that can help in learning (AST, one more repo).

After gaining basic knowledge, it is time to move on to practice.

The first thing you need for mobile app security testing is a device. It is much more convenient to view apps on a physical device, but you can start checking Android apps with an Android emulator, which is not the case with iOS.

From experience I can advise:
  • Genymotion is a lightweight and fast emulator that is more than enough for testing an application.
  • Android studio is a full-fledged development and debugging environment. The built-in emulator is only a small part of its capabilities, so this software is much heavier and requires more computing resources. It will do if you want to write a POC for a vulnerability with a malware app vector.

If you plan to use a physical device, you will first need to root it and enable Android Debug Bridge through the developer settings.

When working with mobile applications, it is worth paying attention to these utilities:
  • JADX is an Android app (APK) decompilation tool that converts Dalvik/ART (DEX) bytecode back into readable Java source code and allows you to examine app structures.
  • Frida is a dynamic analysis and debugging tool that allows you to intercept and modify code execution in real time on devices.
  • Objection is a Frida-based framework that simplifies the process of bypassing mobile app security.
  • AM (activity manager) is an Android command for managing activities and other application components. It allows you to start, stop, and interact with applications through the command line on the device.
  • ADB (Android debug bridge) is a command utility that allows you to interact with your Android device from your computer, performing debugging, installing applications, managing the file system, and executing commands in the terminal.
  • MobSF is an opensource (SAST/DAST) vulnerability scanner for mobile applications. It is unlikely to find anything serious, but it can highlight bottlenecks.

After stocking up on the starting tools and device, let's go get our hands dirty. All sorts of labs and CrackMe will help with this:

Bug bounty programs will help you try your hand at real applications. You can hone your skills on the BI.ZONE Bug Bounty platform, because there are enough public programs there, the scope of which includes mobile applications.

Researching mobile app security opens up career opportunities and helps businesses create quality, reliable products. Hopefully, this article will help some readers pay attention to the mobile app industry and give impetus to research in this area.

Author: Sergey Arefyev, specialist of the application security analysis department.

Source
 
Top