GP3Finder – Group Policy Preference Password Finder

Group Policy preferences were introduced by Microsoft in Windows 2008 allowing administrators to configure unmanaged settings (settings which the user can change) from a centrally managed location – Group Policy Objects (GPO) [1].

Among the preference items configurable through Group Policy preferences are several that can contain credentials: Local Groups and User Accounts, Drive Mappings, Schedule Tasks, Services, and Data Sources.

These credentials are stored within the preference item in SYSVOL in the GPO containing that preference item. In order to obscure the password from casual users it is encrypted in the XML source code of the preference item [2]. However anyone who gains access to SYSVOL can decrypt the passwords because Microsoft published the Advanced Encryption Standard (AES) encryption key [1]:

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

Microsoft addressed this issue in MS14-025 [4] however this update only prevented the creation of new Group Policy Preference items containing credentials; it did not remove any existing instances as this was considered too disruptive. Therefore network administrators must take action to find and remove these vulnerable items.

Several tools exist to exploit this vulnerability including:

Get-GPPPassword (PowerShell – http://obscuresecurity.blogspot.co.uk/2012/05/gpp-password-retrieval-with-powershell.html)

gpp (Metasploit Post Module – http://www.rapid7.com/db/modules/post/windows/gather/credentials/gpp)

gpprefdecrypt.py (Python – http://esec-pentest.sogeti.com/public/files/gpprefdecrypt.py)

gpp-decrypt-string.rb (Ruby – http://carnal0wnage.attackresearch.com/2012/10/group-policy-preferences-and-getting.html)

However each of these existing tools have a significant weakness. Get-GPPPassword must be run from a Windows machine, the gpp Metasploit post module requires a meterpreter session, gpprefdecrypt.py and gpp-decrypt-string.rb require you to manually extract the cpassword for decryption, and finally the version of gpprefdecrypt.py available for download no longer works at the time of writing (due to an update to PyCrypto that removed the default iv of 16 bytes of zeros).

I therefore wrote a new cross platform tool, dubbed GP3Finder (Group Policy Preference Password Finder), to automate the process of finding, extracting and decrypting passwords stored in Group Policy preference items. This tool is written in Python (2.7) and depends on PyCrypto and PyWin32 on Windows or subprocesses on *nix based operating systems.

GP3Finder has been released open source under the GPL2 license here a compiled executable for Windows is also available here.

Update v4.0

On a recent test I had compromised a single Windows host and had remote desktop access as a low privilege user. Since I couldn’t map the C$ share remotely, and didn’t want to search through the dozens of Group Policy Preference items using built in Windows utilities, I quickly added the functionality to gp3finder instead.

Note: Group Policy Preferences are cached locally under the (hidden) directory: “C:\ProgramData\Microsoft\Group Policy\History\” by default.

In this update I also add the option to specify the start path when searching a remote share. This allows you to quickly search for Group Policy Preference passwords when you have access to the C$ share without searching the entire drive.

Another significant change is that you can now specify multiple hosts to search – ideal if you have access to C$ on a number of hosts and want to check all of them. Note, this functionality is not threaded (yet) so can take some time to complete.

Finally I have changed some of the command line options to ensure they are as intuitive as possible (see below or –help).

Example Usage

Decrypt a given cpassword:

gp3finder.py -D CPASSWORD

The following commands output decrypted cpasswords (from Groups.xml etc) and list of xml files that contain the word ‘password’ (for manual review) to a file (‘gp3finder.out’ by default, this can be changed with -o FILE).

Find and decrypt cpasswords on domain controller automatically:

gp3finder.py -A -t DOMAIN_CONTROLLER -u DOMAIN\USER
 Password: PASSWORD

Maps DOMAIN_CONTROLLER’s sysvol share with given credentials.

Find and decrypt cpasswords on the local machine automatically:

gp3finder.py -A -l

Searches through “C:\ProgramData\Microsoft\Group Policy\History” (by default) this can be changed with -lr PATH

Find and decrypt cpasswords on a remote host:

gp3finder.py -A -t HOST -u DOMAIN\USER -s C$ -rr "ProgramData\Microsoft\Group Policy\History"

Find and decrypt cpasswords on hosts specified in a file (one per line):

gp3finder.py -A -f HOST_FILE -u DOMAIN\USER -s C$ -rr "ProgramData\Microsoft\Group Policy\History"

Note: the user this script is run as must have permission to map/mount shares if running against a remote host.

Additional options are available:

gp3finder.py --help

References

[1] [Online]. Available: http://www.microsoft.com/en-us/download/details.aspx?id=24449).
[2] [Online]. Available: http://blogs.technet.com/b/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx.
[3] [Online]. Available: http://msdn.microsoft.com/en-us/library/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be.aspx.
[4] [Online]. Available: http://blogs.technet.com/b/srd/archive/2014/05/13/ms14-025-an-update-for-group-policy-preferences.aspx.


 

As always, if you have any comments or suggestions please feel free to get in touch.

5 thoughts on “GP3Finder – Group Policy Preference Password Finder”

  1. Hi there,

    If I use the -E switch to encrypt plaintext for “3rKb45rV”, I’ll get this:

    E96x4zScqtIZc7dGnJAoDxYBa+RvGYh90cK1YoVm+Yw

    If I put that into the Drive.xml file that GPP references and load up my user account, the drive will fail to map due to a network password error (0x80070056).

    If I were to use a Windows Server 2008 DC to create the drive map, the cPassword attribute turns out to be:

    LehuaWEr7GE2pOY47SZTTK5EA51GcCyOT9ct0h1d7hQ

    If I then use your tool to decrypt that cpassword, it gives you the same plaintext string.

    Basically, different encrypted cpasswords give you the same plaintext string, but only one of the cpassword works in drive.xml.

    I know it is recommended to stop using cpassword with GPP, but our company still use it for reasons I won’t delve into. We do not have a 2008 DC anymore (the one I used earlier was just a test VM I spun up), therefore I’m using your tool to generate the cpassword.

    1. Hi Ricky

      I would first like to reiterate that using group policy preferences with passwords in them is a security vulnerability! Any attacker with a domain account can recover the credentials you are configuring.
      I hope you can work to remove them from your environment in the near future!

      However, thank you for letting me know about that error, I’ve tracked it down and it appears to be due to an incorrect conversion (utf-8 to utf-16 rather than to utf-16le). I have pushed a fix which resolves the problem for the example you gave, please let me know if you find it does not work.

      1. Thanks for the fast response!

        We are aware of the security issue. We’ve looked at the recommendations, however they do not really apply to us…

        For example, we have a few clients are running servers in a Workgroup (for security or other specific reasons). These servers could be hosting databases, or file server stuff. Most of the time, these servers will have shares that will need to be mapped as drives in user sessions. Some users may have access to certain drives, some don’t.

        To control this, we obviously need separate share credentials. The old GPP provides this sort of setup, but having that removed means we need to implement some sort of workaround (we haven’t found one yet).

  2. I’ve downloaded the updated .py file and tried to convert it to .exe myself with py2exe. I’ve run the .exe but I’m getting a bunch of errors…..Would you be able to provide the the updated .exe as well?

Leave a Reply

Your email address will not be published. Required fields are marked *