WriteUp: GamingServer

Once again, we will walk through an easy ctf challenge from the site TryHackMe. This challenge is free so if you have an account on the site, definitely give this challenge a try!

Let’s get to it!

First things first, deploy the machine and run an nmap scan for open ports.
nmap -sS -sV <ip_address>

From the scan, we get two ports we can play with: SSH and HTML. Since we can’t do anything about ssh yet, time to go hunting for more information.

Navigate to the ip address in a web browser. We are greeted with a webpage for Draagan which I can only imagine is a MMORPG in this scenario. The page itself doesn’t look to have any useful information but let’s check the source page.

Interesting. Looks like we may have a username and proof that lorem ipsum does not make for a good website. Save the name to your notes for later.

But we still need more information.

At this point, it is not a bad idea to run a directory search on the url. I will use gobuster for this writeup.
gobuster dir -u <url> -w <wordlist> -t 64

There are a couple of places we can check. We will check the uploads folder first. Three files are present there. The first file looks like a list of passwords. Useful. We can copy that to our computer using wget.
wget <url_path>

The second and third files are more of a misdirect though personally I enjoyed reading the second file.

We are done in this folder so let’s go to the secret folder where we find a very interesting file. A private ssh key! Simply download that file using the wget command.

Now, we have a possible username and a private ssh key. Let’s see if we can log into the target server.
ssh -i <private_key> <username>@<ip_address>

Uh-oh! We need the private key’s passphrase or the user’s password! Fortunately, we have a list of passwords from the webserver! We can check with Hydra if any of theses passwords belong to our user.
hydra -l <username> -P <password_file> ssh://<ip_address>

Nothing.

We still have another option though. Let’s try cracking the private key’s passphrase. We will be using the JohnTheRipper suite for this.

I won’t go into to much detail but if your computer does not have JohnTheRipper (JTR) installed, you will have to install it manually and either setup an alias to the program or change your “.profile” in your home directory to include the path to the program in your “PATH” variable. Generally the path will be “/usr/sbin/”. Else the next steps will have to be performed from the folder the programs are installed.

In addition to having JTR, you will need a program called ssh2john. For whatever reason, this is not included with the suite. I had to download the program and move it over to where my JTR install is. It is a pain, but worth it.

Once you have JTR and ss2john installed and accessible, run ssh2john on the private key and save the output hash as a file.
ssh2john <private_key> > <output_file>

Great, we have the hash! We can use john to crack the hash and get a passphrase if it exists.
john -wordlist=<password_list> <hash_file>

We got a passphrase so let’s try logging in again using the private key through ssh. When asked for the passphrase, we type in our passphrase and we are granted access to the machine!

Getting the first flag is perhaps the easiest part of this whole challenge. Use the ls and cat commands.

First flag done! One more to go!

Getting the next flag is not straightforward and I did a little digging to find it. If you run the groups command, our user is part of the “sudo” group but that is useless to us. We don’t know the user’s password which sudo requires. If you check the system crontab and the user’s crontab, there is nothing we can exploit.

This isn’t looking good. Let’s look back at the groups our user is a part of.

Notice that our user is part of a group called “lxd”. This let’s us know that this computer can use linux system containers . If you go to GTFOBins, you won’t find an entry for lxd or lxc, the command used to interact with lxd.

Try googling “privilege escalation with lxd” instead. There are a few articles that explain how to exploit lxd to gain root privileges. The easiest way to exploit lxd would be to create a container from an image stored on the internet from the target machine. However, this will not work for us because our target machine cannot reach out to the internet.

Back on your machine in a separate terminal, you will need to build an image server that will be uploaded into your target machine and then imported by lxc. From there, you can mount the root of the target machine to the lxc container. Once that is done, you can get a shell to the container and navigate to the final flag.

Sounds complicated?

I agree and my explanation probably does not do it justice but I recommend following this blog by HackTricks for the exploit setup. When ready to upload your files to the target machine, use the scp command.
scp -i <private_key> <source_file> <user@ip_address:destination>

Once the files have been uploaded, go back to the target machine to import the image, create a container, and gaining access to the container. You should be root inside the container.

Notice something weird in the above screenshot? Running the pwd tells us that we are in “/root” but nothing is here! That is because we are in the container’s “/root”. We mounted our target machine’s root folder under the container’s “/mnt” folder. Navigate there and you will see a folder called “root”. Dive deeper to find the root flag.

And there you have it! This is a rather long and involved ctf to complete for an easy level challenge but it is worth taking time to go through as it introduces other mini-challenges (JTR) along the way. Hope this guide helps.

Until next time!

WriteUp: Tartarus

This relatively easy ctf challenge can be found on the site TryHackMe.

This challenge did take me a little while to figure due to overlooking a key step but it is definitely a good hacking challenge for beginners. Let’s dive in.

Part 1

Once you join the room and deploy the machine, scan it for any open ports. In this example, I use nmap.
nmap -sS -sV <ip_address>

