How to clear a local Applocker policy

There are 3 main actions in this menu when you edit the local Applocker policy. You can Import, Export and Clear a policy.

Let’s see how one can clear a local Applocker policy.

If you use Windows PowerShell, you can directly access the built-in Applocker module.
In this case, you can use the following shortcut:

$null | New-AppLockerPolicy -User EveryOne -EA 0 | 
Set-AppLockerPolicy -Verbose

NB: EA is the Alias of ErrorAction and 0 means SilentlyContinue.
It’s required to avoid displaying a message saying:

New-AppLockerPolicy : Cannot validate argument on parameter ‘FileInformation’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

.
Even if there’s an error thrown, a Microsoft.Security.ApplicationId.PolicyManagement.PolicyModel.AppLockerPolicy is created and sent to the output stream.

Unfortunately, the same shortcut cannot be used within PowerShell 7.0.1 (current latest version).
You need the following 2 steps:

# step 1: write an empty policy to a file
$null | New-AppLockerPolicy -User EveryOne -EA 0 -Xml | 
Out-File ~/Documents/empty.xml

# step 2: import that file
Set-AppLockerPolicy ~/Documents/empty.xml

NB: Notice the addition of the -XML switch in the first step.

Here’s another approach for Windows PowerShell that looks like the example provided by Microsoft, named delete-an-applocker-rule that tells you actually how to clear *all* the rules.

The following example doesn’t write a file to disk and directly clears the local Applocker Policy

NB: Notice the first call at line 11 to a built-in command from the Applocker module. It’s used to avoid this error message: Unable to find type [Microsoft.Security.ApplicationId.PolicyManagement.PolicyModel.AppLockerPolicy].
If that first call at line 11 is missing, when you do the following, you get:

Weird, isn’t? If you’ve an explanation, please add a comment 🙂

Check CVE-2020-1048 with AutoRuns

If you’ve seen what’s going on with CVE-2020-1048, it looks quite scary.

