Haxoris Wiki

Insecure Service Permissions And Unquoted Paths

How Insecure Service Permissions And Unquoted Paths works

Insecure service permissions turn a standard user into SYSTEM or root through configuration alone, with no exploit needed. The weakness lives in how a service was installed: a path with a space left unquoted, an ACL that grants SERVICE_CHANGE_CONFIG to Users, a binary or its folder writable by non-admins, or a writable directory on the machine %PATH%.

The attacker plants or points the service at their own file and the operating system runs it at the service’s privilege on next start or reboot. The Linux equivalents are world-writable systemd unit files, over-broad sudoers rules and writable cron directories. It is easy to miss because the service works perfectly - the flaw is in the metadata a functional-test never reads, and installers frequently set these permissions without anyone reviewing the resulting ACL.

Insecure Service Permissions And Unquoted Paths in practice

Enumerate unquoted service paths on Windows

Start with the classic: a service ImagePath containing a space and no quotes, where Windows tries each split point as an executable.

# List auto-start services whose binary path has a space and is not quoted.
Get-CimInstance Win32_Service |
  Where-Object { $_.PathName -notmatch '^\s*"' -and $_.PathName -match ' ' -and
                 $_.PathName -notmatch '^\s*[A-Za-z]:\\Windows\\' } |
  Select-Object Name, StartMode, PathName
# "C:\Program Files\Vendor App\svc.exe" split -> C:\Program.exe, C:\Program Files\Vendor.exe

Test the ACLs that make it exploitable

An unquoted path is only a finding if a standard user can write to an earlier segment, and a quoted path can still fall to a weak service ACL. Test both, read-only.

Unquoted path check:
  For each gap dir (e.g. C:\, "C:\Program Files\Vendor App\") test write as the
  low-priv user. Writable + auto-start service = plant C:\Program.exe -> SYSTEM.

Service ACL check (accesschk, read-only query):
  accesschk.exe -uwcqv "corp\lowpriv" *      # SERVICE_CHANGE_CONFIG / WRITE_DAC?
  A service where Users hold SERVICE_CHANGE_CONFIG can be repointed with sc config.

Binary/dir ACL check:
  accesschk.exe -quv "corp\lowpriv" "C:\Program Files\Vendor App"   # write on the
  exe or its folder = overwrite the binary directly.

Check writable %PATH% entries

A standard-user-writable directory that sits on the system %PATH% lets an unqualified binary call resolve to an attacker file. Enumerate and test each entry.

# Split system PATH and flag directories writable by the current user.
$env:Path -split ';' | Where-Object { $_ } | ForEach-Object {
  $p = $_.Trim('"')
  if (Test-Path $p) {
    try { $t = Join-Path $p ".wtest"; New-Item $t -ItemType File -EA Stop |
      Remove-Item -EA Stop; "WRITABLE  $p" } catch { }
  }
}
# Any WRITABLE line earlier than %WINDIR% is a hijack candidate.

Enumerate the Linux equivalents

Same class, different objects: unit files, sudoers and cron paths that a non-root user can influence.

# World-writable or user-writable systemd unit files -> edit ExecStart, restart -> root.
find /etc/systemd/system /lib/systemd/system -perm -o+w -o -writable 2>/dev/null
# Sudoers rules that grant more than intended (NOPASSWD, wildcards, editors).
sudo -l 2>/dev/null; grep -R "NOPASSWD\|ALL=(ALL)" /etc/sudoers /etc/sudoers.d 2>/dev/null
# Writable cron directories and job files run as root on schedule.
find /etc/cron* /var/spool/cron -writable 2>/dev/null -ls

How to fix and prevent Insecure Service Permissions And Unquoted Paths

  1. Quote every service binary path
    • Wrap the ImagePath in quotes at install time and audit existing services; a quoted path removes the split-point hijack entirely.
  2. Tighten service ACLs to admins only
    • Remove SERVICE_CHANGE_CONFIG, WRITE_DAC and WRITE_OWNER from non-administrative principals so a service cannot be repointed by a standard user.
  3. Keep binaries and their folders off writable locations
    • Install under Program Files with default inherited ACLs and confirm no non-admin holds write on the executable or its directory.
  4. Clean the system %PATH% and unit files
    • Remove standard-user-writable directories from the machine PATH, and set systemd unit files to root-owned 0644 so ExecStart cannot be edited.
  5. Constrain sudo and cron
    • Replace broad NOPASSWD and wildcard sudoers rules with specific commands, and make cron directories and job files root-owned and non-writable by users.

Last updated

References