This is the third in a series of blog topics by penetration testers, for penetration testers, highlighting some of the advanced pentesting techniques they'll be teaching in our new Network Assault and Application Assault certifications, opening for registration this week. For more information, check out the training page at www.rapid7.com/services/training-certification/penetration-testing-training.jsp
Group Policy Preferences (GPP) are a powerful tool that once allowed administrators to create domain policies with embedded credentials. These policies allowed administrators to set local accounts, embed credentials for the purposes of mapping drives, or perform other tasks that may otherwise require an embedded password in a script.
While a useful tool, the storage mechanism for the credentials was flawed and allowed attackers to trivially decrypt the plaintext credentials. While addressed in MS14-025, this patch only prevents new policies from being created, and any legacy GPPs containing credentials must be found and removed. Learning how to find and exploit these GPPs that contain credentials is an important tool to have in the pentester's arsenal because the policies may contain highly privileged accounts.
Embedding credentials in group policy preferences solved a lot of problems for administrators. A GPP could be used to easily apply a common local administrator password to all workstations, apply an entirely new administrator account (as shown below), schedule tasks as other users, map drives, apply printers, or several other uses. Often, these kinds of policies can involve service accounts that frequently have elevated privileges. In the example below, a GPP is set to add the account ‘new_local_admin' to all domain systems. We'll use this account as a demonstration later on.
On pentests I've performed, I've encountered GPPs being used to set local administrator accounts, schedule tasks or even applying a service account to a system which often has elevated privileges. Regardless of why they originally were created, their mere existence is a great resource for a pentester.
Can you keep a secret?
Given the wide variety of uses for GPPs that contain credentials, it is fairly common to find them on penetration tests, and often with credentials ranging from local admin to domain admin. While the functionality of GPPs is very powerful, the mechanism of storing those credentials was compromised in a way that made them trivial to decrypt. Even Microsoft no longer advocates storing credentials in GPPs, and addressed the issue in MS14-025 (https://support.microsoft.com/en-us/kb/2962486)).
Put in basic terms, applying any account, administrative or not, via GPP stores the account's password in an insecure manner. Specifically, the password that is stored in the policy is encrypted with a known key, helpfully documented by Microsoft here: https://msdn.microsoft.com/en-us/library/cc422924.aspx, meaning anyone who can access the GPP can decrypt the store and obtain the plain text password, no matter the complexity. Since GPPs are stored on the domain controller in the SYSVOL share, this means that at a minimum all domain users can access the encrypted credentials.
To put it another way:
While MS14-025 does address the issue to some degree, it only does so by blocking or warning against the creation of new policies that can apply account credentials (https://blogs.technet.microsoft.com/srd/2014/05/13/ms14-025-an-update-for-group- policy-preferences/)), which is perfectly reasonable as clearly no one wants a patch that deletes existing credentials.
However, this means that if any current GPPs are already applying credentials they must be found and manually removed, along with considerations for any functionality such as mapping of drives or printers that may break as a result. As these policies rarely get attention from IT other than during the initial creation, and are more ‘set and forget,' many times a penetration tester will find an account that was provisioned years before and simply forgotten about.
Obtaining credentials is a primary goal during a pentest, and group policy preferences is a go-to attack for many testers as it is stealthy and high reward. Since group policies are stored in SYSVOL on the domain controller, any domain user can read the policy and therefore decrypt the stored passwords. Below is an example of how the password for ‘new_local_admin' is stored in a groups.xml file.
This also means any phishing attack or other foothold on any domain system will result in a leak of all credentials stored in group policy preferences. Demonstrating this is very easy so try this yourself with the Metasploit smb_enum_gpp module. If you run smb_enum_gpp against a domain controller and get credentials in your result, then you'll know you have this vulnerability. Below is the password for ‘new_local_admin' we set in the GPP.
Even without Metasploit, one can extract the cpassword value from the files on SYSVOL and pass them to the gpp-decrypt tool in Kali Linux which will decrypt it:
While GPPs are mainly useful for privilege escalation, persistence, or lateral movement, which are all essentially post-exploitation activities, I've run into some even weirder scenarios during penetration tests. In the worst example, anyone on a local network was able read the SYSVOL share and extract credentials via anonymous access to a domain controller. This sort of misconfiguration can make a bad situation a worst case scenario as it allowed an unauthenticated attacker who had only network access to gain credentials easily. After dumping the active directory group memberships, also via anonymous access, wouldn't you know that this account (that was effectively world readable) was a domain admin! That's about the nastiest of worst-case scenarios.
After finding and exploiting this issue numerous times, I've found some common themes:
- Many organizations simply aren't aware that GPP behaves in this manner.
- They may think that the MS14-025 patch completely remediated the issue.
- Organizations don't even know they have GPPs with credentials.
Number three is by far the most common. Often, the age of the accounts indicates they were set years ago and have been functioning as intended. Usually these are service accounts, commonly with no password expiration. IT administrator turnover or bad documentation simply results in these policies being overlooked.
The first step is to perform an accounting of group policies that apply credentials. Speaking as a pentester, I feel the easiest way is to use attack methods and tools to find the usage of GPPs that contain credentials. As mentioned before, the Metasploit smb_enum_gpp module (https://www.rapid7.com/db/modules/auxiliary/scanner/smb/smb_enum_gpp) can be used to enumerate GPPs that contain credentials, but realistically a search of the SYSVOL share for the files that contain the credentials can also be performed with a script. Microsoft even supplies such a script in kb article 2962486 (https://support.microsoft.com/en-us/kb/2962486).
If GPPs are used to apply local administrator accounts, Microsoft also has the Local Administrator Password Solution (LAPS) tool (https://www.microsoft.com/en-us/download/details.aspx?id=46899)) to help provision these accounts without group policy preferences.
So to recap, legacy GPPs that contain credentials are a great way for penetration testers to gain credentials easily from an insecure credential store on domain controllers. They are easy to find, are often privileged accounts, and accessing them doesn't usually ring alarm bells.
Interested in learning how to use GPP and similar techniques on your penetration test? Register for our next Network Assault class, and keep an eye out for the other blog posts in this series, which we'll be releasing throughout the week.