TryHackMe | Madeye’s Castle Writeup

Anubhav Uniyal
10 min readFeb 2, 2021

This is my first write-up, so excuse me for any mistakes.

You can find this room here: https://tryhackme.com/room/madeyescastle

Overview

This is a medium rated boot2root box, made by TryHackMe user madeye. This is a very interesting box with some new concepts. Firstly, this box uses a method called Virtual Domain Name Hosting (which I go over, briefly in the associated section). Secondly, Mutating a word-list using different rules and getting the password. Exploiting a binary through GTFObins, to escalate privileges. And finally, getting the root flag by exploiting a system call of a SUID binary. Also, the SQLi can’t be done using an automated tool, so you’ll have some trouble if you’re not used to manual injection. All in all, an awesome box which I had fun rooting. Without any further ado, let’s get into it.

Let’s Break In!

First things first, always start with an Nmap scan:

sudo nmap -sS -sV -sC -oA nmap/castle 10.10.137.43 -vv

Here -sS: SYN Scan, -sC: for “Safe” Scripts, or default scripts, -sV: for version enumeration, -oA: output in all format(Greppable, XML and default Nmap output), -vv: for verbose.

We see that 4 ports are open in this box. While the Nmap scan is running, let’s visit the service open on the port 80, which is a reserved port for HTTP. On opening the website, we are greeted with an Apache server default page.

Nothing interesting here, so let’s run a directory brute force. Any brute forcing tool will work, I prefer to use Gobuster.

gobuster dir -u http://10.10.137.43 -w /usr/share/seclists/Discovery/Web-content/raft-small-directories.txt -x php --threads 50 -o gobuster.out

Here, dir: to specify directory brute-forcing, -u to specify the target URL, -w to specify the word list, I use raft-small-wordlist. It is included in the sec-lists over at GitHub, which you can clone in your own distro, and I recommend that you do, because they are very useful. Otherwise you can just download this particular word list from here. -x: to specify the extension. This switch will add a .php after every word to check if a file also exists. You can specify multiple file types, separated by a comma. — threads: to specify the number of requests made at a time. Use this switch very cautiously, as in the real world, huge number of request to a website will get you blacklisted. Since this is a virtual environment, it shouldn’t be a problem. -o: to specify the output file.

Gobuster got a hit on a directory with the name backup. Let’s check it out.

On visiting the directory we see that we are not authorized to view the root directory. So, let’s just brute force this URI to see if we are able to find something interesting here.

gobuster dir -u http://10.10.137.43/backup -w /usr/share/seclists/Discovery/Web-content/raft-small-directories.txt -x php --threads 50 -o gobuster.out

We see that we got a hit inside the backup directory, we can see a directory called email. On visiting the directory, we see its a text file, with some interesting information in it. Its a conversation between two people, talking about virtual hosting. There is also a link provided at the bottom of the document if you want to know what virtual hosting is, or more specifically what virtual domain name hosting(that is used in this box) is, and how it is used. But, in simple terms, virtual domain name hosting is a method for hosting multiple domain names on a single server. Why is this used, because you can host two(or more) different websites using the same IP address, saving cost of having to buy multiple IP addresses.
So, we know that this particular box is using virtual domain name hosting and that the name the of other domain is hogwarts-castle.thm.

Now, to visit this particular website, we have two options(that I know of):
1. You can proxy your traffic through Burp, or any other proxy of your choice, make a request to *THM Box Ip* (10.10.137.43 in my case), intercept the traffic, and change the host header from *THM Box Ip* to hogwarts-castle.thm. The drawback with this method is that every time you want to make a new request you have to change the host header to the domain name, or else your browser will throw an error as it won’t find the host.
2. The Second, and the easier method, is to edit your hosts file. If you are using a Linux based distro, your hosts file will be located in the /etc directory. Open you /etc/hosts file in a text editor and in the IPv4 section add the *THM Box IP* and the domain name, separated by a space. Now, whenever you enter the domain name, your browser will automatically route you to the desired location.
Let’s go to hogwarts-castle.thm.
When we go to the website, we are yet again greeted by the same default webpage. It seems we made a mistake somewhere. On reading the email again, we see that the actual domain name granted was hogwartz-castle.thm instead. Making the required changes in our hosts file, and visiting the domain again, we are greeted with a login page.

Doing a simple SQLi check on the webpage using SQLMap shows that the page might be SQLi vulnerable, but there was no success. So, I decided to try some simple payloads on my own. Using the payload


”user=admin’ or 1=1 --&password=admin”

we get a response back saying that the password for “Lucas Washington is incorrect”. The username was leaked. This means we are on the right track. Wonder why the SQLMap didn’t work. I decided to give SQLMap another try. Still no luck, it would appear that the queries sent by SQLMap ̶a̶r̶e̶ ̶b̶e̶i̶n̶g̶ ̶b̶l̶o̶c̶k̶e̶d̶ ̶b̶y̶ ̶a̶ ̶W̶A̶F̶(Web-Application Firewall)(They weren’t actually). SQLMap provides us with an option to get around this by adding --tamper=space2comment in our SQLMap request.
After bashing my head against the wall with SQLMap, I understood that this technique won’t work. So, I decided to take a different route.

