Skip to Main Content
May 12, 2020

Breaking Typical Windows Hardening Implementations

Written by Oddvar Moe

In this post, I will go over some hardening configurations that are typically set in Group Policy settings and ways to bypass them. It is important to remember that hardening configurations can be a whole series of different settings. For this post, I am showing only a few specific settings, meaning that if these were in a real hardened environment, some of the examples would not work. However, the overall methodology still applies.

General methods for breaking Group Policy hardening

Scenario 1 – Local admin on a machine with some hardening in place:

In the post 'Local Admin Access and Group Policy Don't Mix,' take a look at BUSTING A MYTH: ALL GROUP POLICY SETTINGS ARE RE-APPLIED AFTER A REBOOT OR AFTER 90 MINUTES. This explains how you, as an admin, can change Group Policy settings and get away with it. It is easy to break hardening if you have local admin access on a machine. The above blog post can work as a general method when you have local admin access.

Scenario 2 – Normal user on a machine with some hardening in place:

Let’s say you have access to a machine and realize that the users have some hardening in place. The question is, how can you bypass or stop the hardening? Thanks to David Wells over at Tenable, we can use this as a general technique:

TL;DR: Get a copy of the ntuser.dat under the C:\Users\%username% folder (or create a new one on another computer and adjust), edit it (remove settings, set permissions), and copy it back as under the C:\users\%username% folder. Logon and profit.

Bypasses for specific Group Policy settings/hardening:

Prevent access to the command prompt and registry editing tools

Truthfully, these settings can be annoying. They can be found under ‘User Configuration > Policies > Administrative Templates > System’ and are called ‘Prevent access to the command prompt’ and ‘Prevent access to registry editing tools’.

These settings are not just enabled—they have sub-settings as well. On the command prompt setting, we have the ability to choose if we want to disable command prompt script processing also. The default option is No.

For registry editing tools, you have the option to disable regedit running silently or not. The default option is Yes.

When these settings are in place, you will get an error if you attempt to run cmd.exe or regedit.exe. Note that it also blocks reg.exe, regini.exe, conhost.exe, and more.

The bypasses you need are different depending on the settings. Let’s go over how to bypass the command prompt restrictions first.

Scenario – Command prompt disabled and script processing enabled:

In this scenario, you can do a lot of fun stuff. Every command you want to run can be prefixed with ‘cmd /c or cmd /k’. For instance, if you want to do a directory listing, you can do ‘cmd /k dir c:\’. Or if you want to output the results to file instead, you can do ‘cmd /c dir c:\ > c:\temp\dir_c.txt’.

You don’t get an interactive prompt, but you are still able to get those precious commands executed.

I have also seen in many cases that people forget to think about Powershell.exe, meaning that you still can start up Powershell.exe and use that as an interactive shell.

Another option is to use a LOLBin that can execute what you want, e.g., forfiles.exe.

Scenario – Command prompt disabled and script processing disabled:

This setup makes it more difficult to run commands since we can no longer use /c or /k to execute with cmd.exe. The first step I would try would be to fire up PowerShell as an alternative. If that does not work, another approach is to use a LOLBin that can execute code and does not rely on cmd.exe. For instance, forfiles.exe will be blocked by this setting when script processing is disabled.

Another cool bypass I have used in the past is to use Didier Stevens cmd.exe or cmd.dll. This is a recompiled ReactOS version of the file. It can be found here:

After you download it, you should be able to run the cmd.exe (unless application whitelisting or some other hardening is getting in your way).

In the above screenshot, you can see that the normal cmd.exe on the left is blocked and the downloaded version works just fine.

Scenario – Registry editing tools disabled and allowed to run silently:

You might have guessed that this is easy to bypass since we can execute it silently. Let me go over some examples of how to read and change the registry when this setting is in place.

Reading the registry can be done in many ways. One way is to use regedit with the /s switch. This indicates silent operation. If you want to read Hkey_Current_User\Environment, you could use this command to dump it to a registry file:

Regedit /s hkey_current_user\environment

Afterward, you can open that registry file in Notepad or use type in a command prompt to see the registry values, as seen in the screenshot below.

If you want to write to the registry, you can do an import using regedit. That means you have to prepare a .reg key with the desired settings and then you can run:

Regedit /s registryfile.reg

Another useful option is a visual basic script (vbscript). In many cases, you can save the file as .vbs and execute it directly.

These three (3) lines are all that is needed to read out the path variable from registry:

Set objWshShell = WScript.CreateObject("WScript.Shell")
strKeyToRead = objWshShell.RegRead("HKCU\Environment\path")
wscript.echo strKeyToRead