I’ve created an issue (#71) for this and added a detection in the Print Monitors category (see this commit)

I’ve published a digitally signed version of the AutoRuns module on the PowerShell Gallery as well.
(If you get started with AutoRuns, have a look at this README page.)

Now, if you do this,

Add-PrinterPort -Name "C:\windows\tracing\myport.txt"

You get it detected with the AutoRuns Module like this

Get-PSAutorun -PrintMonitorDLLs -VerifyDigitalSignature | 
Where { -not($_.Signed) }

Notice that there’s still an issue with the ImagePath property that needs to be fixed.
Anyway, it’s quick & dirty and detected 🙂
Happy hunting 😎

How to view an Applocker policy enforcement

When you edit an Applocker Group Policy either a local one or one stored in Active Directrory, you can view and configure what collections are active and what these should do.

Rule collections can be “not configured” or when they are “configured”, they can be set to “enforced” or “audit only”.

I’ve created a function to view the above settings.
Let’s see it in action first:

It can be used without parameters and will display the Effective policy

Get-AppLockerPolicyInfo | ft -AutoSize

You can also use the Local switch to view the local policy configuration:

Get-AppLockerPolicyInfo -Local | Format-Table -AutoSize

It accepts also a policy object sent into the pipeline.
In other words it can be bound with the built-in Applocker cmdlets:

Get-AppLockerPolicy -Local | 
Get-AppLockerPolicyInfo -Verbose | 
ft -AutoSize

It can be used to view the configuration in an Active Directory based Applocker policy.
In this case, I’ll use the cmdlets from the GroupPolicy module.

$gpo = Get-GPO -All | Out-GridView -OutputMode Single
Get-AppLockerPolicy -Ldap "LDAP://$(($gpo).path)" -Domain | 
Get-AppLockerPolicyInfo | ft -AutoSize

There’s another use for this function.
Using both the Effective and Local switches, it can help you diagnose how enforcement is configured if you’ve more than a local policy.
Here’s an example when there’s an overlap on Applocker policies:

In the above specific example, we can see the local policy is Enforced with a few rules (probably default rules) and is stricter than the AD policy that is set to Audit Only. If we want to keep to local policy to apply, an explicit deny can be set to so that the computer stops applying the Audit only GPO.

Here’s the code of this function:

Quick post about VMWare modules and ConstrainedLanguage mode

    • Context

There are new modules from Vmware available on the PowerShell Gallery:

Thanks to Applocker configured in whitelist mode, your favorite PowerShell console runs in ConstrainedLanguage mode even when you’re an admin and have it elevated.
You’ve Applocker rules that for example allow the Path where the VMware modules and files are located.

    • Issue

When you load the VMWare.PowerCli module:

Import-Module VMware.PowerCli -Verbose -Force

There’s a message saying:

Import-Module : Importing *.ps1 files as modules is not allowed in ConstrainedLanguage mode.
At line:1 char:1
+ Import-Module VMware.PowerCli -Verbose -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (:) [Import-Module], InvalidOperationException
+ FullyQualifiedErrorId : Modules_ImportPSFileNotAllowedInConstrainedLanguage,Microsoft.PowerShell.Commands.ImportModuleCommand

    • Solution

If you edit the VMware.PowerCLI.psd1 file and comment the following offending line:

Ok, this breaks the digital signature using the SignerCertificate Subject: CN=”VMware, Inc.”, O=”VMware, Inc.”, L=Palo Alto, S=California, C=US. That’s why we have an Applocker path rules and not a certificate based rule 🙄

It loads your VMware modules w/o the above error message 🙂

Nothing is missing except the welcome/help message in the VMware.PowerCLI.ps1 file 😎

Get statistics from Direct Access server(s)

    • Context

During this COVID period, your Direct Access servers is a good nice-to-have solution for remoting.
However, there’s a limit on the maximum number of connexions it can handle.
You should keep an eye on this limit and get an idea of the current workload.
You may as well report these figures to your boss.

    • Issue

The RemoteAccess module provides a cmdlet to get statistics 🙂

Get-RemoteAccessConnectionStatisticsSummary
Measure-Command {
Get-RemoteAccessConnectionStatisticsSummary
}


As you can see, it’s damn slow. It took about 31 seconds to get the result 😦

    • Solution

You can actually use the WMI repository directly to get a result more quickly

$HT = @{
 Namespace = 'root/Microsoft/Windows/RemoteAccess/Server'
 ClassName = 'PS_RemoteAccessAccountingStatisticsSummary'
 MethodName = 'GetByActiveStatistics'
 ErrorAction = 'Stop'
}
(Invoke-CimMethod @HT).cmdletoutput


As you can see it takes a few milliseconds and not seconds to get the result 😎

If you wonder how I found this, here are the steps I followed:

# Identify the module and what type of command
gcm  Get-RemoteAccessConnectionStatisticsSummary
# Check the content of the function
gc Function:\Get-RemoteAccessConnectionStatisticsSummary
# Once you have identified the relevant Namespace
# You can list classes and their methods
gwmi -ns root/Microsoft/Windows/RemoteAccess/Server -List | ogv

# Once you've the Class, you can query the methods:
Get-CimClass -Namespace `
root/Microsoft/Windows/RemoteAccess/Server `
-ClassName PS_RemoteAccessAccountingStatisticsSummary | 
Select -expand CimClassMethods

Get a DeepBlue analysis

At RSA Conference 2020, in this video The 5 Most Dangerous New Attack Techniques and How to Counter Them, Ed Skoudis presented a way to look for log anomalies – DeepBlueCLI by Eric Conrad, et al. as one of the C2 (Command&Control) defenses available.

I forked the original version from the commit made in Christmas 2019.

My intent is to make the DeepBlueCli:

    • available as a PowerShell module contained in a single .psm1 file
    • expose a single function with many parameters (instead of editing the original .ps1 file to change them)
    • more aligned with what PowerShell can do and other PowerShell coding style standards

Of course, you should first start reading what the original DeepBlueCLI can do in its README

I found the Deepblue.ps1 script great for various reasons:

    • First, it can analyze a live running Windows computer. It reads by default the Security event log.
      However, it’s not scalable because it loads regular expressions used for analyzing commands content from its side regexes.txt file.
    • Sencondly, it can analyze an exported .evtx file either from the ‘Application’, ‘System’, ‘Security’, ‘Applocker’, ‘Sysmon’ or ‘PowerShell’ event logs. That makes it cross-platform. You can use the script on Linux computer running PowerShell 7 🙂
    • Third, it’s a very fast way to find out indicators of compromise. It will tell you if a new account has been added, how many times an account was used to log on, if there are suspicious well known commands…
    • Last but not least, Eric Conrad stores many sample .evtx files in his GH repo.

Let’s see it in action!

I launched a Windows 10 Pro 1809 VM in Azure and ran the following:

# Install PowerShell 7 (msi x64), click, click...
iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"
# Open PS7
saps pwsh

In the new PowerShell 7 console, I ran:

# Download
iwr 'https://github.com/p0w3rsh3ll/DeepBlue/archive/master.zip' -OutFile ~/downloads/DeepBlue-master.zip -Verbose
# Unzip
Expand-Archive ~/downloads/DeepBlue-master.zip ~/downloads/DeepBlue-master
cd  ~/downloads/DeepBlue-master/DeepBlue-master
# Verify
$HT = @{
    CatalogFilePath = "./DeepBlue.cat"
    Path = "./"
    Detailed = $true
    FilesToSkip = 'README.md'
}
Test-FileCatalog @HT
Set-ExecutionPolicy RemoteSigned -Scope Process -Force -Verbose
# Import
Import-Module .\DeepBlue.psd1 -Force -Verbose
# Run the function
Get-DeepBlueAnalysis

I also downloaded that the original DeepBlueCLI script and repo from Eric Conrad and ran the same commands to see the difference between my forked version and his:


NB: Notice the tab completion for the Log parameter in my version 😉

# Capture results in a variable
$r = Get-DeepBlueAnalysis -File `
..\DeepBlueCLI-master\DeepBlueCLI-master\evtx\many-events-security.evtx

# Just to get an idea of what DeeBlueCli is able to report:
$r | group  Results -noEl| ft -Wrap -AutoSize

# Show other sample events:
$r[0]
$r | ? Results -match 'Meterpreter' | select -First 1

Nice, isn’t it?

What’s next? If I get Eric Conrad’s approval, I’ll digitally sign my forked version named DeepBlue and push it to the PowerShell Gallery so that you can do:

# Either Save...
Find-Module -Name DeepBlue -Repository PSGallery
Save-Module -Name DeepBlue -Repository PSGallery -Path ~/Downloads

#...or Install
Install-Module -Name DeepBlue -Verbose -Repository PSGallery

If you want to see what I did since the fork, all the changes are available on this page 😎

Get more info about Edge Chromium

    • Context

If you go on https://aka.ms/EdgeEnterprise, you can download and deploy the new Edge-Chromium

On this page, you’ve first to choose a channel/build from the first drop-down menu:

Then you’ve to choose for what platform, you need the binary:

And you can hit the download button and/or get the latest policies’ templates.

    • Problem

At work I’ve some requirements for maintaining browsers. I need to know when there’s an update available and what it fixes.
I’m already following what Google, Mozilla and Microsoft (for built-in Edge-Html and IE11) do but the new Edge-Chromium (aka ChrEdge) is another beast.

    • Solution

It appears that the source code of the page https://aka.ms/EdgeEnterprise contains some JSON data used to build the above drop-down menu and help select the channel, build, platform to be downloaded.
This JSON data much more data than what appears in the GUI.

I’ve built some helper functions to extract and expose all this data from the blob that is JSON formatted in HTML .
It requires PowerShell 6.x or greater because the code uses the -AsHashtable switch from the ConvertFrom-Json cmdlet.
After this core function named Get-MSEdgeEnterpiseData used to extract the JSON blob and convert it back to real JSON data, I could build the following functions:

  1. Get-MSEdgeEnterpiseBuild to mimic what the first drop-down menu does,
  2. Get-MSEdgeEnterpisePlatform to mimic what the 2nd drop-down menu does,
  3. Get-MSEdgeEnterpiseDownloadInfo to enhance and add metadata about the artifacts to be downloaded
  4. Get-MSEdgeEnterpisePolicy to retrieve the info about policies templates files
  5. Get-MSEdgeEnterpiseEdgeUpdateInfo to return info about the Edge Updates (only present in the JSON blob and not exposed in the GUI)

All these functions can be found in the following gist named MSEdgeChromium.ps1

Let’s see it in action!

# Show the version of PowerShell
$PSVersionTable

# Load the functions by dot-sourcing
. ~/Documents/MSEdgeChromium.ps1

# Show what the raw JSON looks like
 Get-MSEdgeEnterpiseData | fl *

# Show all the builds from the Dev and Stable channels
Get-MSEdgeEnterpiseBuild -Channel Stable,Dev

NB: Notice for example the ExpectedExpiryDate and PublishedTime properties that aren’t exposed in the HTML page.

# Show the first 2 builds from the Stable channel for the Windows x64 platform
Get-MSEdgeEnterpisePlatform -Channel Stable -Platform 'Windows x64'|
Select -Last 2

# Show only the latest version released
Get-MSEdgeEnterpisePlatform -Channel Stable -Platform 'Windows x64' -Latest

# Use the Get-MSEdgeEnterpiseDownloadInfo function to
# Add the metadata about the artifact to be downloaded
Get-MSEdgeEnterpisePlatform -Channel Stable -Latest |
Get-MSEdgeEnterpiseDownloadInfo

# Get the latest policies file published and
# Use the Get-MSEdgeEnterpiseDownloadInfo function to
# Add the metadata about the artifact to be downloaded
Get-MSEdgeEnterpisePolicy -Latest |
Get-MSEdgeEnterpiseDownloadInfo

# Get the latest Edge Update published and
# Use the Get-MSEdgeEnterpiseDownloadInfo function to
# Add the metadata about the artifact to be downloaded
Get-MSEdgeEnterpisePolicy -Latest |
Get-MSEdgeEnterpiseDownloadInfo

NB: This channel named ‘Edge Update’ is hidden and not presented in the web page at all for the moment…

Bonus: Last but not least, if you work behind a proxy, you may want to add more proxy related parameters to the Invoke-WebRequest cmdlet like the -Proxy parameter on line 32 of MSEdgeChromium.ps1