Lets take a step back and see what else we found using Nmap. We can see that port 445 is listening, which is the default samba share port. I connected to this port using smbclient, using anonymous login. But it failed, so I used Nmap scripts to enumerate this port further. Using Nmap we found that the shared folder was named samba share, and not anonymous. Logging in through smbclient, we see that two documents are shared “.names.txt” and “spellnames.txt”, we get both of those documents for further inspection.

One document contains “spell names” as the name suggests, possibly passwords for ssh, and the other document contains two names Hagrid and Hermonine. This I thought was a typo, correcting the spelling and trying to brute-force the SSH through the password list using Hydra was…. unsuccessful. Trying the other 2 usernames, nothing happened. At this point the only feasible option we have left is somehow exploiting the SQLi. Since SQLMap failed to do that for us. I decided to go the manual route. SQLMap already provided us with a payload, so I decided to try it using burp repeater. Using the payload, we see that payload values are reflected in the output, it is clear that we can control the output, which means we can pass functions to it and get data back.

Now this part took me a loooooot of time, not that this was insanely hard, but just because I am not very good at SQLi’s. Currently.
Anyhow, after some hours of researching I finally constructed a payload


‘ union select group_concat(password),2,3,4 FROM users-- -

This payload reflected the password hashes of different users in the database. Finally. Running one of the hash through Haiti, we get to know that these are sha-512. Trying to crack the hashes through john and using the rock you word-list, we find no passwords. Looks like we missed something. So I ran my SQLi payload through burp intruder, replacing “password” with some common server side variable names, using the default burp wordlist, and sure enough we got some more information, user names, and notes. On further inspection of notes, one thing stands out. The second user has a hint to his password.


My password used best64

Huh, the name of this user was “Harry Turner”. Inputting this name in the user field of the login form, displays the same message. Which would mean that the second hash of the password list, is this users password. best64 sounded a lot like base64, so I converted each line from “spellnames.txt” to it base64 counterpart and used this list to crack the hashes, but that was Plain-wrong (sorry for the awful pun). After some Google-fu, it was clear that best64 is a mutation technique, and that hash-cat already has it. Using the pre-built best64 rule in hash-cat on the password, we crack it.

The password has been redacted.

Finally logging into the website, we found that Harry is reusing his passwords. Thanks to the very conveniently placed message. This means we got access to the machine. Upon SSHing into the machine we are greeted by a message.

Also, we got our first flag.

Next, escalating priveleges. Running sudo -l we see that user hermonine can run pico with escalated privileges. To GTFObins we go. Following the instructions there, we are now user hermonine. And, we got the second flag. That was easy.

And if you are wondering why your shell and my shell look so different, I just upgraded this shell using

python3 -c ‘import pty; pty.spawn(“/bin/bash”)’ 

And you’ll be back on track. If it still feels weird, do this


stty rows 13 columns 136
reset

Now, for the root flag. Since, we don’t know the password for user hermonine, sudo is out of the question. Next logical step will be to find a file with a SUID bit set.


find / -perm -u=s -type f 2>/dev/null

Here, /: specifies the directory from where to begin searching(root in this case), -perm: only show files with a particular permission, -type: specify what to find, 2>/dev/null: This option is a little complex in its entirety, so just understand this, it will hide any error during the execution of this command.

Everything else is just routine, except a file named swagger. Executing this, it asks us to guess a number, and then outputs a random number if we are wrong. I saw this and immediately my mind went to a buffer-overflow exploit . But to confirm my thesis, I need to see the internals of this program. So I exported this file to my machine using netcat, I usually prefer python, but it was not working correctly on this machine for some reason.
I opened the file using Ghidra.
It would appear that if we guess the number correctly the program makes a system call to *uname -p*. It appears that the binary is can be exploited using spoofing techniques. But, that means no buffer-overflow. Aww, sad programmer noises.

The main issue in exploiting this binary, lies with guessing the random number. After some researching, I found out that the function “rand()” used for random number generation was unsafe, as it displayed the same number if called in quick succession. This was very easy to confirm, using bash.

for i in {1..5};do echo 1 | ./swagger ; done

With that out of the way, we can start fooling the system. First, we create a file called uname (because the program calls a system file with the same name) in the same directory, with


cat /root/root.txt

as the payload. We give this file executable permission. This will output our flag. We add our pwd(present working directory) to the beginning of PATH environment variable, so that system will first check for the uname file in this directory, using


export PATH=/srv/time-turner:$PATH

Now, we will execute the program passing any number to it, grep the output number, and pass it back to the program, so that it successfully executes.


echo 0 | ./swagger | awk ‘{print $5}’ | tail -1 | ./swagger

This command will help us achieve that. I can’t show you the output of this command as it contains the flag. But trust me, this works.

This was my first write-up, so I hope you enjoyed it. If you have any suggestions, do let me know in the comments.
Have a nice day.

--

--

Anubhav Uniyal

DevOps Engineer. Cyber Security Enthusiast. Always up to solve a mystery. All views are my own