Madeye’s Castle | TryHackMe
Hola Amigos !!
In this blog, we are gonna hack into TryHackMe’s Madeye’s Castle. This box is rated Medium, but I enjoyed it to the fullest.
Before we begin, let me tell you what we are going to do in here:
- First we scan to find a VHost.
- Then we do some SQL injection to dump some data.
- Finally we make our entry to the box.
- After that, we do a horizontal privilege escalation to a second user.
- Then a classic binary exploitation to make our way to root.
With that said, let the show begin.
Let us do a quick port scan to get a rough idea about what ports are open.
We have ports 22, 80, 139, 445 open.
As you might have guessed, we have OpenSSH 7.6p1 is running on port 22, Apache httpd 2.4.29 on 80, Samba smbd on ports 139 and 445.
That is all we need to know in the scanning phase. Let us move to enumeration.
The very first thing we can do with Samba is to check the accessible file shares.
I am using a tool called enum4linux for the purpose.
We have three shares on Samba : print$, sambashare, and IPC$.
Out of the three, we can only access the one called sambashare.
Let us see what that got for us.
We have two files here: spellnames.txt and .notes.txt. Let us view their contents.
The spellnames.txt looks some sort of wordlist to me. And the other one gives a hint of not using the wordlist rockyou.txt.
Looks like that is all we can get from Samba.
Let us move to port 80 (HTTP) now.
Visiting the IP by the browser, it just shows us the default apache installation page.
However, You should always check the source of a page :P
Now this is interesting. We now have a virtual host : hogwartz-castle.thm.
Add that to your hosts file.
Let us check the host now.
Things are getting more interesting!! We have a login page now.
The very first thing we can do when we encounter a login page is to check for SQL injection.
Username : admin’ or 1=1; — —
Password : password’ or 1=1; — —
Now you might be thinking, how this particular inputs are going to do a magic. Well let me explain that to you.
When you fill the username and password fields and hit enter, the server is going to pass them to the underlying database to check the credentials. An example query will look something like below:
SELECT * FROM users WHERE username = ‘YOUR USER’ AND password = ‘YOUR PASS’;
Now you might have figured that out. In the username field, if you type admin’ or 1=1; — — , the single quote will prematurely end the SQL query. The next OR connector connects an additional 1=1 query which is always true. The rest part is commented out using two dashes. Note the spacing between the dashes, it is important.
The password field input can also be understood in the similar way.
Simply put, the above inputs can help us in bypassing the login functionality.
Now, let us check that out.
Seems, there is a SQL injection vulnerability.
Now let us dig deep into the exploitation. That is what our guy says. XD
Since, we have already found SQLi, we can use automated tools like sqlmap or something like that.
But I am going to show you how can you manually exploit this sort of vulnerability. This way, you will know what exactly is going on behind the scenes.
Let us capture the HTTP packet in our burp proxy and experiment with it.
First, we send the packet to the repeater.
Now you know, the SQLi vulnerability is only in the user parameter, not in the password.
Let us now find the number of columns in the query.
Usually I do this with Order by technique or NULL technique.
As you can see, with order by 1 we are getting status code 200 from the server. Let us increase the value till we get an error from the server.
When we increase the value to 5, we are getting a 500 (internal server error). That would mean the original number of columns are 5 – 1 = 4.
Now it’s time to check for the datatypes in each column for data dumps.
We get a strange response here. It is saying The password for None is incorrect! None.
How about we try integer values instead of the NULL values!!
This is interesting !!!
The values 1 and 4 are reflecting on the response packet.
Let us now try some different thing on it.
As you can see, we have replaced 1 with another SELECT statement that concatenates two strings. And the result is shown in the response.
Now we need to find the DBMS type and version.
I tried some common DBMS like MySQL, PostgreSQL, Oracle DB and MSSQL. None of them worked except for SQLite (all thanks to the DBMS Professor of my University that I know how to check DBMS version :) )
It is clear that the SQLite version is 3.22.0.
Let us check for table names now.
SELECT tbl_name FROM sqlite_master
Looks like we have an interesting table called ‘users’. Time to determine number of columns in it.
SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='users'
It has 4 columns:
- name : string
- password : string
- admin : integer
- notes : string
Let us now dump all the data in those columns.
We will be using group_by() to extract all data in a column seperated by a delimeter.
SELECT group_concat(name,’~~’) from users
All data from name column has been dumped. You can now save them locally and parse them in new lines.
You can dump all other data from different columns and save them.
The line 2 in particular seems interesting. The user is harry and the note says My linux username is my first name, password uses best64.
By best64, it probably means hashcat’s best64. But where is the wordlist ??
REMEMBER! We have a wordlist from Samba enumeration.
Let us use that and apply hashcat’s best64 rule.
Now we leave the work to our friend Hashcat to crack the hashes.
Our hash is cracked.
Time for entry to the box.
SHELL AS HARRY:
Since we have password and valid username for the box, we can simply SSH into the box.
And that is it, we are in.
PRIVILEGE ESCALATION TO HERMONINE :
User Harry has a sudo right to run /usr/bin/pico as Hermonine, which is just a symlink to /bin/nano text editor.
With this, we can simply get a shell as Hermonine.
reset; sh 1>&0 2>&0
Great! We have a shell for Hermonine.
PRIVILEGE ESCALATION TO ROOT:
Let us begin by checking for SUID biniaries.
The /srv/time-turner/swagger binary looks odd particularly.
The binary is owned by root.
When we run it, it asks for a number. Then it compares it with a random number.
TIME FOR SOME BINARY EXPLOITATION :
Since we have a SSH credential, let us download the binary to my Kali machine via scp.
Now let us fire up our friend GDB to look for what is going on.
We have loaded the binary into GDB, set a breakpoint to main and hit run.
If you know a bit of x86–64 linux assembly, this will make perfect sense to you.
If you do not, let me break the things to you.
First it sets up the function prologue. Then it calls the time function with argument of integer 0. Basically what this does is return the seconds till epoch (no of seconds from 1st Jan 1970). And this value is argument for another function call srand. This function just sets up a seed for a pseudo random number generation. Why it is called pseudo? because the random number generated is not fully random, it depends on the seed value, i.e. the seconds till epoch. Since every second, the epoch value is unique, the number thus generated may be called random. Then, the rand function is called which returns a random integer based on the seed. Then it prints some strings to the screen. After that, it takes input from the user and compares it with the random number.
If the strings are not equal, the code flow move to another part where some strings are printed and the program ends.
But, if they are equal, another function impressive is called. Now we do not know what this function does. Let us disassemble it and analyze it.
The function first sets the UID and GID to 0. Then it prints some strings. After that, it runs a system command. It is now important for us to know what system command is running. Let us examine that memory location.
As you can see, it just run uname -p.
Notice that it is just uname. No full path is given. That means we can manipulate the PATH variable to run our version of uname.
But for that, we first have to get beyond the random number comparison. How can we do that?
If we can generate the same random number as the binary and feed the output to the binary we might me able to go beyond the comparison.
I have created this code that does the same thing as the binary (generates a pseudo random number that is seeded on seconds of epoch).
I compiled the code, run it and piped it’s output to swagger binary.
It worked as expected and we successfully hacked time. XD
Now let us do it on the remote box to get root.
First I compiled my code. Then I created a file /tmp/uname where I simply put the command to change password for root, using chpasswd. After that, I gave execute permission to it and set /tmp to the start of my PATH variable. Now when I pipe the test binary’s output to swagger binary, the random number comparison is bypassed and it runs uname. Since uname is found in the first entry of PATH variable i.e. /tmp, so /tmp/uname is executed and password for root is changed.
Now we can simply switch user to root.
And Finally we get our root shell.
So that was the Madeye’s Castle from TryHackMe. I like this sort of boxes (the binary exploitation ones =) ).
Thank You for reading this far. Hope you liked the write-up. I will see you in the next one. Till then :