Flutter Secure your sensitive data
By: David Gonzalez
Tags: iOS, Encryption, Flutter, Android, Reverse Engineering

Let’s see how secured it goes

In this situation, I’m going to show you how to retrieve data from Android side, on a signed apk file. I want to know is signing an application with a keystore add extra security, especially to the text assets db.properties I have. As a reminder, this file is here to demonstrate that this is not secured (and we will see why).

There is two ways to retrieve the apk file: directly from the output of flutter build command, or from an installed apk (on your device).

Before investigating apk, I will show you both ways :D.

Retrieve installed APK (the hard way)

Even if this is my own application, I feel like an hacker…

Before starting, check that tools using adb are terminated (check that you closed all applications using adb such as intelliJ, Android Studio, Flutter debug plugin,…).

First, connect your device to your computer, and check that your android device is recognized, using adb devices command in a Terminal (cmd console on Windows computers).

I suggest you to have only one device found. Else each command will need you to specify the device.

Then, you will have to find the package name of your application. You can find it in the build.gradle file, located in ./android/app/ folder. In my case, this is ‘com.example.encrypted_db’.

Locate your apk path using the command adb shell pm path [your_package_name].

Then retrieve the apk using adb pull [device_path] [computer_path] command.

Retrieve compiled apk (the easy way)

You can retrieve the compiled apk too, that may be easier. At this stage, I consider that you have created your keystore, modified required files and compiled the apk using the command flutter build apk.

And… that’s it. The command show you where the apk file is!

Ok now let’s go into serious business

Retrieve embedded file from an apk

Serious things start here. First, an apk is nonetheless an archive file. So here is the trick: change its extension to “.zip”, then decompress it. It may only work in a Terminal/cmd console.

Next, go to the unzipped folder. You will be able to find the database in the assets/flutter_assets/ folder.

And (not) magically, when we try to open it using DB Browser for sqlite, a popup is asking you to write password.

That the level of security we wanted. But the password is plain, either in db.properties file and in the source code. We can easily find db.properties as plain text file inside the apk, so that’s definitively the worst it.

Finding password in the compiled code is a little bit harder.

To do that, we will have to use specific tools, that will dump data from compiled objects. As you may know, in release apk your code will be compiled a-head of time (AOT), in the form of “.so” files.

On my side, I used the arm linux toolchains for MAC OS (https://github.com/thinkski/osx-arm-linux-toolchains). You may have a windows equivalent, but I haven’t tested on that platform.

Then, we will dump objects from the main compiled file: libapp.so, located inside the unzipped apk in the lib/arm64-v8a folder.

Finally dump object using command aarch64-unknown-linux-gnu-objdump -s [compiled_file] (or equivalent on windows and linux).

You shall to store output into a file to process data later ;)

I wrote ouput into reverse.txt file, let’s see what’s in there. By searching plain password text, we can see that we are able to retrieve database name and password, if we know what we are searching!

In red, plain password. In green, database name.