Cybersecurity Contributions
  • CyberSec
  • Zixem Challenges
  • TryHackMe write-ups
  • TryHackMe SQL Injection Lab
  • SQLi Collected Cheat Sheets & write-ups
  • Portswigger - SQLi Labs
  • Riddler CTF Challenges
  • Cyber Apocalypse CTF 2022 Web Challenges
  • CyberStarters CTF Challenges
  • SQLi Filter Bypass 101
  • Order By SQL Injection
  • Black Hat CTF Web Challenges (2022)
  • TJCTF 2023 writeup (Code Review)
  • CAT CTF 2023 Web Challenges
  • Arab Regional CTF 2023 (Cyber Talents)
  • BugHunting
    • Google dorking to SQL injection
Powered by GitBook
On this page
  • Web Security
  • Mobile Security

Arab Regional CTF 2023 (Cyber Talents)

PreviousCAT CTF 2023 Web ChallengesNextGoogle dorking to SQL injection

Last updated 1 year ago

Greetings again, today I'll share how I solved most of the -offensive- challenges in Arab Regional CTF that was held by Cyber Talents. I could have solved more but the infrastructure was so bad (servers went down alot).

Web Security

Note Harbor (Medium)

It was a code review challenge, so let's go ahead

Let's analyze the app.py file, We can see at the beginning some configurations like secret key, database file and the declaration of the database:

I think that the DB here is based on ORM (Object Relational Model) where every Table is treated as a Class which makes it not vulnerable to any form of SQL Injection. Moving on to see the endpoints

The registration endpoint accepts from us username, email and password. While the login endpoint only accepts the email and password

The app is basically a note taking app, so let's register and login to see what we can do

Now after logging in, there were 3 endpoints to deal with the notes, update_note , delete_note and add_note the first 2 may be good starting point but there is restriction to the user session

Until we see this endpoint:

It retrieves user data upon the ID only without validating the user session, very suitable one for retrieving other users' data

Now what we want ... admin? flag? returning to the challenge description :

So we need to find this user, I turned burp intruder until I found it with id of 262

We got her secret and the email, now what? returning back to the code we see that there are 2 endpoints forgot_password and reset_password .

This endpoint takes the email only of the user. It also makes use of the generate_token function, then this token will be used in the reset_password route as follow : /reset_password/token ... nice, let's see the generate_token function:

So it simply generates a seed using the user secret (which we've got) and also the current time in minutes .... And it generates the final token using random.choice upon set of characters. Since we've got the secret we can control the seed hence control the random.choice and reset her password, to make things faster I wrote a script that will get the token and change the password

Finally when we login with the new password and the email :

RenderSaas (Hard)

Again a code review challenge, let's see what we have

The first thing I'd like to see the package.json file which may vulnerable versions for the libraries

So let's see the main code, First thing we can see is the register endpoint

It takes from us 3 parameters: username, password and user_regular ... If we supplied the value 0 to the user_regular directly it will replace it with 1 so we will be regular users

At the render endpoint we see that we should not be regular users to access the rendering feature

So how can we be special user? well if you noticed in the above code the function parseInt() is applied on the user_regular .... So if we passed it as "0e0" it will resolve to 0 and we would grant the special feature without passing the value "0" directly to it. The reason this worked is because the database accepts user_regular as a TEXT not a number

So let's register our user

Now After we login we notice that we can access the template render feature using the ?template query parameter. and it doesn't show us "Functionality not available for regular users!"

Now we need to get code execution, After searching a lot for Dot template injection I came across this payload:

{{= global.process.mainModule.require('child_process').execSync('ls').toString() }}

This will execute the ls command through the child_process module , and the result is:

We can now read the flag file easily.

Mobile Security

There was only one mobile challenge in this CTF (sadly), let's see how to solve it. The app name is act.apk so we can download it to our device using the following command:

adb install act.apk

When we first open the app :

When trying to supply any input we got the following message:

Nice, now let's use jadx-gui to decompile the app:

CTF apps usually are located at com directory, so by heading to it:

We see that it is located in the package com.myapp and also we can see that the main activity extends ReactActivity which is a JS framework used to create mobile apps. Our approach now does not depend on reviewing some JAVA code, instead we should review the JS code for this app. It can be found in the following file: Resources/assets/index.android.bundle :

Some gibberish JS code, going through this code from the beginning is impossible so instead we can search for the word "flag" or "Wrong Flag":

I actually attempted to submit this value but it was wrong .... But what does this code do?

function y(t){
t==f('flag{N0t_Th4t_E4sy}')("616b66607c37333662363f3036613f3765643f3f663366306161643335613632653e653f667a")?j("Correct Flag"):j("Wrong Flag")}

So simply this function compares the value of variable t with the output of the function f() if it is true it will show us Correct Flag and of course if we provided wrong value it shows Wrong Flag as previous.

What we can do now? Well we can trace the code to find the function called f() and analyze it's implementation .... or we can simply modify the app.

A common approach within react challenges is to modify the JS code and rebuild the app to achieve what we want. I opened apklab extension on vscode and wrote the following line:

function y(t){t==f('flag{N0t_Th4t_E4sy}')("616b66607c37333662363f3036613f3765643f3f663366306161643335613632653e653f667a")?j("Correct Flag"):console.log(f('flag{N0t_Th4t_E4sy}')("616b66607c37333662363f3036613f3765643f3f663366306161643335613632653e653f667a"))}

We simply replaced the Wrong Flag message with the output of the function to get the flag, and since we don't know the actual value we put it in the false side of the condition (to be executed obviously) ... let's rebuild the apk and install it again.

No response because the result will appear in the console, we need to get the PID of the app and this can be done by frida-ps -Uai :

Now let's see the log output using logcat:

Hit the CLICK ME button and ....

Script Link
YUCK!
We found the Flag!!
Here is our flag