These three (3) lines can be used to write to the registry using a vbscript:

Set objWshShell = WScript.CreateObject("WScript.Shell")
myKey = "HKCU\Environment\mysetting"
objWshShell.RegWrite myKey,1,"REG_DWORD"

Scenario – Registry editing tools disabled and allowed to run silently disabled:

In this scenario, we can no longer use regedit /s. If you attempt to execute regedit /s, you will get the same error when executing regedit normally. The vbscript approach will still work since this setting will, in most cases, block native Windows registry editing binaries.

In addition to vbscript, you can also attempt PowerShell. If you want to look inside a registry hive, you can do a CD and ls into it, as shown in the screenshot.

You can also browse the different keys by using CD, as shown in the next screenshot.

If you want to look inside HKLM instead, you can use HKLM:. In order to write a value using PowerShell, you can do the following command:

Set-ItemProperty HKCU:\Environment\test\ -Name ha -Value works

If neither vbscript nor PowerShell can help, I would attempt to download Didier Stevens recompiled ReactOS version of regedit. It can be found on Dideier Stevens' blog.

When it is downloaded, you can simply run:

rundll32 <path_to_dll>,DllMain

That should then open a Registry Editor, as shown in the screenshot below:

Scenario – Prevented access to C

In Group Policy, a setting prevents the user from opening the C drive in the file explorer:

After this setting is applied and the user tries to access the C drive, it will display this error message:

This protection is trivial to bypass. Typical things you can do include:

  • Type the full path in the explorer address field:
  • Browse the disk using \\\c$:
  • Use CMD or PowerShell to browse the disk:
  • Do the subst command to fake a new drive letter:
  • View folder structure in Search index:
  • Use the FTP command:

There are many other ways to view the filesystem when this setting is enabled. A cool approach would be to program your own file browser.

Bypass for Group Policy Preferences

There is a difference between what we call Group Policy Preferences and Group Policy settings. A Group Policy Preference is just what it sounds like—it is a preferred setting that the user can change. In many environments, Group Policy Preferences are used to harden the environment since the settings have so much flexibility and are easy to use. However, when you operate in the registry outside the defined Group Policy settings paths, the Access Control Lists are not protecting the settings. That being said, the design around Preferences is that the user should be able to change the settings after they have been set. Let me walk you through a typical example were the administrators want HTA files to open in Notepad instead of executing the code with mshta.exe. A typical way of doing this is through Group Policy Preferences. All the preference settings can be found under the Preferences folder in the Group Policy editor, as shown in the screenshot.

The OpenWith setting can be found under Control Panel Settings > Folder Options.

When the ‘Open With’ option is chosen, you can specify what sort of extension you want to manipulate and the application you want to assign. In the screenshot below, I have specified notepad to open HTA files.

An important thing to notice about Preferences is the Common tab. Here you can specify if the execution should be done as the user or system. When the 'Run in logged-on user’s security context' is checkmarked, then the preference is executed as that user, meaning it is running in the context of the user. If this is unchecked, it is executed as system. In this example, we are going with the default and let it run as the logged-on user.

When this preference is updated on the client, every time the user double clicks on an HTA file, it will open in Notepad instead. This hardening prevents the user from open links that poins to HTA files or HTA files being sent directly to the user's inbox. Let's say we, as a user, want to no longer open HTA files in Notepad, how can we change it and make it be persistent so that the preference settings do not get reapplied on the next Group Policy refresh? The answer is registry editing. When this setting is applied, this is written to the registry under the user’s hive. The full path can be seen in the screenshot below.

Let us try to change this to open with mshta.exe instead and see what happens when we attempt to open an HTA file.

As you can see, it opened correctly in mshta.exe. So, what happens after the next Group Policy refresh? The setting in registry is set back to Notepad and the HTA files are once again opening in Notepad. How do we prevent the system from changing that setting? Easy, we deny it. In Windows Registry, the current user can change the permissions on most of the stuff inside the Hkey_Current_User registry hive (There are some exceptions). Let us right-click on the command folder and see the current permissions.

We can now see the individual permissions assigned to this folder. When we specified the setting, we chose to run as the logged in user, which actually means we have to block our own account from changing this registry key after we set it to what we want.

After this is done, the setting will not reset itself back to notepad.exe when Group Policy refresh is executed. This example goes for many other scenarios were Group Policy Preferences is used.


In this post, I showed some ways to break typical hardenings/settings. Of course there are many ways to achieve the same thing, but hopefully these examples will inspire both defenders and attackers. If you have input or suggestions regarding this post, feel free to reach out.