Back Me Up — Hacking Android apps without root

Noy Pearl
The Startup
Published in
5 min readApr 5, 2020
Image: Unsplash

Why this topic?

Nowadays, we see many tutorials on Android Penetration testing, mentioning using a rooted device as a substantial requirement.

Using a rooted Android device indeed enables you to do many more actions than using an unrooted one.

However, there are a few overlooked methods while pentesting Android apps that don’t require root access. This time we’re going to dive into a very interesting one, which apparently isn’t very well-known — Android Backup.

Why this method?

I chose to focus on this Android Backup method since there’s a difficulty while trying to access the app’s protected data directory with an unrooted device — AKA data/data/APP_PACKAGE_NAME.

Many developers might store there their sensitive data with the claim that you must have root access to read/write these files.

In this article, we’re going to prove why in some cases the above claim is wrong.

To whom is this aimed?

· Android developers

· Security enthusiasts

· Pentesters / Researchers

Some of the methods require an understanding of Android Fundamentals. My suggestion is to google every term you aren’t sure about, understand it, and return to this article. I provided links on specific terms that might be useful for that.

How?

To demonstrate it in the best way — I built an exploitable app in Java.

Here’s the full code of the app — feel free to play with it. Also, I provided there the apk I built so you could test the backup functionality without building the app.

This app represents a bank application that has a few issues which we’ll talk about later.

The package name of the app is com.app.dontbackup. Remember it; we’ll use that later.

Install the app and run it.

Android app main screen

As you can see, this screen shows the full name and balance of an account named Ciri.

I’m saving sensitive information about this user by using an Android component called SharedPreferences. Using this component — the data is saved to /data/data/com.app.dontbackup/shared_prefs/com.app.dontbackup.xml file in the device.

Although the phone number and address aren’t represented on the screen — I still save them using the SharedPreferences component.

The following code in the app saves the sensitive details in the shared preferences folder:

private void writeSharedPrefs(SharedPreferences prefs){
prefs.edit().putString("name", name).apply();
prefs.edit().putInt("balance", balance).apply();
prefs.edit().putString("address", address).apply();
prefs.edit().putString("phoneNumber", phoneNumber).apply();
prefs.edit().putString("email", email).apply();

Many times I see sensitive information that is saved that way, including users’ full name, phone numbers address, username, and password.

Now, Using a rooted Genymotion emulator — I want to show you how the data is actually saved. Don’t worry — when I’ll show you the exploitation method, I’ll be using an unrooted device.

To see the file in a rooted device, we run the following command using ADB:

adb shell cat data/data/com.app.dontbackup/shared_prefs/com.app.dontbackup.xml
Like that, I can see all of the sensitive data that I saved in the device.

But — this isn’t something spectacular. We want to see the data using an unrooted device.

Let’s do it.

Switching to an unrooted Android device.

Great, this device isn’t rooted.

We know already that there’s sensitive data in /data/data/com.app.dontbackup/shared_prefs folder. We want to get it. To do so — we will use the Android allowBackup feature.

This is a feature that enables you to perform a backup of an application via ADB. It’s enabled by default in the AndroidManifest.xml. Here’s a screenshot of it from our app:

allowBackup is enabled by default

Read more about it here.

Using ADB, run the following command to create a backup file of the app’s data:

adb backup -f backup.ab -f com.app.dontbackup

This command will ask the device for backing up the data. If a password is required — fill up the real one. If there isn’t one — leave empty.

Device prompt to backup the data

Now — we got a backup file called backup.ab. Let’s extract the data from it.

We’ll use an open-source tool called android-backup-extractor

Using this tool — We’ll use abe.jar file and turn the backup file into a tar archive

You should get a file named unpacked which is a tar archive

Extract it and get the shared preferences file

Now we can see the sensitive data that was saved to /data/data:

data was extracted from /data/data without root

This app saves only this specific data. Other apps might save much more data in a handful of ways, including SQLite databases, images, app’s configuration files, and security tokens.

Reading this data is excellent — what about modifying this data in the app’s folder with an unrooted device?

I’ll let you research on your own.

A little hint: ‘adb restore’.

Good luck.

But are the dangers real?

Some of you might say that this method of extracting and restoring this sensitive data to the app isn’t that simple. That it requires a device with debugging settings enabled, and who does that?

The answer is a lot. Many of us enable these settings to perform various actions: installing custom ROM, developing and testing Android Applications, or simply exploring the Android system.

Security Mitigations

As I previously showed — enabling backups of an Android app endangers the data stored in its most protected directory. Except for revealing the SharedPreferences — it could expose sensitive SQLite databases that store sensitive information about other users, including full names, addresses, emails, private phone numbers, private images, and any other sensitive data you could think of.

Think about it like that — The app may include any data that the developers thought to keep in secret from everyone who isn’t the app’s process.

If you insist on enabling backups of the app, make sure to do the following:

· encrypt the data with known and robust encryption algorithms.

· Make sure that the encryption key is a unique one and isn’t hardcoded in the app — otherwise, an attacker can read/predict it

· Apply proper decryption of the restored data. Allow the only data that passed the decryption successfully to be restored.

--

--