Remediation Guides

How to Remove GPP cpassword Passwords from SYSVOL (MS14-025)

26 September 2026 8 min read

A GPP cpassword is a password that Group Policy Preferences saved in an XML file on SYSVOL, encrypted with an AES key Microsoft itself published, so any domain user can read and decrypt it. Fix it by deleting every preference item that holds one, changing each exposed password, and installing MS14-025 (KB2962486) where it applies.

What the scanner is actually detecting

Scanner Finding title ID What it checks
Tenable Identity Exposure Reversible Passwords in GPO Indicator C-REVER-PWD-GPO GPO content in SYSVOL: GPP passwords and autologon settings. Rated Medium.
PingCastle Find Password GPO Rule A-PwdGPO GPO content in SYSVOL. Listed under Obfuscated Passwords in the report.
Nessus MS14-025: Vulnerability in Group Policy Preferences Could Allow Elevation of Privilege (2962486) Plugin 73984 Credentialed local check for the missing update on a Windows host. Rated High.

These are two different problems. Tenable Identity Exposure and PingCastle read the policy files and report passwords sitting in SYSVOL right now. Nessus plugin 73984 only reports that a host lacks the MS14-025 update (KB2928120, or KB2961899 on Windows 8.1 and Server 2012 R2 without update 2919355), which stops the Group Policy Management Editor from saving passwords. As Microsoft’s bulletin states, the update does not remove existing GPOs, so passwords already stored stay put.

The password lives in a cpassword attribute inside preference files under \<domain>SYSVOL<domain>Policies{GPO GUID}MachinePreferences or UserPreferences. The files that can carry one are Groups.xml (local users), Drives.xml (drive maps), Services.xml, ScheduledTasks.xml, DataSources.xml and Printers.xml. Tenable’s indicator also covers autologon, which a Registry preference (Registry.xml) can set with a plaintext DefaultPassword value.

Real-world risk

SYSVOL is readable by every authenticated domain user, and Microsoft documents the 32-byte AES key used for every GPP password in its MS-GPPREF specification. MITRE ATT&CK tracks the technique as T1552.006 and lists ready-made tools for it. Microsoft was aware of targeted attacks when it published the bulletin in 2014, and CISA added CVE-2014-1812 to its Known Exploited Vulnerabilities catalog in November 2021 with known ransomware campaign use.

The impact depends on the account. The classic case is a Local Users item that set one local Administrator password on every machine the GPO reached: one decrypted string gives admin rights on all of them. A domain service account in a Services or Scheduled Tasks item is worth whatever that account can do. If the password was already changed everywhere, the remaining exposure is small, but you rarely know that for certain, so PingCastle’s guidance is to treat any password found in a GPO as compromised.

How to confirm it

From any domain-joined machine, as an ordinary user, list the policy files that mention a password. /M prints only file names, so the encrypted values do not end up in your terminal history or ticket:

findstr /S /I /M cpassword \contoso.comSYSVOLcontoso.comPolicies*.xml
findstr /S /I /M DefaultPassword \contoso.comSYSVOLcontoso.comPolicies*.xml

A hit is not yet proof, because preference items saved without credentials can contain an empty cpassword=””. This PowerShell version (it needs the GroupPolicy module from GPMC or RSAT) keeps only non-empty values and resolves each folder GUID to a GPO name:

Import-Module GroupPolicy
$domain = $env:USERDNSDOMAIN
Get-ChildItem "\$domainSYSVOL$domainPolicies" -Recurse -Filter *.xml |
    Select-String -Pattern 'cpassword="[^"]+"', 'name="DefaultPassword"' -List |
    ForEach-Object {
        $guid = [regex]::Match($_.Path, '[0-9A-Fa-f]{8}(-[0-9A-Fa-f]{4}){3}-[0-9A-Fa-f]{12}').Value
        [pscustomobject]@{
            GPO  = (Get-GPO -Guid $guid -ErrorAction SilentlyContinue).DisplayName
            File = $_.Path
        }
    } | Format-Table -AutoSize -Wrap

You do not need to decrypt anything: the account name stored next to the cpassword (for example the userName attribute in Groups.xml and Drives.xml) tells you which account to reset. An empty GPO column usually means an orphaned folder whose GPO no longer exists in Active Directory. Microsoft’s own Get-SettingsWithCPassword.ps1, published in the KB2962486 article, produces a similar report.

For the Nessus finding, check the flagged host for the update:

Get-HotFix -Id KB2928120, KB2961899

How to fix it

1. Back up the affected GPOs

Backup-GPO -Name "Workstation Local Admin" -Path D:GPOBackup

The backup includes the cpassword, so restrict access to it and delete it when your rollback window closes.

2. Remove the preference items

Open each GPO in the Group Policy Management Editor and delete the item at the location below. Use the editor rather than deleting XML files by hand, so the GPO version number changes and clients process the update. If a GPO existed only for that item, remove the whole GPO with Remove-GPO -Name “<name>”.

