Skip to Main Content
January 24, 2019

Local Admin Access and Group Policy Don’t Mix

Written by Oddvar Moe
Password Audits Penetration Testing Policy Development Security Program Management

Having spent a career working with Group Policies, I thought now might be a good time to give an overview of it and I felt like doing a little writeup about Group Policies. I especially want to highlight why having admin access to clients can be really bad. It is important that everyone understands the weaknesses with Group Policies and admin access, though I know many IT organizations fully trust Group Policies. The mentality is often that the settings are set with a Group Policy, so there is a consistent rollout to the entire environment (set and forget). This, however, might not be the case, especially if you allow the use of local admins on your clients/servers.

Busting a Myth: All Group Policy Settings Are Re-Applied After a Reboot or After 90 Minutes

Group Policies are not automatically re-applied, though a common misconception that some have is that the machine runs "gpupdate /Force" after every Group Policy refresh or reboot. That is not how Group Policies work by default. The machine checks the Group Policies every 90 minutes with a randomized offset of up to 30 minutes. During that check, it verifies if the applied Group Policies have changed since the last time it was applied. If there have not been any changes in the central Group Policy, it will not do anything, and it will assume that the applied Group Policy is compliant. There is an exception to this and that is the Security Client Side Extensions, those settings are reprocessed every 16 hours even if there has been no changes. Let’s dive into how this works in a little more detail.

First, we've created a new Group Policy called "Some Important settings" and linked it to the OU that contains my computer account:

If we mark it, the right part of the Group Policy manager will show more information. If you click on the Details tab, you can see the Group Policy’s Unique ID:


Whenever a Group Policy is created, a folder under \\domain.name\sysvol\domain.name\Policies is also created. That folder is named with the Unique ID:

Within that folder there are two sub-folders, machine and user. There is also a file called GPT.ini.
Whenever you add a setting to either the machine part or user part of the Group Policy, the settings are added under the correct folder. This can be a policy, security information (Secedit), or a preference. If we open up the GPT.ini file, we can see that it is pretty empty:

Whenever a change is done to the Group Policy, this file is updated and a new version number is added. If we for instance just set a machine policy setting and revisit the GPT.INI it will look like this:

As you can see the version number was increased with one.
If we now go to a client and either wait until the next Group Policy refresh, do a boot or run "gpupdate", it will apply this Policy and create a local copy of the Group Policy located here:
C:\Windows\System32\GroupPolicy\DataStore\0\sysvol\oddvar.moe\Policies\{51799E88-A6DC-471A-9F0A-D213E5C3FCC3}

This is an exact copy of the central Group Policy we just created. If we now change the central Group Policy, the Version will be increased by one. Meaning that we now have a Group Policy that is version two centrally and version one on the client. Within the next Group Policy refresh or boot, the Group Policy Client (the component on a Windows client that is responsible for applying Group Policy settings) will see that the version number centrally has changed meaning, that it must now apply the new policy and overwrite the existing one. And this is the how Group Policies are applied.

When you run "gpupdate" with the /Force , you are telling the Group Policy Client to ignore the version numbers and get a fresh copy of all Group Policies and apply them.

If you, however, combine user and computer settings in a Group Policy, the version number becomes significantly increased, and there is a reason for that. For instance, here we have just added a random user setting, triggering a version one of the user settings. Take a look at the number:

In the Group Policy management the numbers are correct, but in the GPT.ini file we can see that it has increased to 65538. The top 16 bits are for the user version and the lower 16 bits are the computer version. To make it a bit easier to understand, we can convert it.

First, we convert the decimal value to HEX. This can be done with the Calculator in Windows like this:

As you can see this value is 0x10002 in HEX. The Windows Calculator will remove the leading zeros, so the correct value is 0x00010002. Four HEX characters equal 16 bits. Now that we have our number, we can split it into two 16 bit values.

00010002

The red number is the version of the User settings and the green number is the version number of the Computer settings. These are low numbers, so it is pretty obvious that it is one and two. If it were a higher HEX number, you could take each part, enter the HEX value in the calculator, and view the value in decimal to get the version number.

Why am I telling you all this? It is important to get an understanding of how this works under the hood, since it has weaknesses.

Most Group Policy settings end up in the registry under the following registry keys:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Policies
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
  • HKEY_CURRENT_USER\Software\Policies
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies

The problem here is that if you change the settings that are applied in the registry manually, it will not change back to the value that is set in the central Group Policy, unless you change the Group Policy centrally and increase the version number, or if you run a "gpupdate /Force" on the client.  

Let's go through an example of changing something to highlight the weakness a little better.

Let’s say that you as an IT admin define a Group Policy that enables the setting "Include command line in process creation events". This setting makes the logs more informative, so that you can see the process command line options (everyone should have this turned on by the way). The Group Policy Client sets this with a DWORD called "ProcessCreationIncludeCmdLine_Enabled" in the registry on the client under the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit

Value of 1 = Enabled, Value of 0 = Disabled

Let’s assume that an attacker compromises a box as an admin (we are going to change things in HKLM and that requires local admin access) and wants to remove this setting so that the logs are less informative. The attacker can either just delete that key or set it to the value of zero. After the attacker has done that, the client will no longer show the Process Command line in the event log.

A typical assumption now would be to run "gpupdate", wait for the next Group Policy refresh cycle, or boot the machine to get the setting back. That will not work, as explained earlier in this post.

This is one of the weaknesses with Group Policies, however, this behavior can and should be changed as one example of the security baselines you will find. The setting that changes this behavior is named "Process even if the Group Policy objects have not changed" and can be adjusted for all the different parts of a Group Policy (Scripts, Security, Registry, Wireless, Preferences, and more). When this is enabled, the Group Policy Client will not look at the version numbers anymore and will always apply the settings. In our example here, we want to enable this for registry policy processing.

After setting this setting in a Group Policy and you try to change the registry key to the value of zero and do a "gpupdate" or boot the computer it will change back to one. Great, it works as intended!

This is an excellent setting to set in an environment, so that all the settings are always applied. However, this can also be bypassed if an attacker gets a foothold as an admin. The setting itself is stored in the registry, meaning that we as an admin can manipulate it to change the behavior back.

The setting is named "NoGPOListChanges" and it is stored as a DWORD in the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}

If you change the value from zero to one, you will change the behavior back and you need to either change the Group Policy centrally to increase the version number or do a "gpupdate /force" to get it back again.

Conclusion

Here we saw one of the many problems with administrative access and Group Policy, and as you probably already know, administrative access should be minimized as much as possible inside an organization. Basically, if you have admins that log onto your computers/servers, you cannot be sure that the settings are compliant with what you set in your Group Policies. If this is a big concern, you should consider other products that check compliance according to desired settings. Since I have mostly worked with Microsoft technology, I know that System Center Configuration Manager offers this (Compliance settings). If you must use Group Policy, a recommendation is to log Group Policy so that you can make sure it's healthy and operating as desired. The event id list for the Group Policy can be found here: https://blogs.technet.microsoft.com/grouppolicy/2009/03/04/group-policy-troubleshooting-helpful-event-log-categories/

The future of Windows management is modern management . It is likely that you will use Open Mobile Alliance Uniform Resource Identifier (OWA-URI), which many mobile device manufacturers use to control features on devices, apply settings, and measure compliance. The security and potential for flaws… well, we can address that in another post in the future.