Hey folks, so here’s my writeup for KookSec’s “Lord Of The Root” VM from VulnHub.
WARNING! – I always “plan” on doing a nice short writeup, then just drag it out with possibly OTT details….which i think i’ve done here too. But the purpose of this blog is more for me to refer back to, and understand how something works. And i’m finding if i don’t go into detail….i don’t understand it. Consider yourself warned! 😉
After firing it up, first things first, whats it’s IP. Well Hello Mr Bond….err i mean 192.168.56.100! Now….NMAP time.
Hmmn, not much, lets do a bigger scan of 1-5000 ports, and get a little angrier with a T4 switch.
But i got the same results. So either theres something running on a much higher port, or something funky is going on. Well seen as this is a VulnHub challenge, lets assume the latter 🙂
Lets have a look at that SSH port.Ah ok, so still a normal SSH connection, but with a nice banner.
“Knock Friend To Enter” – “Easy as 1,2,3”.
This sounds like a technique i’ve heard about, called Port Knocking, where you “knock” or “ping” a port, or a series of ports, and if the sequence is correct, “something” happens, usually, it allows the IP address of the knocker access to some other service ports.
As i mentioned, i’ve never played around with this, but i am aware of another VulnHub writeup i read by a friend (Hey Knapsy!) which involved port knocking.
So i had a quick read of that, then ended up firing off the following 3 commands (yes i know i could of scripted it, but hey….i’m lazy!)What we are doing here, is using the hping3 command, pointing it at our IP address, then specifying a port number (e.g -p 1) then how many “pings” to send (in this case just the one e.g -c 1)
Do this for each port 1, 2 and 3, and now lets perform another NMAP scan, see what turns up!
And…..Same result….hmm. K. At this stage, i kept cycling through my “knocking” pings, including knocking on port 123….1,2,3 times. But no luck. Maybe something IS open….but not in the “top ports”.
Lets do a scan for ports between 1-5000 again.AHA! Port 1337, and it looks like a HTTP port, so lets have a browse to it.
Err….K. I checked a few things here including the source code for the page, even found the original file off MemeBase.com and compared the 2 files. The same, so theres no hidden stego stuff going on here.
Next i fired up DirBuster.(I always use directory-list-2.3-medium.txt, if theres something to find, it usually finds it)
First thing it finds, is a /images/ directory, containing the following.
Again, some “meme” pics related to LOTR.
DirBuster didn’t find anything else of interest. I also decided to check robots.txt…worth a shot.
OK, so it didn’t give me a robots.txt file, but did display one of the photos i found before (hipster.jpg)
If there is no robots.txt file on a server, what do you usually get? A 404 not found page, but in this case i’m getting the pic above. And going off the phrase in the pic “We can’t go this way”, maybe this is a personalized 404 page. Lets test it with a random path on the web server, using a random word….like…i dunno “supercalifragilisticexpialidocious“
AHA! Same thing, so this must be a custom 404 page. Lets view it’s source.
Theres the link to our photo, and also a HTTP Comment Tag.
From experience i guessed this was a Base64 encoded string, so i tried decoding it.Hehe, cute. Lets now decode the new string it gives us.
Aha! Nice, we have a new url path to try.
OK, so we have a login page. First things first, lets try a quick ‘ OR 1=1 — in both fields……nothing, just an error saying “Username or Password is invalid”. Quick check of the page source, cookies and another DirBuster scan from /978345210/ didn’t find anything of interest. I’m gonna guess this is some form of SQL Injection, as CTF and boot2roots don’t usually involved brute forcing. Time to let SQLMap have a look at this page.
Before we do that though, we need some “values” for SQLMap to test on, so BurpSuite is used to capture the POST data thats sent when we hit “Login”, as well as the response from the server on a failed login.
So here we can see, the “POST Data” thats sent to the server.
And we already know the response from the server is.
Username or Password is invalid
So with these 2 items, we can use SQLMap to see if theres anything vulnerable, using the following command:
OK, looks like it’s found that the “username” field is vulnerable to a time-based blind SQLi, and it’s detected it’s likely MySQL, so we can skip testing for other DBMS’s.
So now we’ve found it’s vulnerable, lets try and get some info out of it. First we want to know the name of the database being used by this login page, so lets expand our SQLMap command, to specify to find the current database and also specify “MySQL” as the DBMS type.
Now with a “time-based blind” SQL Injection, what SQLMap does is send various SQL queries to the database, which test on something, and if that test is true, it will pause for 5 seconds, and if false, continue on. So in this example, it finds the name of the current database in use.
As you can see it’s found that the database name is “Webapp”. It’s found this out by sending a series of queries like below. (Note the below are NOT actual SQL queries, but rather my interpretation of what it’s doing)
If the name of the current database begins with "A" then pause for 5 secs, otherwise continue on. RESULT = False....so it skips.
If the name of the current database begins with "B" then pause for 5 secs, otherwise continue on. RESULT = False...so it skips.
If the name of the current database begins with "W" then pause for 5 secs, otherwise continue on. RESULT = True...so it sleeps for 5 secs, then SQLMap detects this pause, and knows the current database begins with "W".
Now...if the name of the current database's second letter begins with "a" then pause for........
Hopefully you get the idea. If it detects a pause, it knows it’s right, records the result and continues on. This process can take a while obviously, but it’s a excellent way of pulling info out of a SQL database, when you are “blind.
Now we specify the database name, and include a –dump to dump all the info from that database.
Excellent! If we login to the web page with any of these credentials, they work, but they just take you to a profile.php page, which shows the 3rd image we found earlier…nothing else.
But if you try logging in to the SSH server using these credentials, only one works (smeagol), but we at least now get a shell!
But, it’s a limited shell, so the next obvious step is to escalate our privileges to root. My usual starting process for this is to download a enumerations script, to help gathering any “juicy” info. Theres 3 i currently use:
They all do SOME similar things, such as pull version info for installed services, find “interesting” files, try and read /etc/passwd and /etc/shadow etc. LinuxPrivChecker also suggests some possible exploits. It’s not upto date, and the suggestions sometimes don’t work, but it’s a good starting point.
I’ll just be focusing on LinuxPrivChecker for this writeup. A quick wget downloads it to the vm from my local Kali VM, then we run it using python.
At the end you can see a list of possible exploits. If we scroll through the full output we find a couple of interesting items.
First is a list of files/directories that have the SetUID or SetGID attributes set on them. This basically means you can run the file with the permissions of the owner.
Theres 3 files that have this attribute set, and the owner is root. The files are also…not standard files.
The second interesting item, is that in the list of processes running as root, is mysqld, so the MySQL process that hosts the database we running an SQLi attack againest is running as root, which isn’t normal. Usually it’s running under it’s own restricted “mysql” account.
At this point i’d like to point you to the page on VulnHub for this VM where it states.
There are two designed methods for privilege escalation.
OK! This is useful, particularly for me, as i’m USELESS with binaries, debugging, reversing and buffer overflows etc….So i ignore the 3 binaries with SetUID attributes set, and focus on the fact that MySQL daemon is running as root, and the suggested exploit that LinuxPrivChecker has given us.
First we need to try and get the MySQL “root” account password. This is saved in a database named “mysql” and in the table “user”. So we simple alter our SQLMap command to try and get this info. We also include the switch -C user,password, which only gives us the info from those 2 columns (the user table contains LOTS of other columns todo with access rights, but we only care about the user and password).
And there we have the MySQL “root” users password.
The exploit is here https://www.exploit-db.com/exploits/1518/, i’m not going to go into the full details, but follow the simple instructions to give it a go. But basically, it gets the MySQL database to run a system command, and because it’s running as root, could be a winner.
First we download the exploit C code, and write it to a file on the vm. (I named mine 1518.c…which is the exploit ID from ExploitDB)
On the ExploitDB page is also shows how to use the Exploit. In this example, what it will do is run the id command, and pipe the output to a temp file. Which you can check to see who the id command was run as. Here’s how i used the exploit:
- Created the file 1518.c containing the exploit code on the vm (Done above).
- Compile the code using gcc
gcc -g -c 1518.c
- Login to the MySQL server using the root account.
mysql -u root -p (Enter password when prompted)
- Select the mysql database to work with.
- Create a new table to store the exploit in.
create table myexploit(line blob);
- Insert the compiled exploit file into the table.
- Output the contents of the myexploit table into a file in /usr/lib/mysql/plugin
Note – I had to slightly change my code compared to what was listed in the exploit, as output the file to just /usr/lib as detailed in the exploit didn’t work, hence the change to /usr/lib/mysql/plugin
- Create a MySQL function named “do_system” which uses the above code.
- Check the created function exists.
- Specify the command we want to run, which as mentioned will run as a the mysqld user, which is “root”. In this example, we’ll just output the result of the id command, to confirm we are running as root.
- Now we switch back to a shell prompt.
- Finally, lets read the contents of /tmp/out, which should be the results of the previously run id command.
Excellent! So our exploit works, and we can run commands as “root”. At this stage, we could just change the previous command to list the contents of the /root/ directory, see if theres a flag file, then cat the contents of it. But i still want a proper…proper root shell 🙂
After a bit of Google searching, i found a nice simple way of doing this, following this article. This details using the same exploit we have already use, but then using some simple C code, which launches /bin/bash, compile it, then finally give it the SetUID attribute. So when we run it as our normal use, it launches a shell (/bin/bash) but running as root.
So first up we create our C code, named rootshell.c, which simply launches /bin/bash.
Then, back in the MySQL database, we compile it, by altering the previously created ls command
select do_system('gcc -o /home/smeagol/rootshell /home/smeagol/rootshell.c');
Then we set the SetUID attribute.
select do_system('chmod u+s /home/smeagol/rootshell');
Done! So we now have our “rootshell” binary. Exit MySQL, and run it.
BOOM! We are now root 🙂 A quick ls to find the flag file, and view it’s contents.
REALLY loved this VM, had some cool challenges, and i’ve learnt a few things, which will be VERY useful when i do my OSCP.
I am also going to work on the 3 binaries we found, and understand how to figure out what they do, and how to exploit them, and do a writeup for these too. Which is even easier now we seem to of found the source code for the files (shown above).
Cheers folks, thanks for reading.