Hunting Windows service privilege escalation: when a standard user decides what SYSTEM runs
A Windows service usually runs as a high-privileged account, often the local system account, and the service
manager starts whatever binary the service configuration names. That is safe only if a low-privileged user
cannot influence which binary runs or where it is found. When they can, the service becomes an escalation:
the user changes the configured binary because the service object grants them that right, or replaces the
binary because its file or directory is writable, or plants a file earlier on an unquoted path because an
intervening directory is writable, or rewrites the service's registry configuration because its key is
weakly permissioned. At the next start, the privileged account runs the attacker's code. The bug is not the
service running as system; it is a standard user holding a write that reaches what system executes. You find
these by listing services and asking, for each, whether a non-admin can change the binary, the path, or the
config.
When to use
- A Windows host runs services as a privileged account and you can enumerate their config and permissions.
- Service binaries, their directories, or unquoted service paths may be writable by a standard user.
- Service objects or their registry keys may grant configuration rights to non-administrators.
Scope check
Test service escalation only on hosts you own or are authorized to assess, on non-production or a snapshot,
using a benign marker payload that proves execution as the privileged account rather than taking real action
with it. A confirmed path yields code execution as a system account, so keep every probe within the
authorized scope. If you can't name the authorization, stop.
The loop
Establish the service's account and who can influence its target first. For each service, determine
the account it runs as and whether a standard user holds any write that reaches what it executes: a
service-object right to reconfigure it, write access to the binary or its directory, a writable directory
earlier on an unquoted path, or write access to the service's registry key. This is the false-positive
killer: a service whose binary, path, and configuration are writable only by administrators cannot be
redirected by a standard user, however privileged the account it runs as. Name the specific write before
claiming a path.
Enumerate services and their configured targets. List installed services, the account each runs as,
the full command line and binary path, and the start type. Services that run as a privileged account and
start automatically or can be started by a standard user are the candidates; note the exact binary and
path for each.
Check the service object permissions. Determine whether the service's access control grants a
standard user or a broad group the right to change its configuration or start it. A right to reconfigure
the binary path is a direct escalation; a right only to query is not. Read the granted rights, not the
default assumption.
Check the on-disk and path writes. Determine whether the binary itself, the directory holding it, or,
for an unquoted path containing spaces, any earlier directory on the resolution order is writable by a
standard user. A writable binary is replaced; a writable directory lets a same-named file shadow the
target; an unquoted path lets a file plant earlier in the sequence win.
Check the registry configuration write. Determine whether the service's registry key, which holds the
image path and the account, is writable by a standard user. A write there rewrites what the service
manager launches and under which account, independent of the file permissions.
Confirm and record. Confirm by placing a benign marker binary through the specific write and observing
the privileged account execute it at the next service start on an isolated host. Kill the lead if the
binary, its directory, the whole unquoted path, the service object, and the registry key are all
writable only by administrators, or if the service runs as an unprivileged account no higher than the
attacker. Record the service, the account, the specific write, and the execution observed, or set a
kill_reason.
Where service escalation leaks
- The write is the finding, not the account. A service running as system is normal; a standard user
holding a write that reaches its binary, path, or config is the escalation. Name the write.
- Service object DACLs drift. A service whose access control was loosened to let an application or an
installer manage it can grant a standard user the right to repoint the binary.
- Writable binaries and directories replace the target. A binary or its containing directory writable by
a non-admin lets the attacker overwrite or shadow what the privileged account runs.
- Unquoted paths with spaces resolve early. A path with spaces and no quotes lets the service manager try
earlier truncations first, so a planted file in a writable earlier directory runs instead.
- The registry key is a second door. The service's configuration key holding the image path and account
is an escalation if it is writable, even when the file permissions are correct.
Worked example (a confirm and a kill)
Confirm. An installed service runs as the local system account with an unquoted image path under a
directory a standard user can write to, and spaces in the path let an earlier truncation resolve first. A
benign marker binary planted at the earlier name is executed by the system account at the next start on an
isolated host. Confirmed local privilege escalation from standard user to system through an unquoted
service path, high, remediation = quote the service image path, place service binaries only in
directories writable exclusively by administrators, and restrict the service object and its registry key to
administrators.
Kill. The same service uses a fully quoted image path, its binary and directory are writable only by
administrators, the service object grants standard users query rights only, and its registry key is
admin-writable. A standard user can neither repoint the service nor plant a file the manager would run.
Killed, kill_reason = "binary, path, service object, and registry key are all admin-only writable; no
standard-user write reaches what the privileged account executes."
Rationalizations to reject
- "The service runs as system, so of course it is powerful." -> Power is expected; the finding is a
standard-user write that redirects it. Without such a write there is no escalation.
- "The binary is not writable." -> Check the directory, the unquoted path, the service object, and the
registry key too; any one of them redirects execution even when the file is protected.
- "The path has spaces but it usually works." -> Usual resolution is not the point; an unquoted path with
a writable earlier directory lets a planted file win at the next start.
- "Only an installer touches that service." -> If the installer loosened the service DACL to a broad group,
a standard user in that group inherits the right to reconfigure it.
- "You need admin to change a service." -> Only if the service object and registry key enforce that; a
drifted DACL or key permission can grant reconfiguration to a standard user.
Executing this in practice
You need every service with its account, image path and command line, start type, service object
permissions, and registry key permissions, plus the write permissions on each binary and its directory. For
each privileged service, decide whether a standard user holds any write that reaches the executed target,
through the object, the file, the path, or the key. Reading the permissions settles most leads; planting a
benign marker through the specific write and observing execution as the privileged account on an isolated
host settles the rest.
Related
hunting-scheduled-job-and-search-path-hijacks - the scheduled-task and search-path equivalent of this
write-reaches-execution reasoning, sharing the planted-file and path-resolution analysis.
hunting-windows-dll-hijacking-and-search-order - a service that loads a missing or writable library is
redirected by the search-order gap that skill covers, a common companion to a service path finding.
auditing-windows-token-and-privilege-abuse - once code runs as a service account, the privileges that
account holds are the next lever, which that skill audits.
hunting-setuid-and-capability-escalation - the Unix counterpart, where a privileged binary rather than a
service is the carrier, sharing the escalation-from-a-write shape.
- FINDING-SCHEMA.md - source = the standard-user control over the service config or
its on-disk target, sink = the service manager starting the binary as a privileged account, evidence = the
privileged account executing a planted marker at service start on an isolated host.
1---2name: hunting-windows-service-privilege-escalation3description: Hunt local privilege escalation through Windows service misconfiguration, where a low-privileged user can influence what a service runs as a higher-privileged account, through a weak service object permission, a writable service binary or its directory, an unquoted service path with a writable intervening directory, or a weak permission on the service's registry configuration. Use when reviewing installed services and their binaries, paths, and permissions on a Windows host for a standard-user-to-SYSTEM path. Covers weak service DACLs, writable binaries and paths, unquoted paths, and writable service registry keys. The standard-user control over service configuration or its on-disk target is the source, the service manager starting the binary as a privileged account is the sink, and running attacker-chosen code as that account is the bug.4license: MIT5---67# Hunting Windows service privilege escalation: when a standard user decides what SYSTEM runs89A Windows service usually runs as a high-privileged account, often the local system account, and the service10manager starts whatever binary the service configuration names. That is safe only if a low-privileged user11cannot influence which binary runs or where it is found. When they can, the service becomes an escalation:12the user changes the configured binary because the service object grants them that right, or replaces the13binary because its file or directory is writable, or plants a file earlier on an unquoted path because an14intervening directory is writable, or rewrites the service's registry configuration because its key is15weakly permissioned. At the next start, the privileged account runs the attacker's code. The bug is not the16service running as system; it is a standard user holding a write that reaches what system executes. You find17these by listing services and asking, for each, whether a non-admin can change the binary, the path, or the18config.1920## When to use2122- A Windows host runs services as a privileged account and you can enumerate their config and permissions.23- Service binaries, their directories, or unquoted service paths may be writable by a standard user.24- Service objects or their registry keys may grant configuration rights to non-administrators.2526## Scope check2728Test service escalation only on hosts you own or are authorized to assess, on non-production or a snapshot,29using a benign marker payload that proves execution as the privileged account rather than taking real action30with it. A confirmed path yields code execution as a system account, so keep every probe within the31authorized scope. If you can't name the authorization, stop.3233## The loop34351. **Establish the service's account and who can influence its target first.** For each service, determine36 the account it runs as and whether a standard user holds any write that reaches what it executes: a37 service-object right to reconfigure it, write access to the binary or its directory, a writable directory38 earlier on an unquoted path, or write access to the service's registry key. This is the false-positive39 killer: a service whose binary, path, and configuration are writable only by administrators cannot be40 redirected by a standard user, however privileged the account it runs as. Name the specific write before41 claiming a path.42432. **Enumerate services and their configured targets.** List installed services, the account each runs as,44 the full command line and binary path, and the start type. Services that run as a privileged account and45 start automatically or can be started by a standard user are the candidates; note the exact binary and46 path for each.47483. **Check the service object permissions.** Determine whether the service's access control grants a49 standard user or a broad group the right to change its configuration or start it. A right to reconfigure50 the binary path is a direct escalation; a right only to query is not. Read the granted rights, not the51 default assumption.52534. **Check the on-disk and path writes.** Determine whether the binary itself, the directory holding it, or,54 for an unquoted path containing spaces, any earlier directory on the resolution order is writable by a55 standard user. A writable binary is replaced; a writable directory lets a same-named file shadow the56 target; an unquoted path lets a file plant earlier in the sequence win.57585. **Check the registry configuration write.** Determine whether the service's registry key, which holds the59 image path and the account, is writable by a standard user. A write there rewrites what the service60 manager launches and under which account, independent of the file permissions.61626. **Confirm and record.** Confirm by placing a benign marker binary through the specific write and observing63 the privileged account execute it at the next service start on an isolated host. Kill the lead if the64 binary, its directory, the whole unquoted path, the service object, and the registry key are all65 writable only by administrators, or if the service runs as an unprivileged account no higher than the66 attacker. Record the service, the account, the specific write, and the execution observed, or set a67 `kill_reason`.6869## Where service escalation leaks7071- **The write is the finding, not the account.** A service running as system is normal; a standard user72 holding a write that reaches its binary, path, or config is the escalation. Name the write.73- **Service object DACLs drift.** A service whose access control was loosened to let an application or an74 installer manage it can grant a standard user the right to repoint the binary.75- **Writable binaries and directories replace the target.** A binary or its containing directory writable by76 a non-admin lets the attacker overwrite or shadow what the privileged account runs.77- **Unquoted paths with spaces resolve early.** A path with spaces and no quotes lets the service manager try78 earlier truncations first, so a planted file in a writable earlier directory runs instead.79- **The registry key is a second door.** The service's configuration key holding the image path and account80 is an escalation if it is writable, even when the file permissions are correct.8182## Worked example (a confirm and a kill)8384> **Confirm.** An installed service runs as the local system account with an unquoted image path under a85> directory a standard user can write to, and spaces in the path let an earlier truncation resolve first. A86> benign marker binary planted at the earlier name is executed by the system account at the next start on an87> isolated host. **Confirmed** local privilege escalation from standard user to system through an unquoted88> service path, `high`, remediation = quote the service image path, place service binaries only in89> directories writable exclusively by administrators, and restrict the service object and its registry key to90> administrators.91>92> **Kill.** The same service uses a fully quoted image path, its binary and directory are writable only by93> administrators, the service object grants standard users query rights only, and its registry key is94> admin-writable. A standard user can neither repoint the service nor plant a file the manager would run.95> **Killed**, `kill_reason` = "binary, path, service object, and registry key are all admin-only writable; no96> standard-user write reaches what the privileged account executes."9798## Rationalizations to reject99100- *"The service runs as system, so of course it is powerful."* -> Power is expected; the finding is a101 standard-user write that redirects it. Without such a write there is no escalation.102- *"The binary is not writable."* -> Check the directory, the unquoted path, the service object, and the103 registry key too; any one of them redirects execution even when the file is protected.104- *"The path has spaces but it usually works."* -> Usual resolution is not the point; an unquoted path with105 a writable earlier directory lets a planted file win at the next start.106- *"Only an installer touches that service."* -> If the installer loosened the service DACL to a broad group,107 a standard user in that group inherits the right to reconfigure it.108- *"You need admin to change a service."* -> Only if the service object and registry key enforce that; a109 drifted DACL or key permission can grant reconfiguration to a standard user.110111## Executing this in practice112113You need every service with its account, image path and command line, start type, service object114permissions, and registry key permissions, plus the write permissions on each binary and its directory. For115each privileged service, decide whether a standard user holds any write that reaches the executed target,116through the object, the file, the path, or the key. Reading the permissions settles most leads; planting a117benign marker through the specific write and observing execution as the privileged account on an isolated118host settles the rest.119120## Related121122- `hunting-scheduled-job-and-search-path-hijacks` - the scheduled-task and search-path equivalent of this123 write-reaches-execution reasoning, sharing the planted-file and path-resolution analysis.124- `hunting-windows-dll-hijacking-and-search-order` - a service that loads a missing or writable library is125 redirected by the search-order gap that skill covers, a common companion to a service path finding.126- `auditing-windows-token-and-privilege-abuse` - once code runs as a service account, the privileges that127 account holds are the next lever, which that skill audits.128- `hunting-setuid-and-capability-escalation` - the Unix counterpart, where a privileged binary rather than a129 service is the carrier, sharing the escalation-from-a-write shape.130- [FINDING-SCHEMA.md](../../FINDING-SCHEMA.md) - source = the standard-user control over the service config or131 its on-disk target, sink = the service manager starting the binary as a privileged account, evidence = the132 privileged account executing a planted marker at service start on an isolated host.