Windows Privilege Escalation 01: Initial Enumeration
Hey, how's it going? Are you feeling well? Have you drunk enough water today? If not, see this as your calling before reading along!
Before this series dives into the depths of Windows PrivEsc, I thought I'd throw in some quick references to some Windows fundamentals, commands you should have seen before doing the good stuff. This is what this post is about.
Not all stuff in this is DIRECTLY tied to PrivEsc, still it is pretty beneficial to grasp the base concepts.
So let's go, shall we?
Windows Fundamentals
Connecting In
xfreerdp /v:<IP> /u:htb-student /p:<PASSWORD>
RDP gives you a full GUI desktop session on the target, port 3389. This is how you'll connect to most HTB Windows labs aswell (their collection in Academy truly is huge!).
Add +clipboard for copy-paste, /drive:share,/tmp/loot to access your local files from the target.
Knowing Where You Are
Get-WmiObject -Class Win32_OperatingSystem
Tells you the exact Windows version and build number. This matters because exploits are version-specific. CMD equivalent: systeminfo (gives you even more: patches, domain, architecture).
wmic os list brief
Same idea, CMD-style. Quicker output than systeminfo, just OS info.
whoami /user
Shows your username and SID (Security Identifier). The SID is how Windows actually identifies you internally; usernames are just labels. SIDs ending in -500 = built-in Administrator, -501 = Guest. You'll see SIDs everywhere in Windows security.
Navigating the File System
dir c:\ /a
Like ls -la on Linux. The /a flag shows hidden and system files too, without it you miss things.
tree <directory>
tree c:\ /f | more
Visual directory tree. /f includes files (not just folders). Pipe to more because the output is massive. Useful for quick recon on unfamiliar directories, but in practice you'll use dir more.
Permissions
icacls <path>
The Windows equivalent of getfacl on Linux. Shows the full ACL for a file or folder, who has what access and at what level.
This can be crucial for PrivEsc: you're looking for files or folders where your user has (M)odify or (W)rite access that they shouldn't. Especially on service binaries and directories in PATH.
icacls c:\users /grant joe:f
icacls c:\users /remove joe
Grant/remove permissions. You won't use this offensively often, but understanding the syntax helps you read ACL output.. which you'll do constantly.
Services
Get-Service #PowerShell
Lists all Windows services and their status (Running/Stopped). Services are background processes; many run as SYSTEM. Misconfigured services are one of the most common Windows PrivEsc vectors (unquoted paths, weak binary permissions, writable registry keys).
PowerShell Essentials
help <command>
# or
Get-Help <command> -Full
Like man on Linux. Use it when you don't remember a cmdlet's syntax.
Get-Alias
PowerShell has aliases: ls actually runs Get-ChildItem, cat runs Get-Content, cd runs Set-Location. So your Linux muscle memory partially works in PowerShell. Get-Alias shows the full mapping.
Get-ExecutionPolicy -List
Set-ExecutionPolicy Bypass -Scope Process
PowerShell has a safety feature that blocks script execution by default. Get-ExecutionPolicy shows the current setting. If you can't run a .ps1 script, Set-ExecutionPolicy Bypass -Scope Process disables the restriction for your current session only. You'll need this when running tools like PowerUp or WinPEAS.ps1.
Get-Module | select Name,ExportedCommands | fl
Shows which PowerShell modules are loaded and what commands they provide. Useful to see what's already available on the box (e.g., ActiveDirectory module = domain-joined, interesting).
Security / Defender
Get-MpComputerStatus
Shows Windows Defender status. Is real-time protection on? Are signatures up to date? Check this early. If Defender is active, your tools will get caught. Guides your decision on whether to use on-disk tools or in-memory execution.
reg query <key>
Read values from the Windows Registry (the central config database). You'll use this to check for stored credentials, autostart entries, service configs, and misconfigurations like AlwaysInstallElevated.
Let's test you on what we learned!
All right, good start. Now let's go into PrivEsc, shall we?
Tools We'll Be Using
HTB and other sources will be throwing tools in your face like it's nothing. That's good, you absolutely need them for an efficient workflow in boxes, yet that can be quite overwhelming. Here's a simple overview for future reference:
| Tool | What it does |
|---|---|
| LaZagne | Digs up stored passwords from browsers, databases, Git, chat clients, and more |
| WES-NG | Feed it your systeminfo output and it maps out which vulnerabilities apply to the target |
| SharpUp | C# port of PowerUp; same idea, different runtime |
| SessionGopher | Pulls saved session credentials from PuTTY, WinSCP, FileZilla, RDP, and similar tools |
| winPEAS | Scans for common privesc paths and explains what it finds along the way |
| Watson | Looks for missing patches and ties them to known exploits |
| Sysinternals Suite | We'll be using AccessChk, PipeList, and PsService specifically |
| JAWS | A PowerShell enumeration script built to work even on older PS 2.0 environments |
| Seatbelt | Runs a broad set of local checks; good for getting a quick lay of the land |
| PowerUp | Finds misconfiguration-based privesc vectors and can sometimes exploit them directly |
When in need of such, I'll be transferring all of these to the target myself rather than using anything pre-installed.
I'd recommend you do the same. Working out how is left as an exercise for you, on HTB you can always rely on them being in C:\Tools... yet that's too easy, isn't it? HihiI am simply trying to document what I'm learning, to bring you along and teach you what you need to keep in mind.
LET'S GOOO
A Tool's Safe Haven
C:\Windows\Temp, the BUILTIN\Users group has write access to it.Network Enumeration
Spotting Dual-Homed
A host is dual-homed when it has network interfaces connected to two or more different networks.
Think of it as a machine with one foot in the corporate LAN and another in a DMZ or internal subnet you couldn't reach before. For us, that's interesting because compromising it might open a path into a network segment we had no access to.
C:\Users\htb-student>ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . . : WINLPE-SRV01
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Hybrid
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
DNS Suffix Search List. . . . . . : htb
Ethernet adapter Ethernet1:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter
Physical Address. . . . . . . . . : 00-50-56-8A-88-7D
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::59ba:2624:c975:84c3%2(Preferred)
IPv4 Address. . . . . . . . . . . : 172.16.20.45(Preferred)
[...]
Ethernet adapter Ethernet0 2:
Connection-specific DNS Suffix . : .htb
Description . . . . . . . . . . . : vmxnet3 Ethernet Adapter #2
Physical Address. . . . . . . . . : 00-50-56-8A-B2-0C
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : dead:beef::161(Preferred)
Lease Obtained. . . . . . . . . . : Thursday, April 23, 2026 12:21:33 PM
Lease Expires . . . . . . . . . . : Thursday, April 23, 2026 1:21:32 PM
IPv6 Address. . . . . . . . . . . : dead:beef::bdda:e84a:adaa:e490(Preferred)
Link-local IPv6 Address . . . . . : fe80::bdda:e84a:adaa:e490%4(Preferred)
IPv4 Address. . . . . . . . . . . : 10.129.64.209(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.0.0
[...]See that? 2 Network Interface Cards (NICs). They connect a device to a network, they get a MAC address and they can be assigned an IP address.
That's how we know machine is dual-homed, you can see it clearly:
Ethernet1→172.16.20.45: a private internal network you couldn't reach from outsideEthernet0 2→10.129.64.209: the HTB network you connected through
Interpreting ARP Output
C:\Users\htb-student>arp -a
Interface: 172.16.20.45 --- 0x2
Internet Address Physical Address Type
172.16.21.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
224.0.0.252 01-00-5e-00-00-fc static
239.255.255.250 01-00-5e-7f-ff-fa static
Interface: 10.129.64.209 --- 0x4
Internet Address Physical Address Type
10.129.0.1 00-50-56-8a-95-7b dynamic
10.129.50.254 00-50-56-8a-db-a6 dynamic
10.129.205.123 00-50-56-8a-1a-fd dynamic
10.129.255.255 ff-ff-ff-ff-ff-ff static
224.0.0.22 01-00-5e-00-00-16 static
224.0.0.252 01-00-5e-00-00-fc static
239.255.255.250 01-00-5e-7f-ff-fa static
255.255.255.255 ff-ff-ff-ff-ff-ff staticThe ARP (Address Resolution Protocol) table shows hosts this machine has recently communicated with. Each entry maps an IP address to a MAC address, which is how your machine knows where to actually send packets on the local network.
The Type column tells you how the entry got there.
dynamicmeans the machine actually talked to that host recently and learned its MAC automatically.staticentries are either broadcast addresses or multicast groups that are hardcoded by the OS, not real hosts.
So from the output, the only hosts worth paying attention to are the dynamic ones under 10.129.64.209:
10.129.0.1is the gateway.10.129.50.254and10.129.205.123are actual hosts that this machine has been talking to, those are interesting.
In a real engagement you'd want to note those down and potentially investigate them for lateral movement after you've escalated privileges.
The 172.16.20.45 interface has no dynamic entries at all, meaning this machine hasn't recently communicated with anyone on that internal network. Doesn't mean nothing is there, just that nothing showed up in the cache.
Interpreting the Routing Table
C:\Users\htb-student>route print
===========================================================================
Interface List
2...00 50 56 8a 88 7d ......vmxnet3 Ethernet Adapter
4...00 50 56 8a b2 0c ......vmxnet3 Ethernet Adapter #2
7...00 ff b3 3c cd 5a ......Windscribe VPN
1...........................Software Loopback Interface 1
9...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter
6...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #3
===========================================================================
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 172.16.20.1 172.16.20.45 271
0.0.0.0 0.0.0.0 10.129.0.1 10.129.64.209 15
10.129.0.0 255.255.0.0 On-link 10.129.64.209 271
10.129.64.209 255.255.255.255 On-link 10.129.64.209 271
10.129.255.255 255.255.255.255 On-link 10.129.64.209 271
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
172.16.20.0 255.255.254.0 On-link 172.16.20.45 271
172.16.20.45 255.255.255.255 On-link 172.16.20.45 271
172.16.21.255 255.255.255.255 On-link 172.16.20.45 271
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 172.16.20.45 271
224.0.0.0 240.0.0.0 On-link 10.129.64.209 271
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 172.16.20.45 271
255.255.255.255 255.255.255.255 On-link 10.129.64.209 271
===========================================================================
Persistent Routes:
Network Address Netmask Gateway Address Metric
0.0.0.0 0.0.0.0 172.16.20.1 Default
===========================================================================
IPv6 Route Table
===========================================================================
Active Routes:
If Metric Network Destination Gateway
4 271 ::/0 fe80::250:56ff:fe8a:957b
1 331 ::1/128 On-link
4 271 dead:beef::/64 On-link
4 271 dead:beef::161/128 On-link
4 271 dead:beef::bdda:e84a:adaa:e490/128
On-link
2 271 fe80::/64 On-link
4 271 fe80::/64 On-link
2 271 fe80::59ba:2624:c975:84c3/128
On-link
4 271 fe80::bdda:e84a:adaa:e490/128
On-link
1 331 ff00::/8 On-link
2 271 ff00::/8 On-link
4 271 ff00::/8 On-link
===========================================================================
Persistent Routes:
NoneIt looks at the destination IP and asks "which rule matches this?" then sends the packet out through the corresponding interface via the specified gateway.
The most important column to understand is Network Destination combined with Netmask.
Together they define which range of IPs a rule applies to. The Gateway column tells the machine where to send the packet next, and Interface tells it which NIC to use to get there.
The two 0.0.0.0 entries at the top are the default routes, these are the catch-all rules that handle any traffic that doesn't match a more specific rule. You have two of them, one per interface.
The Metric column is the tiebreaker; lower wins. So with metric 15, the 10.129.0.1 gateway via 10.129.64.209 takes priority over the 172.16.20.1 one with metric 271. That's why you can reach HTB machines, it's the preferred path out.
The On-link entries don't go through a gateway at all. They mean the destination is directly reachable on that interface without any routing needed: The machine is on the same subnet.The Persistent Routes section at the bottom is interesting. It shows the 172.16.20.1 default gateway is hardcoded and survives reboots, while the HTB route is only active because DHCP handed it out.
In a real engagement that tells you the 172.16.20.0 network is the machine's permanent home network, the one it was actually configured for.
Checking Windows Defender
C:\Users\htb-student> Get-MpComputerStatus
AMEngineVersion : 1.1.18400.4
AMProductVersion : 4.10.14393.0
AMServiceEnabled : True
AMServiceVersion : 4.10.14393.0
AntispywareEnabled : True
AntispywareSignatureAge : 1720
AntispywareSignatureLastUpdated : 8/7/2021 11:16:31 AM
AntispywareSignatureVersion : 1.345.139.0
AntivirusEnabled : True
AntivirusSignatureAge : 1720
AntivirusSignatureLastUpdated : 8/7/2021 11:16:31 AM
AntivirusSignatureVersion : 1.345.139.0
BehaviorMonitorEnabled : False
ComputerID : 54AF7DE4-3C7E-4DA0-87AC-831B045B9063
ComputerState : 0
FullScanAge : 4294967295
FullScanEndTime :
FullScanStartTime :
IoavProtectionEnabled : False
LastFullScanSource : 0
LastQuickScanSource : 2
NISEnabled : False
NISEngineVersion : 0.0.0.0
NISSignatureAge : 4294967295
NISSignatureLastUpdated :
NISSignatureVersion : 0.0.0.0
OnAccessProtectionEnabled : False
QuickScanAge : 0
QuickScanEndTime : 4/23/2026 12:34:56 PM
QuickScanStartTime : 4/23/2026 12:31:32 PM
RealTimeProtectionEnabled : False
RealTimeScanDirection : 0
PSComputerName :The first thing to look at is RealTimeProtectionEnabled, on this box it's False. That's significant.
Real-time protection is the part of Defender that actively blocks malicious activity as it happens, so with it off, you have a lot more room to move.
Also worth noting: BehaviorMonitorEnabled, IoavProtectionEnabled, NISEnabled, and OnAccessProtectionEnabled are all False.
Combined with signatures last updated in 2021, this machine is essentially running Defender in name only. In a real engagement you wouldn't be this lucky, but knowing how to read this output tells you exactly what you're dealing with before you start dropping tools.
Checking AppLocker
C:\Users\htb-student> Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
PublisherConditions : {*\*\*,0.0.0.0-*}
PublisherExceptions : {}
PathExceptions : {}
HashExceptions : {}
Id : a9e18c21-ff8f-43cf-b9fc-db40eed693ba
Name : (Default Rule) All signed packaged apps
Description : Allows members of the Everyone group to run packaged apps that are signed.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {%SYSTEM32%\WindowsPowerShell\v1.0\powershell_ise.exe}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 684d8b3e-7656-4451-8abe-2588d772db8f
Name : Block PowerShell ISE
Description :
UserOrGroupSid : S-1-1-0
Action : Deny
PathConditions : {%PROGRAMFILES%\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 921cc481-6e17-4653-8f75-050b80acca20
Name : (Default Rule) All files located in the Program Files folder
Description : Allows members of the Everyone group to run applications that are located in the Program Files
folder.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {c:\windows\system32\cmd.exe}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 9b8293c1-49c7-4bbb-aa17-52c4232b1fe4
Name : c:\windows\system32\cmd.exe
Description :
UserOrGroupSid : S-1-1-0
Action : Deny
PathConditions : {%WINDIR%\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : a61c8b2c-a319-4cd0-9690-d2177cad7b51
Name : (Default Rule) All files located in the Windows folder
Description : Allows members of the Everyone group to run applications that are located in the Windows folder.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : fd686d83-a829-4351-8ff4-27c7de5755d2
Name : (Default Rule) All files
Description : Allows members of the local Administrators group to run all applications.
UserOrGroupSid : S-1-5-32-544
Action : Allow
PublisherConditions : {*\*\*,0.0.0.0-*}
PublisherExceptions : {}
PathExceptions : {}
HashExceptions : {}
Id : b7af7102-efde-4369-8a89-7a6a392d1473
Name : (Default Rule) All digitally signed Windows Installer files
Description : Allows members of the Everyone group to run digitally signed Windows Installer files.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {%WINDIR%\Installer\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 5b290184-345a-4453-b184-45305f6d9a54
Name : (Default Rule) All Windows Installer files in %systemdrive%\Windows\Installer
Description : Allows members of the Everyone group to run all Windows Installer files located in
%systemdrive%\Windows\Installer.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {*.*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 64ad46ff-0d71-4fa0-a30b-3f3d30c5433d
Name : (Default Rule) All Windows Installer files
Description : Allows members of the local Administrators group to run all Windows Installer files.
UserOrGroupSid : S-1-5-32-544
Action : Allow
PathConditions : {%PROGRAMFILES%\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 06dce67b-934c-454f-a263-2515c8796a5d
Name : (Default Rule) All scripts located in the Program Files folder
Description : Allows members of the Everyone group to run scripts that are located in the Program Files folder.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {%WINDIR%\*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : 9428c672-5fc3-47f4-808a-a0011f36dd2c
Name : (Default Rule) All scripts located in the Windows folder
Description : Allows members of the Everyone group to run scripts that are located in the Windows folder.
UserOrGroupSid : S-1-1-0
Action : Allow
PathConditions : {*}
PathExceptions : {}
PublisherExceptions : {}
HashExceptions : {}
Id : ed97d0cb-15ff-430f-b82c-8d7832957725
Name : (Default Rule) All scripts
Description : Allows members of the local Administrators group to run all scripts.
UserOrGroupSid : S-1-5-32-544
Action : AllowTwo rules here stand out immediately: cmd.exe is explicitly denied for Everyone, and so is powershell_ise.exe. So if you only have a standard user shell, you can't just pop open a normal Command Prompt.
However, plain powershell.exe is not blocked, only the ISE variant is. And since everything under %WINDIR%\* and %PROGRAMFILES%\* is allowed, there's already a lot of room to work with.
The key rule to remember: Administrators bypass all of this via the(Default Rule) All filesentry scoped toS-1-5-32-544, the local Administrators group. That's your target. Once you're in that group, AppLocker stops being your problem.
Initial Enumeration
I know there's a gazillion cheatsheets out there, but let's first pretend we don't have them. We want to really grasp what we're looking for with each command.
Using tasklist
PS C:\Users\htb-student> tasklist /svc
Image Name PID Services
========================= ======== ============================================
System Idle Process 0 N/A
System 4 N/A
smss.exe 356 N/A
csrss.exe 436 N/A
wininit.exe 540 N/A
csrss.exe 548 N/A
winlogon.exe 604 N/A
services.exe 676 N/A
lsass.exe 684 KeyIso, SamSs, VaultSvc
svchost.exe 784 BrokerInfrastructure, DcomLaunch, LSM,
PlugPlay, Power, SystemEventsBroker
svchost.exe 848 RpcEptMapper, RpcSs
svchost.exe 960 TermService
svchost.exe 968 Appinfo, CertPropSvc, DsmSvc, gpsvc,
IKEEXT, iphlpsvc, lfsvc, ProfSvc, Schedule,
SENS, SessionEnv, ShellHWDetection, Themes,
UserManager, Winmgmt, wlidsvc, WpnService,
wuauserv
dwm.exe 1004 N/A
svchost.exe 100 Dhcp, EventLog, lmhosts, TimeBrokerSvc
svchost.exe 108 NcbService, PcaSvc, ScDeviceEnum, StorSvc,
TrkWks, UALSVC, UmRdpService,
WdiSystemHost, wudfsvc
svchost.exe 888 EventSystem, FontCache, LicenseManager,
netprofm, nsi, W32Time, WinHttpAutoProxySvc
svchost.exe 1080 BFE, CoreMessagingRegistrar, DPS, MpsSvc
vm3dservice.exe 1120 vm3dservice
svchost.exe 1196 CryptSvc, Dnscache, LanmanWorkstation,
NlaSvc, WinRM
svchost.exe 1400 Wcmsvc
svchost.exe 1476 WlanSvc
svchost.exe 1844 PolicyAgent
spoolsv.exe 1924 Spooler
svchost.exe 1980 AppHostSvc
svchost.exe 1988 DiagTrack
svchost.exe 1312 ftpsvc
WindscribeService.exe 2020 WindscribeService
vmtoolsd.exe 2060 VMTools
FileZilla Server.exe 2076 FileZilla Server
svchost.exe 2100 StateRepository, tiledatamodelsvc
MsMpEng.exe 2112 WinDefend
inetinfo.exe 2120 IISADMIN
VGAuthService.exe 2132 VGAuthService
sqlwriter.exe 2144 SQLWriter
svchost.exe 2188 LanmanServer
svchost.exe 2216 W3SVC, WAS
Tomcat8.exe 2256 Tomcat8
conhost.exe 2456 N/A
dllhost.exe 3356 COMSysApp
sqlservr.exe 3368 MSSQL$SQLEXPRESS01
sqlceip.exe 3376 SQLTELEMETRY$SQLEXPRESS01
WmiPrvSE.exe 3584 N/A
msdtc.exe 3668 MSDTC
RuntimeBroker.exe 4736 N/A
sihost.exe 4816 N/A
svchost.exe 4836 CDPUserSvc_45dd1, OneSyncSvc_45dd1
[...]We can use the tasklist command to look at running processes.The /svc flag is what makes this useful: it maps each process to the Windows services running inside it, not just the process name.
What to look for
Standard Windows processes like smss.exe, csrss.exe, winlogon.exe, lsass.exe and the army of svchost.exe instances are all normal. Don't let the noise distract you. Your eyes should go straight to anything that isn't a default Windows component.
From my output, the interesting ones are:
-
FileZilla Server.exerunning as a service is immediately worth investigating. FTP servers are frequently misconfigured — anonymous access, weak credentials, or sensitive files in accessible directories are all common findings. inetinfo.exemeans IIS is running, andsvchost.exehostingW3SVCandWASconfirms an active web server. Web applications running locally are a common privesc vector, they often run as SYSTEM or a privileged service account.Tomcat8.exeis another web server, Java-based this time. Tomcat has a manager interface that's frequently left with default credentials (tomcat:tomcatoradmin:admin). If you can log in, you can deploy a WAR file and get code execution.sqlservr.exemeans SQL Server Express is running (MSSQL$SQLEXPRESS01). Databases often store credentials, and SQL Server misconfigurations can lead directly to SYSTEM viaxp_cmdshell.WindscribeService.exeis a VPN client service — interesting because third-party services like this sometimes have weak permissions on their binaries or service configurations, which is a classic privesc path we'll get into later.MsMpEng.exeis Defender. we already know from earlier that it's essentially toothless on this box, but in a real environment spotting this tells you what evasion you'll need.
Displaying Environment Variables (set)
Displaying Environment Variables
set
Quick gotcha: set only works in cmd.exe. In PowerShell, set is aliased to Set-Variable which is why might get an error. Use either of these instead:
# PowerShell equivalents
Get-ChildItem Env:
# or
ls env:
What to look for in the output:
PATH is the most interesting one. If any directory in there is writable by your user, that's a potential privesc path. Also note the order entries on the left take priority over C:\Windows\System32, so a writable custom path on the left is significantly worse than one on the right.HOMEDRIVE and HOMEPATH tell you where the user's home lives. In enterprise environments this is often a network share rather than a local path, worth navigating to manually, as IT shares occasionally contain credential spreadsheets or other sensitive files.
USERNAME and USERDOMAIN confirm whose context you're running in, and LOGONSERVER tells you which domain controller authenticated the session.
Viewing Config Info
C:\Users\htb-student> systeminfo
Host Name: WINLPE-SRV01
OS Name: Microsoft Windows Server 2016 Standard
OS Version: 10.0.14393 N/A Build 14393
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00376-30821-30176-AA890
Original Install Date: 3/24/2021, 3:46:32 PM
System Boot Time: 4/23/2026, 12:21:21 PM
System Manufacturer: VMware, Inc.
System Model: VMware7,1
System Type: x64-based PC
Processor(s): 3 Processor(s) Installed.
[01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~1996 Mhz
[02]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~1996 Mhz
[03]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~1996 Mhz
BIOS Version: VMware, Inc. VMW71.00V.24504846.B64.2501180334, 1/18/2025
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume2
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory: 6,143 MB
Available Physical Memory: 4,127 MB
Virtual Memory: Max Size: 7,167 MB
Virtual Memory: Available: 4,964 MB
Virtual Memory: In Use: 2,203 MB
Page File Location(s): C:\pagefile.sys
Domain: WORKGROUP
Logon Server: \\WINLPE-SRV01
Hotfix(s): 4 Hotfix(s) Installed.
[01]: KB3199986
[02]: KB4054590
[03]: KB5001078
[04]: KB3200970
Network Card(s): 3 NIC(s) Installed.
[01]: vmxnet3 Ethernet Adapter
Connection Name: Ethernet0 2
DHCP Enabled: Yes
DHCP Server: 10.10.10.2
IP address(es)
[01]: 10.129.64.209
[02]: fe80::bdda:e84a:adaa:e490
[03]: dead:beef::bdda:e84a:adaa:e490
[04]: dead:beef::161
[02]: vmxnet3 Ethernet Adapter
Connection Name: Ethernet1
DHCP Enabled: No
IP address(es)
[01]: 172.16.20.45
[02]: fe80::59ba:2624:c975:84c3
[03]: Windscribe VPN
Connection Name: Ethernet
Status: Media disconnected
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.Damn, what are we bombarded with here? Look at these four things:
Four things, nothing else:
-
OS VersionandSystem Boot Time: together these tell you the patch story. An old build number or a machine that hasn't rebooted in months is likely unpatched and vulnerable to known exploits. Hotfix(s)— only 3 hotfixes installed here, which is almost nothing for a production server. Feed these KB numbers into WES-NG later and it'll map them to known CVEs for you.System Manufacturer / Model—VMware7,1tells you immediately it's a VM. Useful context for later stages.Network Card(s)— two NICs listed confirms dual-homed, same conclusion we drew fromipconfig /allearlier but this gives it to you in one place without having to parse adapter blocks.
Enumerating Installed Patches
Two ways to get the same info:
C:\Users\htb-student> wmic qfe
Caption CSName Description FixComments HotFixID InstallDate Installe
dBy InstalledOn Name ServicePackInEffect Status
http://support.microsoft.com/?kbid=3199986 WINLPE-SRV01 Update KB3199986 NT AUTHO
RITY\SYSTEM 11/21/2016
http://support.microsoft.com/?kbid=4054590 WINLPE-SRV01 Update KB4054590 WINLPE-S
RV01\Administrator 3/30/2021
https://support.microsoft.com/help/5001078 WINLPE-SRV01 Security Update KB5001078 NT AUTHO
RITY\SYSTEM 3/25/2021
http://support.microsoft.com/?kbid=3200970 WINLPE-SRV01 Security Update KB3200970 WINLPE-S
RV01\Administrator 4/13/2021
C:\Users\htb-student> Get-HotFix | ft -AutoSize
Source Description HotFixID InstalledBy InstalledOn
------ ----------- -------- ----------- -----------
WINLPE-SRV01 Update KB3199986 NT AUTHORITY\SYSTEM 11/21/2016 12:00:00 AM
WINLPE-SRV01 Update KB4054590 WINLPE-SRV01\Administrator 3/30/2021 12:00:00 AM
WINLPE-SRV01 Security Update KB5001078 NT AUTHORITY\SYSTEM 3/25/2021 12:00:00 AM
WINLPE-SRV01 Security Update KB3200970 WINLPE-SRV01\Administrator 4/13/2021 12:00:00 AMGet-HotFix is generally cleaner output. Use wmic qfe as a fallback if PowerShell isn't available.
The only columns that matter are HotFixID and InstalledOn. You're looking for two things: how many patches are installed total, and when the most recent one was applied. A handful of KBs and a date from years ago means the machine is likely sitting on unpatched CVEs.
Again: Take those KB numbers and feed them into WES-NG, that's what maps them to actual exploits. We set that tool up earlier for exactly this reason.
Installed Programs
wmic product get name
# or
Get-WmiObject -Class Win32_Product | select Name, Version
wmic product get name is the quick CMD version. The PowerShell equivalent gives you versions too, which matters — knowing something is installed is useful, knowing it's running an old vulnerable version is actionable.
What you're actually looking for here is software that shouldn't be on a server, or software that is on a server and has known CVEs. Java 8 Update 231 in the output above, for instance, is ancient. Old Java, old Tomcat, old SQL Server installs — these are worth cross-referencing with WES-NG or a quick search.
A/lso: if you spot FileZilla, PuTTY, WinSCP, or similar tools, that's your cue to run LaZagne or SessionGopher. Those applications store session credentials locally, and they're frequently forgotten about.
Netstat: What's Listening?
C:\Windows\system32>netstat -ano
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:21 0.0.0.0:0 LISTENING 2068
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 860
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 3424
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 988
[....]The -ano flags give you everything useful: active connections, listening ports, and the PID of the process behind each one.
Cross-reference the PID column with tasklist /svc to figure out what process owns each port. That's how you connect the dots.
The column that matters most is Local Address. Anything bound to 0.0.0.0 is accessible from outside.
Anything bound to 127.0.0.1 is only reachable locally, meaning you'd have to already be on the box to hit it.
That second category is exactly what you're hunting. A service listening only on localhost is invisible from your attack machine, but once you have a shell, it's right there. Port 1433 (SQL Server) or 8080 (maybe a local web app) bound to loopback is a classic privesc setup: the service is running as SYSTEM but was never meant to be exposed, so nobody hardened it.
User & Group Information
Even on a well-maintained box, you'll often find the path to SYSTEM runs straight through a person. A browsable home directory, a reused password, a forgotten admin account.
Logged-In Users
C:\Windows\system32>query user
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
sccm_svc console 1 Active none 4/25/2026 12:16 PM
>htb-student rdp-tcp#0 2 Active . 4/25/2026 12:17 PMShows who's currently on the box and how. The STATE and IDLE TIME columns are what matter operationally: an active session with zero idle time means someone is sitting at that machine right now. During a covert engagement that changes how you move. On a box with an active admin session you want to be quiet: no noisy enumeration tools, no obvious file drops.
TheSESSIONNAMEcolumn tells you how they connected.rdp-tcp#0means RDP.consolemeans local. That context matters if you're thinking about session hijacking later.
Current User
C:\Windows\system32>echo %USERNAME%
htb-studentFirst thing you run after getting a shell. You need to know whose context you're operating in before you do anything else. Sometimes you land directly as SYSTEM or as a service account with powerful privileges. In that case half your work is already done.
Current User Privileges
C:\Windows\system32>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ======================================== ========
SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set DisabledThis is one of the most important commands in your initial enumeration. Certain privileges are direct privesc paths regardless of group membership. A few important examples to know by heart:
SeImpersonatePrivilege: held by service accounts, exploitable via Juicy Potato, PrintSpoofer, or similar tools to get SYSTEM almost immediately.SeBackupPrivilege: lets you read any file on the system regardless of ACLs. That includes SAM, SYSTEM, and NTDS.dit.SeDebugPrivilege: lets you inject into and read memory of processes you don't own, including lsass.SeLoadDriverPrivilege: lets you load kernel drivers, which means kernel-level code execution.
Even a Disabled state doesn't protect you here. Most of these can be enabled in the same process with a few API calls.Current User Group Membership
C:\Windows\system32>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\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 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\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 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\High Mandatory Level Label S-1-16-12288Group membership is how Windows delegates rights, and inherited rights are easy to overlook. What you're scanning for here is anything that isn't standard for a normal user account: membership in Backup Operators, Event Log Readers, Remote Management Users, DnsAdmins, or Hyper-V Administrators all have documented privesc paths.
The Mandatory Label line at the bottom tells you your integrity level. Medium is a standard user. High means elevated. System means you're already there.
All Local Users
C:\Windows\system32>net user
User accounts for \\WINLPE-SRV01
-------------------------------------------------------------------------------
Administrator DefaultAccount Guest
helpdesk htb-student htb-student_adm
jordan logger mrb3n
sarah sccm_svc secsvc
sql_dev
The command completed successfully.Gives you the full picture of who has an account on this box. Look for anything non-standard alongside the built-in accounts. Naming patterns like bob and bob_adm side by side are a credential reuse gift. Service account names often reveal what software is installed. Accounts like secsvc or helpdesk suggest IT staff with elevated access. Worth investigating whether their profile directories are readable.
All Local Groups
C:\Windows\system32>net localgroup
Aliases for \\WINLPE-SRV01
-------------------------------------------------------------------------------
*Access Control Assistance Operators
*Administrators
*Backup Operators
*Certificate Service DCOM Access
*Cryptographic Operators
*Distributed COM Users
*Event Log Readers
*Guests
*Hyper-V Administrators
*IIS_IUSRS
[...]The default groups are noise. What you want to notice is anything custom; a group named after a department, a project, or a specific application. Non-standard groups sometimes exist purely to grant access to something sensitive, and their membership is often poorly maintained.
Also worth paying attention to:Remote Desktop Users,Remote Management Users(WinRM), andBackup Operators. These are default groups but non-default membership is a flag.
Group Details
net localgroup "Group Name"
Run this for any group that looks interesting, but always run it for administrators. You're looking for accounts that shouldn't be there: service accounts, regular user accounts, or domain groups that have been lazily added. Any of those is potentially a lateral movement path.Don't skip the Comment field on custom groups either. It sounds unlikely but credentials in group descriptions are a real finding.
Password Policy
C:\Windows\system32>net accounts
Force user logoff how long after time expires?: Never
Minimum password age (days): 0
Maximum password age (days): Unlimited
Minimum password length: 0
Length of password history maintained: None
Lockout threshold: Never
Lockout duration (minutes): 30
Lockout observation window (minutes): 30
Computer role: SERVER
The command completed successfully.The password policy tells you what you're up against before you start any credential attacks. The fields that matter:
Minimum password length: 0means passwords aren't enforced to meet any complexity bar. Short or blank passwords are possible.Lockout threshold: Nevermeans you can brute force local accounts without risk of locking anyone out. That's significant.Maximum password agetells you how stale credentials can get. 42 days is standard, but if you seeNeverthat means passwords may not have been rotated in years.Computer role: SERVERconfirms this isn't a workstation — it's worth noting for context.
And a third time: Check what you've learned!
That was quite a lot now wasn't it? We've covered maany commands that you can initially do to figure out what's going on. Next time we will go into Processes and user privileges more. See you then!
No spam, no sharing to third party. Only you and me.
Member discussion