As I think about Group Policy as a target for attackers, there are many obvious avenues to take advantage of a poorly protected GP infrastructure. I’ve written about many of these here:
However, I was recently thinking about less obvious ways to mess with GP and one interesting path came to mind–namely, compromising ADMX files. For those of you who need a refresher on the role of ADMX in Group Policy, have a look at this article I wrote a few years ago. In a nutshell, ADMX (and their associated, language-specific ADML files) are XML files that allow Group Policy to render UI within the Group Policy Editor, in the Administrative Templates namespace, to support the definition of many 1000s of registry-based configuration items. Think of the ADMX file as translating registry keys and values, in readable language that an administrator can understand, as shown here:
You enable a policy for “Do not process the run once list”, and inside the GPO’s registry.pol file, an entry is stored for the registry key and value that corresponds to that “English-language” policy. The ADMX file controls that mapping between policy name and registry entry.
All the setting options you see in GP Editor under “Administrative Templates” are there by virtue of the fact that ADMX files are located either on your local Windows Machine (under c:\windows\policydefinitions) or in something called the ADMX Central Store. The Central Store is just a folder within SYSVOL (i.e. replicated to all DCs under \\domain\sysvol\domain\policies\Policydefinitions) and is used in many enterprises today. An enterprise will typically copy the current version of ADMX files and their corresponding ADML files, into the Central Store, and all administrators of GP will use the same set of ADMX/L within any GP-related tool that they run in the domain (the local copies on a given Windows machine are simply ignored). This ensures that, regardless of whether an administrator is editing or reporting against a GPO, a single set of ADMX files from the Central Store are the ones that are used by everyone to build the UI in GP Editor, and to generate settings reports in GPMC.
The Central Store is both a blessing, and a curse. As I mentioned above, the ADMX files control what registry keys and values are manipulated when a particular Administrative Template policy is enabled (or disabled). So, if you control the Central Store, you control what actually ends up in the registry on a given system that processes that policy. And here is where the issue lies. If an attacker or otherwise ill-mannered administrator, has write access to the Central Store’s ADMX files, they can edit those files to have a seemingly innocuous policy, set a registry value that is not so innocuous. Here’s an example. The following is a snippet from the Logon.ADMX, that controls what you see under Computer (or User) Configuration\Policies\Administrative Templates\System\Logon. In particular, this snippet controls the “Always wait for the network at computer startup and logon“:
<policy name="SyncForegroundPolicy" class="Machine" displayName="$(string.SyncForegroundPolicy)" explainText="$(string.SyncForegroundPolicy_Help)" key="Software\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon" valueName="SyncForegroundPolicy"> <parentCategory ref="Logon" /> <supportedOn ref="windows:SUPPORTED_WindowsXP" /> <enabledValue> <decimal value="1" /> </enabledValue> <disabledValue> <decimal value="0" /> </disabledValue> </policy>
I chose this particular setting, because this is a popular setting, that many administrators will enable in Windows environments. It essentially enables synchronous GP processing and can solve certain classes of problems around GP processing on client machines. But let’s say I decide to edit this file and this snippet as follows:
<policy name="SyncForegroundPolicy" class="Machine" displayName="$(string.SyncForegroundPolicy)" explainText="$(string.SyncForegroundPolicy_Help)" key="Software\Microsoft\Windows\CurrentVersion\Policies\System" valueName="EnableLUA"> <parentCategory ref="Logon" /> <supportedOn ref="windows:SUPPORTED_WindowsXP" /> <enabledValue> <decimal value="0" /> </enabledValue> <disabledValue> <decimal value="1" /> </disabledValue> </policy>
So what did I do here? I changed the registry key and value that this policy would set, from HKLM\Software\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon\Syncforegroundpolicy to Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA. I also swapped the enabled and disabled values to be 0 if the policy is enabled and 1 if the policy is disabled. This new key/value pair happens to control User Account Control (UAC). When it’s set to (Enabled) 0, that registry value turns off UAC. However, there’s no visual notification of it for the administrator who’s in GP Editor, as you can see:
It’s important to understand, however, that this is not an instantaneous change. What has essentially happened here, is that I’ve planted a landmine. I’ve mucked with an existing Administrative Template policy definition, but the administrator of the domain still has to step on the mine by enabling that policy in a GPO, after I’ve made my change. This is why I picked a relatively “popular” setting to futz with–I increase my chances of my changed definition getting picked up and deployed. One can, of course, mess with many settings, across many ADMX files, to increase the chances of someone inadvertently enabling the policy. But the point is, this tinkering I’ve done is not magically disabling UAC across all machines in the environment. You still need the administrator’s help to deploy the setting into a GPO, which requires patience. And of course, one can pick any registry value to substitute into any ADMX file. I suspect, though I haven’t tested it, that you may even be able to mess with the local SAM and Security hives with a carefully crafted ADMX. Since per-computer GP processing occurs within the localSystem context, you could theoretically grant privileges on the local system to user accounts using this approach. But even just being able to manipulate “regular” registry keys is malicious enough, as there are plenty of security hardening settings that are simple to enable/disable in the registry.
It’s pretty obvious how this approach could cause security problems for an organization, but there are some mitigating factors here that make this less painful in practice. As I mentioned, once an attackers modifies ADMX files, it’s up to the administrator to implement one of the modified settings in a deployed GPO–otherwise that setting will never see the light of day on endpoints.
However, if the attacker is patient, this attack is worth worrying about, and the most obvious control you can put in place to protect against this, is to ensure that users who have write-able permissions on the Central Store are Tier 0 administrators (i.e. Domain Controller Admins) only. They should be the only ones who can write to files here. In addition, if you have domain controller auditing in place, audit the file folder of the Central Store for file system changes to ensure that unexpected writes to ADMX files don’t happen without your knowing it.