Played with my Uni team @cyb3rk1m4th1 and ranked 3rd on the scoreboard. Great challenges and dope team mates too!
I solve android/mobile challenges for teams I play with and slowly getting to rev challs as well.
There were 6 challenges and we solved 4. Here’s how I approached the challenges with tools I use in ctfs, bugbounty and general android pentesting.
Tools:
jadx/jadx-gui - Decompilation
Genymotion - Android emulator
linux swiss knife - strings | grep | e.t.c
android sdk - adb | logcat | e.t.c
frida - (didn’t use in any of the challenges. but important to have)
Disclaimer - I will not show (installation/tutorial) on how to use any of the tools. You can however install the tools and you know… learn how to use them.
General Methodology:
I do not strickly adhere to this methodology (like I don’t many things in life) but, I always try to.
Download the apk
Install the apk to the android device (drag n drop to install in geny)
Run the application (to know what it does…)
Decompile with jadx-gui
Depending with what we get after decompiling, things take their course. At this point, we can now start thinking about frida, objection, burpsuite, ghidra, e.t.c
Challenges
Note: flag format was flag{} - Important when greping strings!
Chall 1:
Downloaded the app and installed it to my geny device. Launching the app, I’m greeted. There’s no other activity, so decompiling is the next step.
jadx-gui
Similar to the main function in programming languages, android applications have a mainActivity that is launched first. The mainActivity is then important when reversing as it will always point you to other activities.
In the case of the multilingual app, the mainActivity sets a layout of the app and it’s done. So what next? strings
jadx
there’s jadx-gui and jadx. gui for graphical user interface. jadx is a cli utility and I use it when I want to decompile the apk without the need to see the code.
usage: jadx -d multilingual multilingual.apk
The application is decompiled to the multilingual directory. The decompilation creates two other directories, sources and resources. Resources has the assests (strings, drawables, layouts, e.t.c) while sources has the code sources.
I used grep recursively on the resources dir in search of flag
good. Got a three part flag which was base64 encoded.
Chall 2:
Run application
There’s no interaction we can have with the mainActivity, so we move to jadx-gui.
You now know about mainActivity, right? Nothing much there. Set’s the layout and done. However some important info here: ‘insider preview’.?
jadx-gui
Decompiling the app with jadx-gui, we see an InsiderActivity. The activity also sets a layout and it’s done. But unlike the mainActivity, we haven’t seen what is displayed by the InsiderActivity. There’s no button or function to get the app to launch the insiderActivity. How do we do that?
The androidManifest which is an xml file, lists all the activities, permissions, intents, receivers and all other android components. This is important because it informs us if activities are exported or not. More on exported activities
The InsiderActivity is exported and that means we can access it using the adb’s activity manager (am), or create another application to do that (I don’t think you want to do this. Please do though).
usage: adb shell am start com.shehacks.intervasity.earlyaccess/.InsiderActivity
The command launches the activity and there’s the flag!
Chall 3:
run apk
On running the application, we get a prompt for some password. The password will perhaps retrieve some secured notes and maybe reveal a flag. We however don’t know the password. Can we find it though?
decompile with jadx-gui
Decompiling this apk, reveals that’s it obfuscated. Nothing to worry about because with jadx-gui *everything is possible.
Time to read through the code and get the logic. Some knowledge with java or ability to read and understand code is important. (Anyone doing this kind of thing is certainly smart enough to read code.)
The mainActivity
has two methods n() and o()
n() - decodes a base64 encoded string and returns the decode string. okay…
o() - takes care of what you see on the screen. text et.al
At this point, we don’t see any usage of n() in the mainActivity. Hunting it’s usage with jadx-gui is easy. Rightclick the method and choose Find Usage.
Found it’s usage in another class and there laid it’s logic.
get’s a string (R.string.secret), passes the string to n() as the parameter to decode, reverses that and converts it to a string.
what to do? get the string, decode it and then reverse it.
voila!!
To get any referenced strings in the application, go to /res/values/strings.xml
password
Chall 4
you know… run the app (check functionalities), decompile, yada yada yada
note: when you have an application that has register, login and activate functionalities, call burpsuite.
Also, note that not all apps will need reversing. Interacting with the functionalities offered may lead to the discovery of subtle logic bugs.
Methodology
Register account
Try to login (redirected to activate)
Activate
! All these while intercepting with burp suite
The activate functionality is interesting. Asks for a code that is said to be sent to your email. Waited for that email but nothing came!
Intercepting the request_otp endpoint with the correct email and password returns a code and a message. Ignore the message. No email is coming!
There, got the code and went a head to activate the account with it. Time to login.
hmmm… no flag, just a screen with my 0.00 balance (cries in real life)
Checked the response of the /login endpoint and there:
Chall 5
A continuation of chall 4. Didn’t solve this though!
… thought of IDOR, but the account id was encoded and couldn’t get a way to decode it.
Chall 6
A more secure app than chall 3. Reversed it and got the logic. Uses a password to unlock the notes, similar to chall 3. However the validation is done using functions in the libraries.
This required some knowledge of JNI functions and patience. Lots of patience reversing that. I didn’t have the patience and run to other challenges.