FTP, SSH, and HTTP are open for us. We will check FTP first to see if we can login anonymously. When asked for a password, simply press the ENTER key.

And we got in! Now for a little snooping. Using the ls command shows us one file call “test.txt”. Reading it gives us nothing. Using ls -a on the other hand reveals a weird directory. Enter that directory and rerun ls -a. Another weird directory. Keep going until you run into an actual file. After downloading the file, read it and make note of the path you see.

Before going to our newfound path, let’s explore our HTML port. If we go to the default webpage, we’re greeted with the default test page from Apache. Checking source code reveals nothing new. We will use a directory enumeration tool to find if any other files or folders exist. In this example, I use dirsearch.
python3 dirsearch -u <url> -e html
(In the screenshot, I am using an alias to run the command.)

The search gives us a status code 200 for “robots.txt”. Visit that page and you’ll see another path we can explore. Navigate to that path. There are two files available. One looks like a bunch of passwords and the other has possible usernames. Copy the files manually or with wget.
wget <url>

After copying those two files to your computer, you can try exploring more from our current angle but there is nothing else. So, let’s go to that path we found in the FTP file.

You’re greeted with a login page. We can attempt to guess the credentials but there is a tool for that. We will use Hydra to check for credentials using the two files we just copied over to our computer. Hydra should come default with Kali Linux but if you are an intrepid soul using a different Linux flavor, you can install it from here.

To use Hydra against a webpage login, you need three things: usernames, passwords, and a login error message. Get the login error message by entering a bogus credential on the webpage.

We will get the error message “Incorrect username!”. Now we try our attack.
hydra -L <username_file> -P <password_file> <domain/ip> http-form-post "<login page>:username=^USER^&password=^PASS^:Incorrect username!"

There are a lot of results for just one user! We need to narrow it down.

Try one of the combinations on the login page. More than likely, you’ll get a new error message, “Incorrect password!”. Let’s rerun Hydra but with a couple of changes.
hydra -l <username> -P <password_file> <domain/ip> http-form-post "<login page>:username=^USER^&password=^PASS^:Incorrect password!"

Bingo! We have valid credentials! Login in and there is an upload page ready to be exploited. But what to upload?

Ultimately, we want to get on the target machine to get those flags so let’s upload something that will give us a reverse shell. Pentestmonkey has an excellent file called “php-reverse-shell.php” that will do just that! Download it and edit it so that it uses your computer’s ip address and the port you want to listen to.

Upload the edited version. You’ll see that the upload was successful but trying to navigate to your uploaded file gives you an error. What gives?!

We assume the file is definitely uploaded so we will run our directory searching tool again to look for other folders.

In doing so, we discover an “images” folder. This path holds our uploaded content. Before opening the file, go back to a terminal and prepare your end of the reverse shell connection using netcat.
nc -nlvp <port>

Now go to your uploaded file from the browser and you should have a shell prompt on the terminal.

Part 2

It takes a while to get to this part but if you have been keeping notes of previous findings, getting back here is very simple. Now let’s get some flags!

Find out who are are logged in as with whoami and which directory you are in with pwd. Then use the find command to look for the first flag. Of course, you can skip figuring out who and where you are but it’s good to get a lay of the land first.
find / -name "user.txt" 2>/dev/null

First flag found! Let’s see about getting the root flag.

If you run sudo -l, you’ll see we can execute /var/www/gdb as the user thirtytwo. So we will exploit this to gain a shell as that user.
sudo -u thirtytwo /var/www/gdb -nx -ex '!sh' -ex quit

GTFOBins is a great site for figuring out if a command can be exploited or not. I highly recommend taking a look there.

For the next part, we need to get an interactive shell.
python -c 'import pty;pty.spawn("/bin/bash")'

Then we can run sudo -l and see that thirtytwo can run /usr/bin/git as the user d4rckh. We will exploit that with this command.
sudo -u d4rckh /usr/bin/git help config

Once you get a prompt, use !/bin/sh to get a new shell.

Now we are d4rckh! We found our first flag in this user’s home folder so we will navigate there first. Run ls -la and we see there is a file called “cleanup.py” owned by root that we can write to.

Reading the file, we notice we can have this script execute system commands with os.system(). Before we write anything, we need to see how to get the command to run as root. Our user is not part of the sudo group and if we run sudo -l, we are asked for a password. (Don’t press CTRL+C! You’ll have to start all over!)

Check out /etc/crontab.

The script we can abuse runs every two minutes as root. Perfect! Let’s carefully edit that script with a command to get us the root flag.
echo "os.system('cat /root/root.txt > /home/flag; chmod 444 /home/flag')" >> /home/d4rckh/cleanup.py

I say carefully because entering bad code means we have to type it all over again! No one wants that pain.

In about two minutes, we can check to see if we got our root flag.

Part 3

If you’re like me and entered the wrong command to get the root flag, it definitely feels like game over.

The best thing to do is to terminate the remote machine and redeploy. This means you have to re-upload the reverse shell script. Hope you took notes.

