> For the complete documentation index, see [llms.txt](https://khalid-emad.gitbook.io/cyber-sec/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://khalid-emad.gitbook.io/cyber-sec/arab-regional-ctf-2023-cyber-talents.md).

# Arab Regional CTF 2023 (Cyber Talents)

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

<figure><img src="/files/8JkkTWrOnPcKwttFqY5b" alt=""><figcaption></figcaption></figure>

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:

<figure><img src="/files/O8uGAGPjF1sKLIKCdLAv" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/7yBzdhWpq2362DcXw923" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/QUvO1I8UwF6HY62JFFFn" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/cNjh5F9NvHeLgSuCGQzz" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/m6Mh7LFbq4OJ6pu5z4bm" alt=""><figcaption></figcaption></figure>

Until we see this endpoint:

<figure><img src="/files/LjXpwg3McFKcKjGaBMk0" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/F8TMFq7zegb4TjprryHy" alt=""><figcaption></figcaption></figure>

Now what we want ... admin? flag? returning to the challenge description :&#x20;

<figure><img src="/files/76z2VO6Pe0VQFe5vCH94" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/I2xw5o0C6Uym7vhx6KBM" alt=""><figcaption></figcaption></figure>

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` .

<figure><img src="/files/aaxAukeUHHElFsEaSWdQ" alt=""><figcaption></figcaption></figure>

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:

<figure><img src="/files/t4UOilETcKOYd9Xtww4H" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/4UFjRZcRdw5cbZFUI8re" alt=""><figcaption></figcaption></figure>

[Script Link](https://github.com/khaled1000emad/CTFs-With-Python-Scripts/blob/main/Arab-Regional-Notes-Harbor/PWN.py)

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

<figure><img src="/files/urjKaNcgedViSqdfiPev" alt=""><figcaption></figcaption></figure>

#### RenderSaas (Hard)

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

<figure><img src="/files/GFaA7mLbq2sN7nku1czz" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/7jCQNH9PUzYgcVdDDgUa" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/I2yapnKSgm8nm7QRiPsn" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/V5sqBd8Tu1SHeh9V1POo" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/uWiUuehTPKtkZpiwmKdE" alt=""><figcaption></figcaption></figure>

So let's register our user

<figure><img src="/files/r80YUByk5RMWg7OpoB1l" alt=""><figcaption></figcaption></figure>

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!"

<figure><img src="/files/zdVVl8v0d7qhUfp49AOb" alt=""><figcaption></figcaption></figure>

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

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

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

<figure><img src="/files/bp8QuvzDaKYKePlXKnZk" alt=""><figcaption></figcaption></figure>

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 :&#x20;

<figure><img src="/files/AeeOlTxwbvKt6x7YVJ5M" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/mbHeK5gKucWQtgKpsXVV" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/vrMX5pE9Xd0HUWhSNX2T" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/CrMt0bE6Ihsl1ROdbLSc" alt=""><figcaption></figcaption></figure>

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` :&#x20;

<figure><img src="/files/W9HyPoZWqQYer244wSo0" alt=""><figcaption><p>YUCK!</p></figcaption></figure>

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":

<figure><img src="/files/JiJQ0WLC6WAgbde50rR5" alt=""><figcaption><p>We found the Flag!!</p></figcaption></figure>

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

{% code overflow="wrap" %}

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

{% endcode %}

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:

{% code overflow="wrap" %}

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

{% endcode %}

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.

<figure><img src="/files/uBHXdQnN7yApyfXKWWTr" alt=""><figcaption></figcaption></figure>

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` :&#x20;

<figure><img src="/files/FGVPC7DbJlNH1tVQKTtW" alt=""><figcaption></figcaption></figure>

Now let's see the log output using logcat:&#x20;

<figure><img src="/files/mMaWs0Jf9o49qgjLKesJ" alt=""><figcaption></figcaption></figure>

Hit the `CLICK ME` button and ....

<figure><img src="/files/gozt722vORwO0i3jPv2U" alt=""><figcaption><p>Here is our flag</p></figcaption></figure>
