This challenge is linked to a job offer, the article has only been published once the offer has been put offline.
Here is the challenge (originally in French):
During an Android phone analysis, we have found the following file “secfile.enc”. Its content is apparently cyphered and our research led us to think that this ciphering was probably done with the application “SafeCRT.apk”. Will you be able to decipher it?
If you would like to try to decipher it by yourself without any help, stop reading here. I will explain below what was the process done to decipher it (even the wrong directions will be displayed as when I start writing the article, I have not finished the challenge).
Still here? ok then we will then switch to the explanation:
First thing to know, APK is an archive based on zip compression, which means most compression tools can open them. Using your favorite tool, you can have a look at the archive content:
Here is a small description of the content:
lib => Directory containing native library => Can be one though part of the challenge, back on that later META-INF => Typical java directory containing MANIFEST.MF (containing here resource file SHA1 digest) and cert files res => Uncompiled Resources files AndroidManifest.xml => Application descriptor (min Android version, referenced lib, name, version...) classes.dex => Android jar file, contains all classes resources.arsc => Compiled resources
The application seems quite standard, let have a look at the code:
Right now we only have a dex files, i prefer to convert it to jar files to use standard jar decompiler.
dex2jar transform the dex to jar file.
Once we have the jar file, we can open it with jd-gui:
The interesting classes are the one in the package ch.scrt.safecrt (other are android standard ones).
The MainActivity is the standard startup class for android, here is the class we need to dig into.
Here are the different functions existing in the class:
Let’s go dig into the code to understand the decrypt process, what can we see:
- 5 numberpickers are initialized and allows end user to select a number between 00000 and 99999
- this string is sent through generateKey function
- the result is sent through mixKey function and generate the key that will be used
- then the content of the file to decrypt is sent to decrypt function with the key which return the decrypted string
Resumed this way, it seems quite easy, we just need to recreate an application that will try the decrypt for the 100 000 possible input string.
There is just one issue, we don’t have the source code for the function mixKey, if you look closely, you will see that this function is imported through a static statement loading a native library called libtest.so (the one in the lib directory seen when we have opened the apk file).
The native library:
When we open the lib directory, we see a subdirectory called armeabi-v7a, that means that the file inside is compiled to be executed on ARM V7 architecture so to understand how it works, you will need some knowledge on ARM architecture. Sadly, not my case at all.
If you are familiar with such architecture, you can use IDA Pro (not the freeware version not supporting ARM).
As I am not this familiar, I will use an online service:
And here is a screenshot of a small part of the result both in ARM ASM and Decompiled in C.
Needless to say that it seems to be a pain in the a** to understand what it really does.
It is do-able but is there a easier way? and (hopefully) the answer is yes.
The bruteforce application we will write should be running on an ARM V7 structure 🙂 by a matter of fact, I have an android with an ARM V7 CPU in my pocket.
TIPS: this library was created through android native library creation process which means it can only be used by a specific package (reminder: function name is Java_ch_scrt_safecrt_MainActivity_mixKey), so you should check beforehand what package name and class name you should choose 🙂
The bruteforce application
What should our application do?
- open the encrypted file and store it into a byte
- for int i=0; i<=99999; i++
- get the string on 5 char with left padding with 0 (00025 instead of 25)
- generate key (code taken from decompiled source)
- call mixkey (native library)
- call decrypt
- if success write the result in file with combination as filename (because many results may be wrong positive)
Once it is written, let your application run trough every possible combination.
After completion, you can pull files from your android.
We have approximately 400 positive results with only just one true result.
To get through the files easily we need to know what we are looking for, if you have read the decompiled code correctly you should see that only plain text can be entered (input was written on an android keyboard and UTF8 chars are forbidden).
The easiest solution is to rely on a good old command, the file command:
file * | grep text
If you have done everything correctly then you should see the result 🙂