HackBlue

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.

10 min read · practice only with authorization

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.

Snippet
Get-CimInstance Win32_Service | Where-Object { $_.PathName -notmatch '^"' -and $_.PathName -match ' ' -and $_.PathName -notmatch '^C:\\Windows\\' } | Select Name, StartName, PathName

Writable 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.

Snippet
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.

Snippet
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?