Hack The Box: Mirage Machine Walkthrough β Hard Difficulity
Introduction to Mirage:

In this writeup, we will explore the βMirageβ machine from Hack The Box, categorized as a Hard difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.
Objective:
The goal of this walkthrough is to complete the βMirageβ machine from Hack The Box by achieving the following objectives:
User Flag:
We kicked off with NFS, SMB, and Kerberos enumeration, mounted the open MirageReports share, and grabbed two internal PDFs. One revealed the missing hostname nats-svc.mirage.htb. We hijacked DNS with DNSadder.py, funneled all NATS traffic through our proxy, and snatched JetStream auth_logs messages β yielding valid credentials for david.jjackson. After syncing our clock with the DC, we scored a TGT, fired up Evil-WinRM, and landed on the domain controller as david.jjackson to claim the user flag.
Root Flag:
We started with david.jjacksonβs ticket, and then kerberoasted nathan.aadam. After cracking his password, we gained his shell and subsequently discovered mark.bbondβs credentials. From there, we also retrieved the Mirage-Service$ managed password. With these pieces, we used Certipy to forge a DC01$ certificate, and as a result, we configured RBCD so mark.bbond could impersonate the domain controller. Once that was in place, we executed DCSync to dump all domain hashes, including Administrator. Finally, we obtained an Admin TGT and used EvilβWinRM to open a shell as Administrator, which ultimately allowed us to claim the root flag.
Enumerating the Mirage Machine
Reconnaissance:
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
nmap -sC -sV -oA initial 10.10.11.78 Nmap Output:
ββ[dark@parrot]β[~/Documents/htb/mirage]
ββββΌ $nmap -sC -sV -oA initial 10.10.11.78
Nmap scan report for 10.10.11.78
Host is up (0.15s latency).
Not shown: 987 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-11-20 20:52:31Z)
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/tcp6 rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 2,3,4 111/udp6 rpcbind
| 100003 2,3 2049/udp nfs
| 100003 2,3 2049/udp6 nfs
| 100003 2,3,4 2049/tcp nfs
| 100003 2,3,4 2049/tcp6 nfs
| 100005 1,2,3 2049/tcp mountd
| 100005 1,2,3 2049/tcp6 mountd
| 100005 1,2,3 2049/udp mountd
| 100005 1,2,3 2049/udp6 mountd
| 100021 1,2,3,4 2049/tcp nlockmgr
| 100021 1,2,3,4 2049/tcp6 nlockmgr
| 100021 1,2,3,4 2049/udp nlockmgr
| 100021 1,2,3,4 2049/udp6 nlockmgr
| 100024 1 2049/tcp status
| 100024 1 2049/tcp6 status
| 100024 1 2049/udp status
|_ 100024 1 2049/udp6 status135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open 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
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-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
|_ssl-date: TLS randomness does not represent time2049/tcp open nlockmgr 1-4 (RPC #100021)
3268/tcp open 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
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
| Not valid before: 2025-07-04T19:58:41
|_Not valid after: 2105-07-04T19:58:41
|_ssl-date: TLS randomness does not represent time
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: -22m05s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-11-20T20:53:32
|_ start_date: N/AAnalysis:
- Port 53 (DNS) β Provides internal domain resolution. Useful for discovering hostnames and performing zone transfers if misconfigured.
- β’ Port 88 (Kerberos) β Active Directory authentication endpoint. Key for attacks like Kerberoasting or ASβREP roasting.
- β’ Ports 111 & 2049 (NFS) β NFS running on a Windows DC is unusual. Could allow unauthenticated mounts or expose readable files.
- β’ Ports 135 / 139 / 445 (MSRPC / SMB) β Standard Windows services. SMB signing is enforced, which prevents NTLM relay attacks.
- β’ Ports 389 / 636 / 3268 / 3269 (LDAP / Global Catalog) β Full AD environment. LDAP enumeration is possible if permissions are misconfigured.
- β’ Port 464 (kpasswd) β Kerberos password change service. Can provide insights for passwordβspray attempts.
- β’ Port 593 (RPC over HTTP) β RPC over HTTP interface. Typically used for Outlook Anywhere or AD RPC proxying.
Server Enumeration:
Perform web enumeration to discover potentially exploitable directories and files.

We scanned SMB and saw the service up, but mirage.htb blocked all NTLM logins (even dark:dark failed with STATUS_NOT_SUPPORTED). Kerberos only from now on.
We added the domain/realm to /etc/krb5.conf and used -k flags everywhere β no more passwords over the wire.
NFS Share Enumeration and Mounting Process on Mirage machine

The showmount -e mirage.htb command reveals that the target is exporting an NFS share named /MirageReports, and it is accessible to everyone. This means the share does not enforce host-based restrictions, allowing any machine to mount it. Since the export is world-accessible, itβs likely a good entry point for enumeration, as you can mount the share locally and inspect its contents for sensitive files, misconfigurations, or clues leading to further access.

The mount attempt failed because the local path /mnt/mirage doesnβt exist on our machine. NFS requires a valid directory to mount a remote share, so before accessing the exported /MirageReports share, we need to create a local mount point.

Creating the directory with mkdir -p /mnt/mirage resolves the issue, allowing us to mount the share and begin enumerating its contents.

The βfailed to apply fstab optionsβ error usually comes from stale mount settings or syntax issues. Just rerun the command cleanly or add -o vers=3,nolock β it fixes the problem in HTB.

We corrected the syntax (added -o vers=3,nolock when needed) and re-ran mount -t nfs mirage.htb:/MirageReports /mnt/mirage. The share mounted perfectly and gave us full access to the internal reports.

After mounting the NFS share, ls reveals two PDFs: Incident_Report_Missing_DNS_Record_nats-svc.pdf and Mirage_Authentication_Hardening_Report.pdf. These internal reports likely expose misconfigurations and are key for further enumeration.

This command copies all files from the mounted NFS share at /mnt/mirage into your current working directory using elevated privileges. It allows you to analyze the documents locally without needing to stay connected to the NFS share.
Discovery and Analysis of Internal Reports

After copying, the files should now be available in your current working directory for further analysis.


Reviewing the Incident_Report_Missing_DNS_Record_nats-svc.pdf file revealed an additional hostname: nats-svc.mirage.htb.

Exploiting Missing DNS Entry for NATS Interception on Mirage Machine
The Incident Report showed nats-svc.mirage.htb missing from DNS β internal clients failed to resolve it. We fired up DNSadder.py, added a fake record to our proxy, and hijacked all NATS traffic β full MITM on auth and JetStream (including auth_logs).
Enumerating and Interacting With NATS JetStream
NATS is a messaging system that helps different parts of a companyβs software talk to each other. Instead of applications connecting directly, they send messages through NATS, which delivers them quickly and reliably.

To install the NATS commandβline interface on Parrot OS, you can use the Go toolchain included in the system. Simply run the command go install github.com/nats-io/natscli/nats@latest, which downloads and compiles the latest version of the NATS CLI and places it in your Go binaries directory for use.

To verify that the NATS CLI installed correctly, simply run the nats command in your terminal. If the installation was successful, it should display the available subcommands and usage information, confirming that the tool is ready to use.
Checking the auth_logs Stream

nats stream info auth_logs showed a small stream (max 100 messages) on subject logs.auth that currently held 5 messages β perfect for grabbing credentials.
Creating a Pull Consumer

We created a pull consumer named whare1 on the auth_logs stream using Dev_Account_A credentials. It fetches messages one-by-one with explicit acknowledgment, allowing us to retrieve all five stored authentication logs.
Grabbing the Credentials

We fetched the five messages from the auth_logs stream using our whare1 consumer. Every message (subject logs.auth) contained the same authentication event:
- Username: david.jjackson
- Password: pN8kQmn6b86!1234@
- Source IP: 10.10.10.20
All messages were acknowledged and consumed successfully, confirming we now have valid domain credentials.
Extracting Credentials and Kerberos Ticket Operations

The leaked david.jjackson:pN8kQmn6b86!1234@ credentials let us request a Kerberos TGT with impacket-getTGT. The first try failed due to clock skew; after sudo ntpdate -s 10.10.11.78, the second attempt succeeded and saved david.jjackson.ccache
Initial Foothold β david.jjackson Access on Mirage Machine

After syncing time with sudo ntpdate -s 10.10.11.78, the second impacket-getTGT run succeeded and gave us a valid TGT.

This command sets the KRB5CCNAME environment variable to use the david.jjackson.ccache file as the active Kerberos ticket. It tells all Kerberosβaware tools to use this ticket automatically for authentication instead of a password.

Try running the command again if it doesnβt work on the first attempt.
Lateral Movement Using Cracked SPN Credentials

With david.jjacksonβs ticket, we ran impacket-GetUserSPNs -k -no-pass and discovered a crackable Kerberos service ticket ($krb5tgs$23$) for the SPN HTTP/exchange.mirage.htb, belonging to the high-privileged user nathan.aadam (member of Exchange_Admins group).
Cracking the TGS β Password: 3edc#EDC3

We cracked the TGS hash using John and the RockYou wordlist, recovering the password 3edc#EDC3 for nathan.aadam β a weak credential that immediately granted us access to this Exchange Admins group member.
BloodHound Collection and Domain Enumeration on Mirage machine

As nathan.aadam, we ran BloodHound and dumped the entire Active Directory structure for privilege escalation path hunting.

Mark.bbond is a member of the IT Support group, and he has the ForceChangePassword privilege over the user javier.mmarshall.

Javier.mmarshall has ReadGMSAPassword permission on the account Mirage-Service$.

nxc smb dc01.mirage.htb with nathan.aadam initially failed due to clock skew (krb_ap_err_skew). After syncing time again (ntpdate -s 10.10.11.78), authentication succeeded cleanly.

Same clock skew issue hit nxc smb. After ntpdate -s 10.10.11.78, it worked instantly and confirmed valid access as nathan.aadam : 3edc#EDC3 on the DC.

We used the cracked password 3edc#EDC3 to obtain a Kerberos TGT for nathan.aadam (impacket-getTGT). The ticket was saved as nathan.aadam.ccache, giving us full Kerberos access for the next steps
Accessing the DC as nathan.aadam

Connected instantly as nathan.aadam β full PowerShell access on the Domain Controller.
Grabbing the User Flag

We can read the user flag by typing the βtype user.txtβ command
Escalate to Root Privileges Access on Mirage Machine
Privilege Escalation Attempts and LogonHours Analysis

We checked AD LogonHours. javier.mmarshall had all zeroes β account completely locked out (canβt log in anytime). This hinted the account was disabled but still present for potential abuse.

No default password was detected.

You can transfer the WinPEAS executable to the compromised host by running the upload command inside your EvilβWinRM session. This pushes the file from your attack machine directly into the victimβs system, allowing you to execute it afterwards for privilegeβescalation enumeration.


No usable credentials were identified.

This command verifies SMB access on dc01.mirage.htb using Kerberos authentication with the mark.bbond credentials. The scan shows the host details and confirms a successful login, indicating that the provided password is valid and SMB authentication for this account works correctly.

The command requests a Kerberos TGT for the user MARK.BBOND using the discovered password 1day@atime. By specifying the domain controller IP, the tool authenticates against the DC and generates a valid ticket. Once successful, the resulting Kerberos ticket is saved locally as MARK.BBOND.ccache for use in later Kerberosβbased operations.
Password Resets, Kerberos Tickets, and Service Account Abuse

A password reset for the account javier.mmarshall was performed using bloodyAD. By authenticating as mark.bbond with Kerberos (-k) and supplying valid domain credentials, the command successfully updated the userβs password to p@ssw0rd123, confirming the operation completed without issues.

Attempting to obtain a TGT for the account javier.mmarshall with impacket-getTGT results in a KDC_ERR_CLIENT_REVOKED error. This indicates the credentials are no longer valid because the account has been disabled or otherwise revoked in Active Directory, preventing any Kerberos authentication from succeeding.
Enabling javier.mmarshall (disabled account)

By running the command shown above, the password update completed successfully.

As mark.bbond, we used BloodyAD to read the msDS-ManagedPassword attribute of the Mirage-Service$ managed service account and instantly retrieved its current plaintext password + NTLM hash.

We used Impacket to request a Kerberos TGT for Mirage-Service$ with its leaked NTLM hash (pass-the-hash). This gave us a valid ticket without ever needing the plaintext password.

We asked the domain CA for a certificate using mark.bbond (now pretending to be dc01$). The CA accepted it and gave us a shiny dc01.pfx file that lets us log in as the real domain controller machine account.

After exporting the Kerberos ticket with export KRB5CCNAME=mark.bbond.ccache, a certificate request is made using Certipy

We requested a certificate for mark.bbond (UPN = dc01$@mirage.htb). The CA issued it without issues β dc01.pfx ready for authentication as the DC machine account.

We cleaned up by resetting mark.bbondβs UPN back to mark.bbond@mirage.htb with Certipy β leaving no obvious traces.
Certificate Abuse and Resource-Based Constrained Delegation (RBCD)

With the dc01.pfx certificate, Certipy authenticated us over LDAPS as MIRAGE\DC01$ β we now had full LDAP control as the domain controller itself.

We used Certipy to grant mark.bbond Resource-Based Constrained Delegation over DC01$ β now mark.bbond can impersonate anyone (including Administrator) to the domain controller.

As mark.bbond, we ran impacket-getST to impersonate DC01$ and request a CIFS ticket for the real DC. Delegation succeeded β valid ticket saved.

The Kerberos ticket was set as the active credential cache by exporting it to the KRB5CCNAME environment variable:
export KRB5CCNAME=DC01$@<a>CIFS_dc01.mirage.htb@MIRAGE.HTB.ccache</a>
With the delegated CIFS ticket, we executed impacket-secretdump -k dc01.mirage.htb and successfully dumped the entire NTDS.DIT β every user and machine hash, including Administratorβs, was now ours.

The impacket-getTGT command was executed using the Administrator NTLM hash to request a Kerberos TGT from the Mirage domain controller. The request completed successfully, and the resulting ticket was saved locally as Administrator.ccache.

The evil-winrm command was used to connect to dc01.mirage.htb with Kerberos authentication. EvilβWinRM initialized successfully, displaying standard warnings about Rubyβs pathβcompletion limitations and noting that the provided username is unnecessary when a Kerberos ticket is already available. The session then proceeded to establish a connection with the remote host.

We can read the root flag by typing the βtype root.txtβ command
The post Hack The Box: Mirage Machine Walkthrough β Hard Difficulity appeared first on Threatninja.net.











































































































































































































































































































































































