Tools · Windows security and Event Logs · 23 / 27
Auditing Windows services: unquoted paths, weak permissions, and service accounts
Find services with unquoted paths containing spaces, binaries in writable folders, and services running as privileged user accounts, and fix them.
Unquoted service paths
If a service’s path contains spaces and is not quoted, such as C:\Program Files\Acme Tool\svc.exe, Windows tries C:\Program.exe, then C:\Program Files\Acme.exe, before the real binary. If a standard user can write to any of those earlier locations, they can place a program there that runs as the service account at next start.
Most systems protect C:\ and Program Files, so the real risk appears when software installs to a custom folder with loose permissions. The fix is simple: quote the path in the service’s ImagePath.
Get-CimInstance Win32_Service | Where-Object { $_.PathName -notmatch '^"' -and $_.PathName -match ' ' -and $_.PathName -notmatch '^C:\\Windows\\' } | Select Name, StartName, PathNameWritable binaries and folders
A service binary or its folder that Users or Everyone can modify lets any user replace it with their own program, which then runs as the service account, often SYSTEM. icacls shows file and folder permissions. Look for (F), (M), or (W) granted to Users, Authenticated Users, or Everyone.
Service configuration permissions matter too. sc.exe sdshow name prints the service’s security descriptor; standard users should not have rights to change its configuration.
Get-CimInstance Win32_Service | ForEach-Object {
$p = ($_.PathName -replace '^"([^"]+)".*','$1') -replace ' -.*#x27;,''
if (Test-Path $p) { $a = icacls $p | Select-String 'Everyone|BUILTIN\\Users|Authenticated Users' | Select-String '\((F|M|W)' ; if ($a) { "$($_.Name): $a" } } }Lab: create a vulnerable service and fix it
On a lab VM, create a folder C:\Apps\Lab Tool, grant Users modify permission, and register a service with an unquoted path to a harmless executable inside it. Run both audit commands and confirm the service is flagged twice. Fix it by quoting the ImagePath in the registry and removing the Users modify permission, then rerun the audit.
The registry key is HKLM\SYSTEM\CurrentControlSet\Services\name, value ImagePath.
New-Item -ItemType Directory 'C:\Apps\Lab Tool' | Out-Null icacls 'C:\Apps\Lab Tool' /grant 'BUILTIN\Users:(OI)(CI)M' Copy-Item C:\Windows\System32\cmd.exe 'C:\Apps\Lab Tool\labsvc.exe' sc.exe create LabTool binPath= "C:\Apps\Lab Tool\labsvc.exe" start= demand # fix Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\LabTool ImagePath '"C:\Apps\Lab Tool\labsvc.exe"' icacls 'C:\Apps\Lab Tool' /remove:g 'BUILTIN\Users' sc.exe delete LabTool
Service accounts
Services running as domain user accounts, especially privileged ones, expose those credentials on every machine the service runs on. Use virtual accounts, Local Service, Network Service, or group Managed Service Accounts (gMSA), which rotate their own long passwords automatically.
List services by StartName and look for named domain users. Each one is a credential to protect and a candidate for gMSA migration.
Diagram
Three service weaknesses
Each lets a standard user run code as the service account.
- Unquoted path with spaces
Windows tries earlier path segments first.
- Writable binary or folder
Replace the program and wait for a restart.
- Weak service DACL
Change the binary path through the service manager.
- Privileged user account
Exposes a domain credential on the host.
Check yourself
1. Why is an unquoted service path with spaces risky?
2. Which icacls result is a problem on a service binary?
3. What is the preferred account type for a service that needs domain access?