Broken cryptography
In this article, we will discuss broken cryptography in Android applications. Broken cryptography attacks come into the picture when an app developer wants to take advantage of encryption in his application. This article covers the possible ways where vulnerabilities associated with broken cryptography may be introduced in Android apps. We will also see some of the ways an attacker can exploit this kind of vulnerability.
Learn Applied Cryptography
Main reasons for broken cryptography
Broken cryptography in Android apps can be introduced due to various reasons. The two main reasons as mentioned in OWASP Mobile Top 10 Projects are:
- Using a weak algorithm for encryption/decryption
- Using a strong encryption algorithm but implementing it in an insecure way
Using a weak algorithm for encryption/decryption
Let us first see how an app may become vulnerable if it uses an insecure algorithm for sensitive data encryption.
An example would be using MD5 as it is for hashing. MD5 is known to be insecure. If an app is using a weak algorithm like MD5 and if an attacker gains access to these hashes, the chances of breaking them are high. Let us assume that an app has used MD5 and produced the following hash.
9a618248b64db62d15b300a07b00580b
An attacker can use a tool like John or use an online service to perform a rainbow table attack as shown below.
As we can see in the above figure, the hash is cracked.
Apart from this, developers use encoding for protecting sensitive data. Encoding is not encryption and hence can easily be decoded. As an example, let us assume that the following Base64 encoded text is found inside application code after decompiling the app.
c3VwZXJzZWNyZXQ=
This can be decoded just by going to any online website that provides Base64 decoding service as shown below.
Using a strong encryption algorithm but implementing in an insecure way
Another important concept is using a strong algorithm but in an insecure way. When using Symmetric key encryption like AES, though it is strong in nature, it is susceptible to attacks when not implemented properly. Key management is a challenge here. In the next section, we will see how an attacker can take advantage of vulnerabilities due to poor key management.
Demonstrating broken cryptography with the SQLCipher library
Android applications store data on the device in various ways. The usage of the inbuilt SQLite library is quite common for data storage and management in the form of database files.
In this sample app, I used the SQLCipher library for encrypting the database.
From a black box assessment perspective, to decrypt any application database developed for the Android environment, the knowledge of the location of the database file and the type of encryption being implemented is essential.
Prerequisites
Download the APK file below and run it in an emulator, so that it creates an encrypted database.
Examining the SQLite Database - The Usual Way
Let us first see if we can see the contents of the database which was created on the emulator. First pull the database file onto the local machine using the following command.
adb pull /data/data/[packagename]/databases/filename.db
Now, let us try to see the table names using the regular way with the SQLite3 command line tool as shown below.
As we can see in the above figure, we are getting an error saying the file is encrypted. So, we need to have the encryption algorithm used as well as the key for decryption.
Extracting details of the encryption used from the application code
The first step is to understand the process of encryption that has been used. Let us understand this by looking at the decompiled Java code using dex2jar and JD-GUI.
Unpacking the apk file
Android apps are distributed in .apk (Android Application Package) file format. The contents of these files can be accessed by unpacking them, similar to the unzipping of zipped files.
In this example, our target app "SecureSQLite.apk" file is placed in my working folder on the Desktop. Open the Terminal and navigate to the working directory and enter the following command:
unzip SecureSQLite.apk
This command would result in the extraction of the contents of the SecureSQLite.apk into the current directory.
"classes.dex" is the file we are interested in.
Decompiling the code
The "classes.dex" file contains the code of the application. This file is a compiled binary for Android and first needs to be converted to .jar. This can be done using the dex2jar tool.
To use this tool the following command needs to be executed:
dex2jar classes.dex –o classes.jar
This command would result in creation of classes.jar file in the same folder. This file is a package of all the code of the application.
We can now use a tool like JD-GUI to get Java code.
Code walkthrough
A look through the code would give an overview of what type of encryption was used for encrypting the database file.
As we can see in the above figure, a third party encryption library called "sqlcipher" is imported and is used to encrypt the database. The package name for the application is "com.androidpentesting.securesqlite".
Though this is not often the case, some details regarding the key to the encrypted data can be found in the code.
In the above example, the key for encryption is given as "password".
Note: Since this app is made for demo purposes, the data being inserted into the database is also hardcoded.
Decrypting the extracted database file
The decryption can be done using the same library in its Unix/Linux command line version, called SQLCipher Core Command Line.
Download the SQLCipher from this link: http://sqlcipher.net/open-source/
After downloading extract the contents of the download onto the Desktop. This will create a folder named sqlcipher on the Desktop.
Open the command prompt and navigate to this folder and build it using the instructions from this link: http://sqlcipher.net/introduction/
And usage of various commands can be found in this link: http://sqlcipher.net/sqlcipher-api/
To decrypt the database file "secure.db", the following commands can be used:
First we have opened the encrypted database file using sqlcipher command line tool. Then, we provided the key we obtained from the decompiled source code using the following command:
PRAGMA key = 'password';
Now, the database contents can be accessed as a regular database.
We can even export the unencrypted version of database.
Once we are done, we can type ".exit" in the end to exit.
This is just an example of how an application can be vulnerable even if it is using a strong algorithm with an insecure implementation.
Additional Notes
Usage of custom encryption protocols is another problem which introduces vulnerabilities into apps.
In this article, we have seen how weak cryptography implementations can be exploited in Android apps. It is not recommended to hardcode the keys on the device. As we have seen, key management is a problem with symmetric key encryption. If it is really demanded to use such implementations, Password Based Encryption is one recommended way for developers, where keys will be derived based on user entered passwords.
Learn Applied Cryptography