One challenge at Insomni’hack CTF this year was about memory forensics on Android devices. The challenge provided a memory dump of an Android device along with the task to retrieve some encrypted information from it.

Besides the memory dump, two additional files (module.dwarf and System.map) were provided:

The first tool that comes to mind when analyzing memory dumps is Volatility. In order for Volatility to “understand” the memory dump, it needs to have a profile matching the original device. Creating a profile requires the system’s module.dwarf and System.map files (what a coincidence). Details about building a profile for Android can be found here: https://github.com/volatilityfoundation/volatility/wiki/Android#build-a-volatility-profile

Once the profile has been created, it is available in Volatility:

Volatility is now ready to analyze the provided memory dump. Out of the box, Volatility provides several commands for analyzing Linux memory dumps (most of them work for Android as well):

By running the plugin “linux_pslist” we get an overview of all running processes at the time the memory dump was created:

Among these processes, one catches our attention, as it is named exactly as the challenge:

This seems worth analyzing further. We can gather additional information about said process using different plugins (e.g. listing the static environment variables for this process):

However, we suspected that we should have a closer look at the underlying application itself. Luckily, we can recover quite a big part of the file system with Volatility. The following command tries to restore the parts of the file system that were loaded into the memory at the time the dump was created (takes some minutes to complete):

As a result, we are provided with the following output:

Next, we try to locate the .apk of the secr3tmgr process:

Using “apktool” we can now disassemble the above .apk file:

This provides us with a pseudo source code for the application in the form of smali files:

Smali files are essentially disassembled .dex files (.dex files contain the binary Dalvik bytecode).

For further analysis, the tool “jadx-gui” (https://github.com/skylot/jadx) has been used, which also allows disassembling of .apk files in a GUI. Furthermore, it tries to reconstruct the original Java code from the smali files.

As can be seen below, we can now browse the Java code and have a look at the actual implementation:

The application reads a file called “Secr3tDb.json” from its assets. These assets can also be accessed with either “jadx-gui” or “apktool”:

Now we have found the encrypted values and need to decrypt them. The associated code can be found in the MainActivity class:

We can see that the application prompts the user for a password and then attempts to decrypt the encrypted values:

The implementation of the cryptographic functions can be found in the same class:

Now all we need to do is find the password, as we already have all the other components (used algorithms, salt for the key derivation function etc.) Our best guess is, that the password was entered by the user prior to the memory dump creation and therefore can be found somewhere in the dump.

To narrow down the search (the memory dump is 1.1 GB), we extract all memory maps associated to our process using Volatility:

This leaves us with about 680 MB of data (which is still a lot to find the password). Next, we run a simple string extraction over said memory maps:

We now try to locate the password based on its context. We know what kind of strings are used by the application (i.e. the name of the json file, its content, the password prompt etc. etc.).

As an example, a search for “Finance” (one of the entries in the json file) with 20 lines before and after is shown below:

As can be seen in the screenshot above, we have found several other strings that we already know (i.e. contents of the json file), but also something that looks like a potential password. In order to verify this, we create a simple Java class based on the code of the secr3tmgr application:

Running this code yields the flag: