Insecure local storage: Shared preferences
In the previous article, we discussed the common techniques of how application developers check for a rooted device and then how an attacker can bypass some of the techniques used by the developers. In this article, we will discuss different methods being used by Android developers to store data locally, and then we will see how secure these methods are.
What should you learn next?
Device loss is a very common problem with mobile devices. An attacker who has physical access to the device can have access to personal as well as corporate data stored in the device. The situation could be worse if the device is rooted. Keeping this in mind, if the data storage mechanisms being used by an application are not implemented properly, it may lead to serious attacks.
[download]
Android local data storage techniques
Developers can store data in Android applications locally in various ways, as shown below.
- Shared preferences
Shared Preferences are XML files to store private primitive data in key-value pairs. Data Types include Booleans, floats, ints, longs, and strings.
- SQLite databases
SQLite databases are lightweight file-based databases. They usually have the extension ".db" or ".sqlite". Android provides full support for SQLite databases. Databases we create in the application will be accessible to any class in the application. Other apps cannot access them.
- Internal storage
Internal storage is another way in which we can save files directly on the device. By default, files saved to internal storage are private to your application, and other applications cannot access them. When the user uninstalls your application, these files are removed.
- External storage
External storage is a location that you can use to save files. This can be a removable storage media (such as an external SD card) or an internal (non-removable) storage. External SD cards are world readable.
In the next section, let's see how developers can use Shared Preferences to store data on a device, and then we will see how an attacker can access this data from a device as well.
Prerequisites to follow the steps
- Computer with Android SDK installed
- A rooted mobile device/emulator to install the apps
Test application's functionality
I have developed a test application to demonstrate the issue. You can download the sample application from download section. After downloading the application, install it on a rooted Android device or in an emulator.
App can be installed with adb using the following command:
adb install <name of the apk>.apk
Figure 1
All the applications have a feature to store data inside the application. When we launch it, it appears as shown in the figure below (Shared Preferences app is used here).
Figure 2
Shared preferences
Lets launch the sharedpreferences app and insert some sample data into the username and password fields.
Shared preferences are created in Android applications using the SharedPreferences class. Below is the piece of code used in the sample application given for download.
Figure 3
As we can see in the above figure, we have created a SharedPreferences instance and then we are using it to insert data into the xml file using Editor object.
Now, let's go ahead and see where this data is stored in the application.
The common location where SharedPreferences are stored in Android apps is:
/data/data/<package name>/shared_prefs/<filename.xml>
So, let's navigate and inspect the above path to see if there are any shared preferences created in this application.
Figure 4
As we can see in the above figure, there is a folder named "shared_prefs". This gets created when an app is using shared preferences in it. We can change the directory to shared_prefs and use the "cat" command to look at the contents of this application right away.
If we want to get the xml file onto our local machine, we can pull the file as shown below.
Figure 5
As we can see in the above figure, "userdetails.xml" file has been copied onto the local machine. We can now see the contents of the file as shown in Figure 6.
Figure 6
Cracking gaming applications to modify the scores
Most of the games available for mobile platforms are native applications and do not require the Internet while playing them. So, it is obvious that the statistics associated with the game would be stored locally somewhere on the device itself. On a rooted device, if we explore the local file system for the files storing these game scores, we can easily modify them and bypass the limitations.
Let's take a popular application named StickCricket. This game is very popular on the Internet and personally I love it because of the difficulty in achieving high scores. Let's see how we can modify the scores of this application from the backend.
Prerequisites
- Device must be rooted
- Droid Explorer tool for analyzing the file system
- ADB access on the device
When we launch the StickCricket application to play it, it has an activity which shows the best score so far. Generally, it is difficult to score 130+ from 5 overs.
Now, let's see how we can crack this application to increase the score.
Let's navigate to the application's local file system to see the files where the application can store its data. This is shown in the following figure.
We have opened an adb shell on the device and then elevated the privileges using the "su" command. Every application installed on an Android device will have all its application-specific data inside "/data/data" directory. So, we have navigated to /data/data/com.sticksports.stickcricket/.
If we execute the "ls" command here, we can see some directories where the application stores its data. The directory of our interest here is "shared_prefs". Now, let's navigate to the shared_prefs directory to see if there are any interesting files inside this. This is shown in the figure below.
We have navigated to shared_prefs directory and listed all the files inside this directory. There are three XML files inside the shared_prefs directory. If we do some analysis on these three files, by looking at the contents using the "cat" command, it is obvious that "Cocos2dxPrefsFile.xml" is the file which is being used to store all the scores. Now, we have to replace the existing scores in this file to the scores we wish to have.
To do this, I am using a tool called "Droid Explorer" in Windows.
Droid Explorer can be downloaded from their official website: >http://de.codeplex.com/.
Droid Explorer is a nice tool to interact with the device using Windows Explorer. Its GUI makes our life easier to perform various tasks such as moving files from device to machine, uninstalling applications, making a backup, etc.
Below are the steps.
- Connect the Android device to the machine.
- Launch Droid Explorer and navigate to the target directory.
- Pull the file onto the device and open it in a text editor
In the above figure, we have changed the highest score from 129 to 180.
- Now, delete the Cocos2dxPrefsFile.xml file from the Android device using Droid Explorer.
- Push the modified "Cocos2dxPrefsFile.xml" file from the machine to device using DroidExplorer.
- Launch the game again. Now we should be able to see the modified score updated in the application as shown below.
What should you learn next?
Conclusion
In this article, we have seen how shared preferences are implemented in Android apps and the security issues associated with them if they are not properly implemented. To secure application data, it is recommended to use crypto libraries available. We will discuss how to use crypto libraries in your Android apps later in this series. In the next article, we will see the other ways to store data in Android apps and security issues associated with them.