Creating Applocker GPO's from Powershell

Applocker's basic setup was covered here, it was an out-of-the-box configuration for the sole purposes of trying to exploit Windows with an RCE and seeing how Applocker would fair. it didn't. Manually configuring Applocker is no fun compared to the alternative, Powershell. Auditing the system, creating custom settings and finally creating Domain Group Policies. I'll cover some of the arrgghhh, Why Microsoft just Why, considerations as well.

Applocker is available with Windows 7 Ultimate and all Windows Enterprise Editions from 7 upwards, Windows 10 Pro when managed by MDM eg InTune. Applocker is an application whitelisting service that is meant to keep the system safe from malware execution. It does this via GPO and Publisher, Hash and Path rules for the following file types:

Executables (.exe, .com)
Dll's (.ocx, . dll)
Scripts (.vbs, .js, .ps1, .cmd, .bat)
Windows Installers (.msi, .mst, .msp)
Packaged App (.appx)

There is an undocumented feature of blocking API's when DLL enforcement is enabled, requiring path rules. There are others that will be covered later on.

Before we start looking at Applocker there's a decision to make. Install RSAT for Windows 10 or not, no RSAT and it will be a 2-stage process of generating the rules on the Windows client and then coping the output to something with the AD\GPO Powershell modules installed for importing into Group Policy.

So the first hurdle, thanks Microsoft.... All my demos are created in an offline Hyper-V system with no Internet. With Windows 1803 and above, I'm using 1909, RSAT is no longer available as a separate download...why not. If you plan on installing RSAT run the following commands whilst online:

DISM.exe /Online /add-capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~
DISM.exe /Online /add-capability /CapabilityName:Rsat.GroupPolicy.Management.Tools~~~~


Create folder 'C:\logs\Applocker' as the working area for scripts and .xml files. 

Next complaint, why doesn't the Applocker Module for Powershell provide full support for path rules? The rule will only work for a folder based on the existing content. No .exe file is in the folder, and no rules are created. If anyone has a fix, please let me know, I'll update this page with you being credited. 

To work around the lack of path support, open gpedit.msc and manually create folder rules for any location where the user can Write and\or Execute. Repeat this process for each Applocker Rule type. So you don't have to, click on the image below to download the rules to 'C:\Logs\Applocker\', rename from .txt to .xml.

Include any network shares, I've H\: for Home Drives and G:\ for Groups and don't forget DVD's and USB mappings.

It's possible to create an Applocker Deny path rule for 'C:\' with exclusions for 'C:\Program Files\*' and 'C:\Windows\*' etc this then effectively whitelists those entire Directories, may as well deploy the default rules and go home. Instead deny rules will protect individual folders that are writeable.

To protect the root of C:\ from users being able to Write and Create folders, deploy run this command: 
icacls.exe c:\ /remove:g "Authenticated Users" 

Enabling enforcement of .dll's does cause performance issues when the policy is created with PowerShell, grouping is not particularly effective. The number of rules created and processed results in poor performance and with excessive rules approved programs are denied randomly. Hence why I tend to use path rules for .dll's constraining the calling from system defaults of Windows and Program Files. Alternatively, if it's a requirement for whitelisting, manually group .dll's and approve by Publisher, until no further 8003 errors are generated in the Applocker Eventlogs. 

Now for the fun bit, Powershell. 

The script and xml files can be downloaded from Github (here).

Note: The 'PacakgeRules.xml' is no longer required, the script will create a new package file on the fly.

Either run the script from Powershell or ISE and enter the name of the GPO when prompted.

The following output will be created.

The following 3 GPO's will be created.

'GPO_Applocker_2020_July' Audit of files

'GPO_Applocker_2020_July_PS' Audit of Powershell instances.

'GPO_Applocker_2020_July_Path' Manually created path rules.

Assign the 3 GPO's to an OU with a representative Windows 10 1909.

Create an additional GPO for setting the 'Application Identity' service to Automatic.

Logon to Windows 10 client as a user and run 'gpupdate /force', 

Open Eventvwr and browse to the Applocker logs, check for 8001 event, at this point Applocker is enforcing policy.

Open Office and other applications, reboot and re-logon to the client. Open Eventvwr and review the Applocker events for errors.

Despite the entire system being audited looks like some more file types aren't supported, but Applocker will block them. These need to be whitelisted by the path. These have been added to the 'pathRules.xml'

Execute 'psr.exe' to test enforcement, an 8004 event is raised.

The next test is to create a Powershell script with the following line 'gwmi Win32_bios | outfile c:\logs\wmi.txt', right click on the script and 'Run with Powershell'

Initially this worked as Powershell is approved. So much for protecting against un-approved Empire type scripts.

Applocker logs did not show any MSI and Script logs.

In fact the only evidence as that Powershell.exe was allowed to run, no mention of the script.

However attempting to run the script from Powershell failed. 

How to tackle the script issue. If you run Powershell logon scripts or App-V it may be challenging. There is also the issue that some Users or Admins may have a business requirement for Powershell. 

Let's say that Powershell must be blocked. Create an AD group named 'GP_Applocker_Block', that's easy.

Now... add every single user that does not require access to Powershell.....if you're in a large organisation that's a lot of users to add and manage going forward, any new user will have to be actively added to the group. This is my biggest gripe with Applocker.

Now update each rule, changing the 'Everyone' group to the 'GP_Applocker_Block' group. 

The script can be amended to add the 'GP_Applocker_Block' to Applocker rules automatically.

ForEach-Object {$ardnyPS} |

Get-AppLockerFileInformation -ErrorAction SilentlyContinue | 

New-AppLockerPolicy -RuleType Hash -Xml -user GP_Applocker_Block |

 Out-File $xmldnyPS

There is a fair amount of information regarding bypassing Applocker and 'Living off the Land' with the solutions normally involving deny lists. Deny lists based on hashes should be considered a moment-in-time snapshot. Patching, updating the files and the hashes change, at that point the deny list is no longer effective. It is advisable to run just the deny sections of the Powershell script monthly just after patch Tuesday creating new GPO's. 

I've not covered why all those path rules in any great detail, denying execution from those writable folders is a must, as an example, it prevents older and bug-prone and digitally signed files from being downloaded and run from the desktop. 

Any comments or observations please use the contact form and let me know. Thanks for your time.