Lately I am interested in reverse engineering as much as Achal Sharma is interested in Udip Shrestha. So, I completed the DIVA vulnerable app and many other android reversing courses via youtube. And, I planned to try one real problem. Not a real tho, it was a CTF Challenge I found in github and planned to try this one.
So, I downloaded the apk from above provided link and quickly setup my android device with adb and run the app. The app greeted with me screen which says guess the flag.
I tried blank inputs, tested very long inputs and got no luck. It always said Nope, that’s not it.
Then i quickly checked adb logcat if the app is leaking some logs which gives me flags. But no luck, I had to decompile this app now and do static analysis.
I quickly fired up jadx and opened my apk there. This is what I found the flag checking function.
This is too complicated and I need to spend 3/4 hours to find flag by analyzing this code.
So basically if you’re not a java developer what this does is whenever you type anything in that field and press the button. It checks if your provided string equals with the string returned by the function i(). And now our search is very narrow but deep.
In order to find the correct flag, we need to find what is the string returned by the given function. So, if you started doing maths on that, well good luck on that.
Trust me, I tried.
Then, I got an idea. If this application is checking this string with my string. Then what if I can log this string out. Then i decompiled my app using apktool.
apktool d FlagApp.apk
Now, my FlagApp folder had all codes decompiled into smali files which can be analyzed and also modified. Then, I got a plan. I will inject a code in up of the return statement to log out the string which is about to be returned by i function. So, This is the expression which logs out a string in smali.
invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
Here, v0 and v1 need to be two strings which will behave like log title, and log message. So, I need to put my string here and the application will log out the flag to me.
Here, you can see line 235 is converting my byte array into string array and saving into string instance v0. Now, I need to log this v0 out. Now, it doesnt matter to me if the log title and log message is same.
So, I added the highlighted line which basically logs the value in v0 out to the android logger which I can read from logcat.
After editing this piece of code. I again recompiled and signed the app using these commands which is pretty straight forward.
apktool b -d application -o unsigned.apk
Now, The app is created but I also need to sign it so I created a keystore and signed my application with it.
keytool -genkey -v -keystore key.keystore -alias alias_name -keyalg RSA -keysize 2048
After creating a keystore, time to sign my apk with it.
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore key.keystore unsigned.apk alias_name
Now, my apk is signed and ready for installation but we need to zipalign it because the old certificate conflicts with my new one.
zipalign -v 4 unsigned.apk final.apk
Now, I am ready to install my app. And did it too :D
adb install final.apk
Now I opened the app and run adb logcat with grep in threadLoop because threadLoop occurs so frequently it’s impossible to see any other logs.
so I did this.
#/ adb shell
130|OP486C:/ $ logcat | grep -v threadLoop
This greps all log output except those lines containing threadLoop. Now, I opened the app and hit some random inputs and checked the logs.
See the last output, it’s from my apk as the log title and log message is same.
Checked in the app if it’s correct one and yes :D That’s the flag :P