Skip to content

Local privilege escalation: ProgramData directories created without restrictive ACLs #357

@Christophe-Rogiers

Description

@Christophe-Rogiers

Description

When Servy creates directories under C:\ProgramData\Servy\ (db, security, recovery), no explicit ACLs are set:

Affected locations:

  • src/Servy.Core/Helpers/AppFoldersHelper.cs (lines 63–65) — db\ directory
  • src/Servy.Core/Security/ProtectedKeyProvider.cs (line 182) — security\ directory
  • src/Servy.Service/Service.cs (line 648) — recovery\ directory
Directory.CreateDirectory(directory);  // inherits default ProgramData ACL

The default C:\ProgramData ACL grants the Users group write access to newly created subdirectories. This means any local non-admin user can:

  1. Modify the SQLite database (C:\ProgramData\Servy\db\Servy.db) to change service configurations — executable path, working directory, pre/post-launch hooks, environment variables
  2. Point a service's executable path to a malicious binary that then runs as the service account (potentially SYSTEM)
  3. Tamper with recovery files to reset restart attempt counters or cause denial-of-service
  4. Delete or corrupt DPAPI key files making all encrypted passwords unrecoverable

Severity

Critical — local privilege escalation (CWE-276: Incorrect Default Permissions). A low-privileged local user can escalate to SYSTEM by modifying the database to redirect a service's binary path.

Suggested fix

Set restrictive ACLs on C:\ProgramData\Servy\ immediately after creation:

var dirInfo = Directory.CreateDirectory(directory);
var security = dirInfo.GetAccessControl();
security.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
security.AddAccessRule(new FileSystemAccessRule(
    new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
    FileSystemRights.FullControl,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.None,
    AccessControlType.Allow));
security.AddAccessRule(new FileSystemAccessRule(
    new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
    FileSystemRights.FullControl,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.None,
    AccessControlType.Allow));
dirInfo.SetAccessControl(security);

Also ensure the installer (Inno Setup) sets the same ACLs during installation.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions