Skip to main content
cd ../config-traps
risk/register/sysvol-cpassword-the-gpp-field-that-never-died.html
Active Directory Group Policycritical severityActive Directory / Group Policy

SYSVOL cpassword: The GPP Field That Never Died

Overview

Legacy Group Policy Preferences store cpassword credentials in SYSVOL XML files encrypted with a static AES key Microsoft published years ago. MS14-025 blocked new GUI writes but never purged existing files, so any authenticated domain user can decrypt them instantly and gain shared local admin access fleet-wide.

At a glance

Unsafe setting
cpassword credentials stored in SYSVOL GPP XML encrypted with Microsoft's publicly known static AES key
Failure trigger
Any domain-authenticated user reads SYSVOL Policies folder and decrypts cpassword with published key or gpp-decrypt
Blast radius
Decrypted shared local admin password grants SMB/WinRM access to every machine the GPO applied to.
Recommended control
Scan SYSVOL for cpassword, delete offending GPO items, rotate exposed passwords, migrate to Microsoft LAPS.

Fix commands and configuration

Get-ChildItem -Path "\<domain>SYSVOL<domain>Policies" -Recurse -Include *.xml | Select-String "cpassword"

The Trap

Group Policy Preferences cpassword fields left in SYSVOL Groups.xml, Drives.xml, Services.xml, ScheduledTasks.xml, and DataSources.xml. These files store credentials pushed via GPP wizards using a single AES-256 key that Microsoft published openly in its GPP documentation. The key is identical on every domain that has ever used the feature.

The Default State

Domain admins used the GPP GUI to set local admin passwords, map network drives with service credentials, or schedule tasks under a domain account, because it avoided touching local SAM databases individually. The wizard writes the password into an XML attribute called cpassword, encrypted with the published static key rather than anything domain-specific. SYSVOL grants Authenticated Users read access by default, since every domain member must read GPOs to apply policy. MS14-025, released in 2014, stops the GUI from writing new cpassword values but does not scan SYSVOL and remove ones already there, and it does nothing to files created through scripted or third-party GPP tooling.

The Blast Radius

Any domain-joined device, including a kiosk machine, a service account with no elevated rights, or a compromised low-privilege workstation, can browse \domainSYSVOLdomainPolicies{GUID} and pull the XML. Decryption is a single published AES key away using tools like Get-GPPPassword or Metasploit’s gpp-decrypt module, and it returns plaintext instantly. Because these credentials were typically set as a shared local admin password across an OU or the entire fleet to simplify management, one decrypted string grants SMB/WinRM admin access to every machine the GPO applied to. An attacker with zero prior privilege escalation moves from domain-authenticated to local admin on hundreds of hosts in the time it takes to run one PowerShell one-liner.

The Lead Mechanic Fix

Audit every domain controller’s SYSVOL tree regardless of patch level: Get-ChildItem -Path "\<domain>SYSVOL<domain>Policies" -Recurse -Include *.xml | Select-String "cpassword". Treat any hit as a confirmed credential compromise, not a hygiene finding. Delete the offending GPO preference items, then rotate every local admin password those GPOs ever distributed, because the string has had years to leak into logs, backups, and attacker toolkits. Replace credential distribution entirely with Microsoft LAPS, which stores a unique, randomly generated password per machine in the confidential ms-Mcs-AdmPwd attribute, protected by a delegated ACL rather than a static published key. Disable GPP credential-based preference processing at the OU level via GPO to prevent recreation.