While Privilege Escalation via Group Policy Preferences (GPP) is not a new topic in the penetration testing world by any means [Chris Gates (@carnal0wnage) and others were speaking about this way back in 2012], it is still prevalent across many networks today. It is important enough to talk about because it is "low-hanging fruit" for pentesters (and hackers) and it is often one of the first things checked for after an initial foothold into a network. As it can quickly allow for escalation to Local Administrator and lateral movement, it is often just a matter of time before complete Domain compromise.
What is GPP?
GPP was introduced with the release of Server 2008 and allows for configuration of Domain-attached machines via group policy. Domain machines periodically reach out and authenticate to the Domain Controller utilizing the Domain credentials of the logged-in user (these can be, and often are, unprivileged accounts), and then synchronize policies. These policies can make all sorts of configuration changes to machines, to include:
- Start Menu Items
- Network Drive Mapping
- Registry Settings
- Printer Configuration
The Group Policy Preferences (GPP) Vulnerability
The most interesting (and dangerous) feature of GPP is the ability to set passwords for the Local Administrator account. Group Policies for account management are stored on the Domain Controller in "Groups.xml" files buried in the SYSVOL folder. For example, below is a screenshot from my domain-connected workstation, where I have browsed to the SYSVOL folder on the Domain Controller (again, authenticating with my unprivileged Domain Credentials). Please note that while there are only a couple "Groups.xml" in this scenario, a typical corporate server will most likely have many files, corresponding to a large variety of account configuration policies implemented over the years.
While some of these files may only contain something as simple as a configuration to rename an existing account, what we are interested in as pen testers are files that contain the "cpassword" field. These policies will actually set the password for the contained account. Below is a screenshot of one such file from the Domain Controller:
As you can see above, the value of the "cpassword" field appears to be jibberish. This is because Microsoft encrypts it with AES (using a 32-bit key... yikes!). The news gets worse upon visiting the MSDN site, which reveals the key utilized with AES is static AND publicly available:
What this means for us as pen testers is that if we have access to ANY Domain account, we can pull down the "cpassword" values for accounts stored on the Domain Controller and simply decrypt the plaintext password. Given that these policies are set in order to manage multiple machines in a Domain, we can often move laterally, authenticating with Local Administrator privileges to a number of other machines. This freedom to move around the network can open all sorts of opportunities for further exploitation. Let's take a look...
Exploiting the Group Policy Preferences Vulnerability
We are going to start with an "assumed breach" scenario, in which I currently have a shell on a Domain computer (for the sake of this demonstration, let's say an ignorant Domain user Steve, who is logged onto a domain-connected machine, has been successfully phished):
Now that I have a foothold on this Domain machine with the phished user's Domain credentials, I also have read access to the "Groups.xml" files stored on the Domain Controller. Utilizing my meterpreter session, I'm going to load a Metasploit module (post/windows/gather/credentials/gpp), which will easily retrieve any "cpassword" values stored and decrypt them utilizing the known AES key:
And there it is: the plaintext password for the Local Administrator account! Another method of retrieving these credentials is by utilizing a PowerShell script written by Chris Campbell (@obscuresec). However, this method requires dropping the script onto a compromised Domain machine prior to execution. The script can be found here:
Let's attempt to utilize this password to move laterally and authenticate to another Domain computer with these credentials. While there are many tools to assist in moving laterally (and these will be covered in detail in a future post), for this example we are going to use the Metasploit psexec module (exploit/windows/smb/psexec), which will allow us to pass the compromised credentials and authenticate to another Domain machine.
BOOM! We have successfully moved from our initial compromised machine to another Domain machine. This can be done over and over for any machines that utilize the affected Group Policy and that have Server Message Block (SMB) services open, allowing us to move freely around the network, dumping more credentials and uncovering juicy information.
Group Policy Preferences Vulnerability Remediation / Caveats
Microsoft finally got around to "patching" this vulnerability with MS14-025; however, merely applying the patch will not fix the issue. This is because so many organizations utilize the GPP method for managing Local Administrator passwords that Microsoft didn't want to negatively affect business operations for its customers. Instead, the patch takes the following approach: current policies are restricted to the "delete" operation only and the ability to deploy new policies has been removed. This does nothing for any policies that are currently in place and sitting out on SYSVOL, however. As a result, many organizations remain vulnerable.
Two PowerShell scripts are available from Microsoft to assist customers in moving away from GPP to set Local Administrator credentials. The first script, Get-SettingsWithCPassword.ps1, will clean up all instances of Groups.xml files that contain password information. The second script, Invoke-PasswordRoll.ps1, is Microsoft's new solution for Local Administrator account management. Local passwords are randomly set and then stored in a password-protected CSV file. The same script can be utilized to decrypt the password later.
While this new solution effectively breaks lateral movement with Local Administrator accounts (even if someone were to uncover the password for one machine's account, it could not be used to authenticate elsewhere); I can't help but feel that Domain Administrators hate this solution. The whole reason to use GPP to deploy a standardized password is to simplify administration of machines and many Domain Administrators may feel like their workload has increased with a very inelegant solution.
In my humble opinion, a better solution would have been to allow for the creation of a unique AND strong (not 32-bit please!) encryption key for each Domain. That being said, if a bunch of machines are set to the same Local Administrator password, all it would take is one compromised machine and subsequent credential dump to be right back in lateral movement heaven.
I'd love to hear your thoughts on the issue. Is there a better way that allows for the appropriate balance of functionality and security? Am I missing something?