Once that is done and you’re logged back into the machine, you can skip the lateral escalations and go straight for the root escalation. Remember, anyone can write to “cleanup.py” and cron will run it as root!

Cautiously edit the script with your command, wait two minutes, and viola!

So why go through all the trouble if we can just do this? Sometimes, it takes a lot of jumping around to get the right permissions to get the exploit. Imagine if the cleanup script was in a subfolder that only d4rckh could read and write to. Suddenly our quick solution is invalid and we would have to jump to a different user to try to get permission to edit the script!

With that said, I’m glad this quick solution exists. No tab complete, cursor navigation, or up arrow for previous commands make this an irksome task to complete.

WriteUp: Gotta Catch’em All

Another fun and relatively easy CTF from the website TryHackMe! I swear, this is by far my favorite site for learning pentesting techniques and getting some practical experience!

This CTF is about Pokemon and though you can probably guess the answer to “Find the Grass-Type Pokemon”, you probably won’t know how to present that answer. Good fun!

Deploy the machine and let’s get started!

First things first. We need some information about the machine. Run a basic nmap command for any open ports we may be able to leverage.
nmap -sS -sV <ip_address>

We got http and ssh open. Can’t do much with ssh so let’s take a look at the website. One thing I like to do before navigating to the site is having something like gobuster searching for directories.
gobuster dir -u <ip/domain> -w <wordlist>

When you go to the webpage of the ip address, you’re greeted with an adorable Apache2 default welcome page. Sorry, no Pikachu here. But maybe gobuster found something?

A bunch of 403s won’t do us any good. All we get is that default page…or do we?

At the very bottom of the webpage, there is something that looks out of place. A colon, all alone. To find out why it’s there, let’s look at the page source.

The source page has the typical css, javascript, and html trio. If you want, you can take some time with the javascript but it is not a clue. Believe me, I’ve tried. Instead look towards the bottom and there are two tags that doesn’t look like html.

I’ll admit this took me a while to get and I face palmed myself once I realized what I was looking at. Right there in plain sight, ssh credentials! Now that we have those, we can leave the browser and ssh into the machine.
ssh <user>@<ip_address>

Once we’re in, run the groups command. Our user is a part of many groups but not sudo. If we try sudo -l, we get a message that the user may not run sudo as root. Taking a look at the file permissions of /etc/passwd and /etc/shadow does not give us any kind of leverage we can use. And there’s nothing special in /etc/crontab. Looks like we won’t be escalating privileges yet so we’ll explore a little.

Running ls and ls -a on the home directory of our user does not yield anything interesting. If we look in the Desktop folder…

There is a zip file. Unzip it using the unzip command and we’ll see that our first flag is now available! There is a catch though. The flag is encoded. It is up to you figure out the encoding. Once you do, you’ll have the grass-type flag!

Going back to our home directory, we can list the contents of the other folders which gives nothing back except for one folder. The “Videos” folder has a folder called “Gotta”. Interesting. Navigate to that folder and the sub-folders that follow. There is a file at the end of the folder path that ends in “.cplusplus”. Run cat on this file.

We got credentials for another user! Before we use these credentials, let’s see if we can find any other flags as the user we currently are.

At this point, we still need the water and fire type flags. Good thing we can search based on keywords from the flags. We will use the find command to see if we can get the other two flags.
find / -name "water-type*" 2>/dev/null

This shows us that there is a file called “water-type.txt” under /var/www/html. Run the cat command on the file and you’re presented with something resembling the flag. This flag needs to be decrypted and once again, I leave that up to the reader to figure out but as a hint, the ancient romans would be proud.

To find the fire-type flag, we will run the find command again but changing out the word “water” for “fire”.
find / -name "fire-type*" 2>/dev/null

Once again, we get a path to a file called “fire-type.txt”. Run cat on the file and you’ll get the third flag…encrypted. And as before, it’s up to you to figure out what the encryption is. All I can say is all your blank are belong to us.

What about root’s favorite pokemon?

Personally, I think it’s Psyduck but we got another set of credentials we can try out. Login to the other user’s account with the following command.
su <new_username>
After logging in, run the groups command. You’ll see that this user is a part of sudo!

One thing you may notice quickly is that this user doesn’t have a home folder to go to. Check out the “/home/” folder with sudo ls -l.

Although it’s redacted, we can see that our new user’s home directory is owned by root however we can read the “roots-pokemon.txt” file. Read it with the cat command to get the final flag! No tricks!

And that’s it! Congratulations on completing the CTF!



Side Note

When I originally did this challenge, I did not use the above steps after the initial ssh login. Instead, I was able to cat the .bash_history of the user and saw all of the commands taken to create the files for the flag and the additional user. I copied that to a temporary file in /tmp and used it as my guide to hunt the flags.

While writing this writeup, I found out that the .bash_history is now completely empty. This was certainly a surprise as I had thought that was the way to do the challenge. I now like to think I hacked the hacking challenge…or got really lucky that the bash history wasn’t cleared out.

Thank the hacking gods that there is a find command.