File Editor location Replacement
Groups.xml Computer or User Configuration > Preferences > Control Panel Settings > Local Users and Groups Windows LAPS for local admin passwords
Drives.xml User Configuration > Preferences > Windows Settings > Drive Maps Share and NTFS permissions for the users themselves
Services.xml Computer Configuration > Preferences > Control Panel Settings > Services A built-in account, or a group Managed Service Account
ScheduledTasks.xml Computer or User Configuration > Preferences > Control Panel Settings > Scheduled Tasks Run as SYSTEM or a local service context, or only when the user is logged on
DataSources.xml Computer or User Configuration > Preferences > Control Panel Settings > Data Sources No GPP replacement; integrated authentication where supported
Printers.xml Computer or User Configuration > Preferences > Control Panel Settings > Printers Print permissions for the users themselves
Registry.xml (DefaultPassword) Computer Configuration > Preferences > Windows Settings > Registry Remove the autologon value

Delete any orphaned GPO folders found during the check once you have confirmed that no GPO in Active Directory references them.

3. Change every exposed password

Removing the item does not change any password: machines keep the last one the GPO set, and the old value may already be copied. For domain accounts, reset the password and then update every service, task or mapping that uses it:

Set-ADAccountPassword -Identity svc-backup -Reset -NewPassword (Read-Host -AsSecureString "New password")

For local administrator accounts the fix is a unique, rotating password per device, which is what Windows LAPS provides. It is built into Windows Server 2019 and later and supported Windows 11 releases (from the April 11, 2023 update onward). The basic Active Directory setup:

Update-LapsADSchema
Set-LapsADComputerSelfPermission -Identity "OU=Workstations,DC=contoso,DC=com"

Then link a GPO to that OU and, under Computer Configuration > Policies > Administrative Templates > System > LAPS, configure the BackupDirectory setting to back up passwords to Active Directory. Windows LAPS manages the built-in Administrator by default; if your old GPP item managed a custom account, configure AdministratorAccountName and make sure the account exists, because LAPS does not create it. Remove the GPP Local Users item in the same change, or Group Policy can keep writing the old password over the one LAPS stored. If the LAPS policy does not seem to reach some machines, check link order and filtering with our guide on why a GPO is not applying and how precedence works.

4. Patch or retire the management host

For plugin 73984, install KB2928120 (or KB2961899 where it applies) from the Microsoft Update Catalog. Every Windows version the bulletin covers is past the end of extended support, so the lasting fix is to run Group Policy administration from a supported server and retire the old host.

How to verify the fix and rescan

GPMC writes to the PDC emulator by default, but a scanner may read any domain controller, so check them all once SYSVOL has replicated:

$domain = (Get-ADDomain).DNSRoot
Get-ADDomainController -Filter * | ForEach-Object {
    $hits = Get-ChildItem "\$($_.HostName)SYSVOL$domainPolicies" -Recurse -Filter *.xml |
        Select-String -Pattern 'cpassword="[^"]+"', 'name="DefaultPassword"' -List
    "{0}: {1} file(s) still holding a password" -f $_.HostName, @($hits).Count
}

Every DC should report 0. On a sample of devices, run Invoke-LapsPolicyProcessing, look for event ID 10018 in the LAPS event log, and confirm the backup with Get-LapsADPassword -Identity PC01 | Select-Object ComputerName, Account, PasswordUpdateTime.

Then rescan. A new PingCastle healthcheck should no longer show A-PwdGPO, and the Tenable Identity Exposure indicator should stop listing the GPOs once it re-evaluates. For Nessus, rerun the credentialed scan against the patched host and confirm the login succeeded, because a scan that could not authenticate reports nothing either.

What can break and how to roll back

  • Drive maps that relied on alternate credentials stop working for users who lack their own permission on the share.
  • Services and scheduled tasks set up with that account generally keep their stored credentials after the item is deleted, then fail to log on once you reset the password. Reconfigure them before or with the reset.
  • Local admin access: anyone who used the shared password loses it once LAPS rotates it. That is the point; give support staff LAPS read permission instead.
  • Data sources that authenticated with a stored password fail until the application uses another method.

To roll back, Restore-GPO -Name “<name>” -Path D:GPOBackup brings back the previous settings, cpassword included. Use it only to recover other settings, then delete the credential item again. Never put a password back into a preference item; fix the dependent system instead.

Common false positive reasons

  • Empty attributes. A plain text search matches cpassword=””, which holds no password. PingCastle’s rule is built around passwords it was able to retrieve, so check which tool raised the hit.
  • Replication lag: the scanner read a domain controller whose SYSVOL had not yet received your change.
  • Nessus on hosts without the management tools. Per Microsoft, clients are affected only with RSAT installed and servers only when Group Policy Management is configured. If neither applies, document it and dispute the finding.
  • “The password was changed long ago.” Not a false positive. The item is still published, and the fix is to delete it.

FAQ

Isn’t the cpassword encrypted?

Yes, with AES, but Microsoft publishes the key in the MS-GPPREF specification, so treat the value as plaintext.

Does installing KB2962486 remove passwords already in SYSVOL?

No. It only stops the editor from saving new ones. Existing items stay until you delete them.

The GPO is disabled or unlinked. Is it still a risk?

Yes. The XML file is still in SYSVOL and readable by every domain user until the item or the GPO is deleted.

Do I have to change the password after deleting the item?

Yes. Deleting the item stops publishing the password but does not change it on any system.

Tracking this finding across many hosts

The SYSVOL side of this finding is fixed once per domain, while plugin 73984 can appear on every legacy host that ran the management tools. SITEY, a self-hosted vulnerability management platform, imports Nessus results when you upload a .nessus export (it does not pull them automatically), and per-finding retest works for Nessus findings, so it can confirm when 73984 has closed on each host. Keep the SYSVOL search above as your check for the directory side.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing