NahamCon is a free virtual offensive security conference and the CTF was a 48-hour competition that lasted between June 15th, 12:00 PM PDT - June 17th, 12:00 PM PDT. This post only covers the 5 Mobile category challenges in the CTF.
Upon installing the application, I encountered a user interface featuring an input field and a "GUESS" button. Nothing much to see.
I decompiled the application package. I stumbled upon a function named decrypt() and an encrypted file located within the application's resources. This finding hinted at the presence of an encryption mechanism employed by the application. The decrypt() function utilized the user's input as the key in the AES decryption process.
Further, my attention was directed to to a string resource named correct_guess in the MainActivity file.
I referred to the strings.xml file and used the value as the input in the application.
It was indeed the way to get the flag.
Firstly, the uppercase letters JNI in the challenge name seemed to be suggest the use of Java Native Interface in the application. The application has not much to do in the user interface.
I decompiled the application and noticed the following line of code in MainActivity. The application was loading a .so binary.
The binary was available in the lib folder of the decompiled application. I ran strings command on the library file and the flag was right there.
The application opened a "Sign-In" page when executed. However, no credentials were provided so there was nothing to test.
So, I jumped into the code and looked at the activities available for the application. There were a couple of exported activities on the application among which "SignUpActivity" felt like the right way to go. So, I opened the activity using ADB.
The UI was not working properly and the sign-up request was not being sent to the server so, I looked further into the SignUpActivity and extracted the necessary parameters for sign-up request.
The application was using Google Identity Toolkit API so I asked ChatGPT for the sign-up endpoint and signed up an account.
Then, I signed in to the application and the user feed looked as follows.
There was a feature to save drafts as well. My CTF experience tells me that the flag is surely on some user’s draft.
As the application was using WebSocket to fetch posts and drafts, I looked through the WebSocket traffic and found a request that was fetching my drafts.
The first part of the request is the user ID, and this was available for other users too when their posts were being fetched for the user feed.
I grabbed the user ID from one of the requests and send a request to fetch the user’s drafts hoping that it does not have proper authorization checks in place. And, sure enough it did not and the flag was retrieved.
Red Light Green Light
The description of the challenge said to press the button when the light is green but it would not turn green at all.
As always, I decompiled the application and found this piece of code. The value of the variable red is set to true and there is a decrypt() function that runs only if the value of the red variable is not true.
Next, I wrote a simple frida script to change the value of red to false from true during runtime.
I hooked the script to the application and pressed the MOVE! button and the flag was retrieved.
Upon installing and starting the application, it asked for location permission and when granted would display a message as follows.
The network request looked as follows for the application. It was sending the latitude and longitude based on the device location and respond how far Waldo is.
ChatGPT had something to say about it.
This, however, did not work but was helpful in some way. After some trials and errors, the flag was retrieved.
All in all, the CTF challenges were incredibly enjoyable and provided a great experience. I'm eagerly looking forward to NahamCon 2024, anticipating an even more exciting and enriching experience.