Arab Regional CTF 2023 (Cyber Talents)
Last updated
Last updated
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).
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 :
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:
This will execute the ls
command through the child_process
module , and the result is:
We can now read the flag file easily.
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:
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?
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:
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 ....