Estimated difficulty: 💜💜💜🤍🤍
Oh no, it’s another one from the MOBster series coming to get you! Hide… Run… Read with intrigue! This post is covering, M2: Insecure Data Storage, the second listing from the OWASP Top 10 Mobile Risks list. The last post in the MOBster series covered M1: Improper Platform Usage.
Insecure data storage is common and easy to exploit. At a high-level, this can occur when the developer from a third party application insecurely stores data on the device, where an attacker. For this post we will focus on the Android operating system and walk through how we can exploit this vulnerability.
What in the APK is it?
Insecure data storage sounds like exactly what you are thinking! It occurs when data is not securely stored on the device, and when data is accessible to an attacker. An attacker may be able to access this data by stealing the device itself or by implanting malware on the device to exfiltrate sensitive data. It should be noted that certain vulnerabilities may need to exist for an attack to be successful. These conditions might be:
- A vulnerable operating system.
- Vulnerable frameworks.
- A vulnerable compiler environment.
- A rooted/ jailbroken device/
It may be easier to think of it in a more familiar scenario. For example, if we think of a traditional web application we think of a server to host the application, a database to store the application’s data, a framework and software libraries to create the application and something to host the app like a browser. This is similar in mobile applications; however, there are different types of mobile applications such as native, hybrid and web, which affects how some of the application’s components work.
In summary, the mobile app is installed onto your device somewhere in the filesystem. The application is developed with a framework (if not a native app), software libraries and the application is executed by a runtime environment. All in all, each component may play a part in making an application vulnerable, like it would a traditional web application.
According to the OWASP Mobile Top 10 itself, insecure data storage is common and occurs when developers assume that an attacker will not check the sensitive data stores or filesystem of the device.
The data that an attacker might after could include Personally Identifiable Information (PII), credentials, proprietary data and much more. This could have a severe impact on the companies reputation, as well as the user itself, for fear of fraud and identity theft. You can see the OWASP Mobile Top 10 guide for a more detailed explanation of the impacts.
How it works
There are many ways a developer might insecurely store data, below I have listed some examples.
- Sensitive data is stored with no encryption.
- Sensitive data is stored with poor encryption libraries.
- The data is stored in a shared location.
- Components used such as libraries and frameworks become vulnerable.
To explain how insecure data storage can occur more accurately we will focus on how applications are installed, stored and executed on Android devices. Ever since I have been trying to learn about mobile security the following diagram never fails to help me understand. Although please note, Dalvik is now old, ART is the new runtime engine.
As you can see in the above image there are multiple components an application might interact with when running. The application might store some data in the SD Card. The SD Card driver that exists in the kernel will tell the OS how to function and store that data. Alternatively, a library in the application such as a database library might tell aide the application to access the data. Each component used may become vulnerable.
There are multiple ways an application can store data, such as the following:
- SQL Databases (we see this later in challenge 2)
- Log Files
- Text Files (we see this later in challenge 4)
- XML Data Stores (we see this later in challenge 1)
- Binary Data Stores
- Cookie Stores
- SD Card (we see this later in challenge 3)
- Cloud Synced
Likewise, storage methods can make the application insecure. So it’s important to consider how the app is processing and storing your data if it is being stored locally and how easy it might be for an attacker to steal. For example, if an attacker installed malware on your device and an application had stored plaintext credentials, accessible to other apps, then an attacker may be able to exfiltrate this information.
To understand this vulnerability further, let’s look at an existing real-world example where insecure data is a serious risk. Now you may be thinking that an attacker may need to physically steal your phone to steal the sensitive information off it… that is no longer the case! Malware can be introduced through 3rd party apps. Luckily there are certain scans performed on unrooted devices to try and protect you from these kinds of apps and malware, such as SafetyNet. There is a great article on Forbes, that lists Android applications that have contained malware that has been able to read the external storage of your device, amongst other creepy dangerous things!
There will always be apps that slip through the cracks and safety checks for malicious content. Please be careful when downloading apps and make sure you trust them when you do to limit the risk. Rooted devices will have less protection against detecting malicious applications also, so I would say root with caution. 😛
Try it yourself!
So now we know the theory behind the issue, let’s get our hands on the technical nitty-gritty! After all, we might as well learn by doing. Make sure you have completed the following steps for your setup:
- Install/pull the application DIVA either from Git and compile the source or the beta apk.
- Install the Virtual Machine (VM) software Virtual Box to host your VM.
- Install your VM of choice, I use Kali Linux as it holds a lot of pentesting tools.
- Install Genymotion for an Android emulator.
- Add a virtual Android phone in Genymotion by clicking the plus button. This is so we have a device to carry out testing. I’m using the Google Pixel 3a 10.0 API 29.
1. Start up your Kali machine (or VM of your choice) and the Android test device. You can start your Android test device in Genymotion. Make sure that both the VM and Android emulator (phone) are on the same bridged adapter network. You can change these settings in Virtual Box by going to the Network tab in Settings. Check the IPs of each device and make sure they are on the same network. There should be consistency between the IPs.
2. Since we are using DIVA (Damn Insecure Vulnerable App) to practice our testing we want to install the apk on the phone. We can use either adb (android debugging bridge) or just drag and drop the file onto the virtual Android device. First, download the DIVA application onto your Kali VM, then run the following adb commands or drag and drop the file.
Commands for adb install (to be run on Kali):
adb connect <Android IP>:5555 adb install diva-beta.apk
3. Open the diva-beta application on the Android device. There should be a list of tasks for you to complete. We are going to focus on the Insecure Data Storage challenges to fully understand how this vulnerability may affect the device.
4. Now the setup is complete we can test! Select the first challenge: Insecure Data Storage – Part 1 and let’s get cracking.
Insecure Data Storage – Part 1
This challenge highlights the importance of encrypting your data at rest!
1. First we need to input our username and password into the application. Once these have been submitted we can go ahead and tackle one of the objectives – where are the credentials being stored. As we are already connected to our virtual Android device through adb, we can drop into a shell using the below command:
The base OS for an Android device is Linux and therefore we can use similar/ the same commands when interacting with the device.
2. We can blindly poke around, however, a quick Google search suggests that the data may be stored in /data/data/<package name>/… so lets have a look in there.
3. We can see a folder called databases. This does not bring up the creds, however contains interesting table information. We go back and there is a folder called shared_prefs. This is a method of storing information for the application and we can see that it has stored our credentials in the jakhar.aseem.diva_preferences.xml file.
4. The map tag has been used to may key pair values and in this case, it is the username and password. This is insecure as the data has been stored in plaintext. As the root user, we are able to easily access and identify this data.
Challenge: As we briefly covered reversing an app in the last post, see if you can find the relevant java file defining the activity for this challenge.
Insecure Data Storage – Part 2
The data seems to be a-lookin-like it has been stored in plaintext again! But this time in a SQLite database… 😮
1. To kick off this challenge, it looks like we need to enter in our third-party creds again! This time I am going to change my credentials to be john:smith, as to not get confused with the previous challenge.
2. After checking the initial shared_prefs folder and not finding anything, I was led to the databases folder again, just to see what was in there. It turns our the application has been busy in here! It has created two new folders ids and ids-journal.
3. We can open these new files however we only see a line of what looks to be SQL light code. We may or may not have had a hint from the previous challenge, when snooping on the database files initially.
��en_USblemyusermyuserCREATE TABLE myuser(user VARCHAR, password VARCHAR)W--ctableandroid_metadataandroid_metadataCREATE TABLE android_metadata (locale TEXT)
4. We need to find a way of interacting with these tables. Looking at the Java class file for the activity provides us with more information on how the database is set up.
5. We can see that the table “myuser” is created in the ids2 database. We have also identified this from our snooping, therefore we should try and interact with it. We need to run the below commands in the Android shell:
SQLite3 exists on this Android device. We can run the following commands in the sqlite prompt to view the table information for “myuser” like we previously identified in the code.
sqlite > .tables sqlite > select * from myuser;
6. Bam we have access to the credentials! Not so hidden now, and they are in plaintext. This is the opposite of best practice.
Insecure Data Storage – Part 3
Temporary files are the culprit here, let’s see if you can find them!
1. For this challenge it’s the same again, input your credentials and save them, so I have used the creds in honour of our lovely Captain Sir Tom Moore – captain:tom.
2. We haven’t been given much more information to go off here, so we can try all the previous haunt, the shared_prefs folder and the database. From this, we can see that the credentials are not in that folder, but upon changing back a directory to:
We can see the file “uinfo2211390882447365772tmp”.
3. Cat the file and we will see the username and password captain:tom.
4. Upon saving our credentials in the app, this damn insecure vulnerable web application has created a new temporary file and stored our credentials here. The code within this application shows us how the activity is doing this. I use jadx to decompile the apk.
Challenge: Try to decompile the application yourself and view the code.
Insecure Data Storage – Part 4
Files being stored in external storage and plaintext are not the best way to go…
1. As the challenge is yet again very similar if not samey looking to the previous challenges, I have created the last set of credentials as last:lastpass (we all love a good password manager as well).
2. Since it’s the last challenge, let’s turn things on its head and analyse the code first. Take the apk file and unzip it. You should see a classes.dex file. This is where all the main code for the application is stored. We can run the tool dex2jar against it to pull out the jar file. you can use any java decompiler to view the code.
3. Alternatively I like to use jadx to view the code. All you do is open the apk file in the jadx GUI (Graphical user interface) and it instantly displays the code for you. We can now see the class and how the activity is behaving for Insecure Storage – Part 4.
4. We can see here that the code seems to be storing the “uinfo” user info in the external storage directory with a file named “.uinfo.txt”. We need to make note of the dot in front of the file name as this means it would be hidden. To me, external storage indicates that it is saving the data in the SD Card.
5. Go to the sdcard directory. I initially made the mistake of going straight to /sdcard, however the file was found in the /mnt/sdcard directory. Use the command below to list the file.
Use the following command to view the contents of the file.
6. And that is a wrap we have found yet another set of plaintext credentials in the external storage in plaintext. This storage does not restrict permissions on who can read this file and therefore is even more vulnerable.
What did we learn?
For me, one big takeaway from completing these challenges is that data should be encrypted at rest, especially if in a shared location! Base64 or other attempts to obscure the credentials is not really that smart… And the main takeaway comprising of limiting yourself to the number of apps and being aware of what information they will, so you are clued up in protecting yourself!
Thanks for reading through this post, it was a long one, but you made it! I would just like to note that there are many other walkthroughs on hacking the diva application and I have to give my thanks to them, as they helped me through when writing this post!