WDACTools PowerShell module comprises everything that should be needed to build, configure, deploy, and audit Windows Defender Application Control (WDAC) policies.
Despite the relative complexity of this repository, the goal is to minimize policy deployment, maintenance, and auditing overhead.
WDACTools requires Windows 10 1903+ Enterprise in order to build multiple policies. Once policies are built, Enterprise SKUs of Windows 10 1903+ are not required for deployment as long as the
Enabled:Inherit Default Policy policy rule option is specified.
The feature of WDAC that motivated me to develop this module was, beginning in Windows 10 1903, the ability to deploy multiple base and supplemental policies. In particular, this offers the following unique advantages:
- Mixed-mode policy enforcement: Upon properly tuning a policy, I can place one or more policies into enforcement mode. Then, as new tuning/maintenance requirements arise, I can have one or more policies in audit mode that will permit execution while tuning while keeping well-establised rules in enforcement mode. Additionally, there may be scenarios where it is unrealistic to block execution of certain binaries but you would like to have optics into when they're loaded with an audit mode policy side by side with enforcement policies.
- Maintaining multiple policies that are scoped to a specific set of software and/or signers is far easier to maintain than a single, massive, difficult to audit policy.
- When code integrity (CI) events are logged, the corresponding policy that generated the CI event is logged.
- The advantage that having many policies offers also creates its own maintenance headache where maintaining policy rule option consistency across many policies. I have been bitten by accidentally prematurely placing a policy intended for audit mode in enforcement mode, resulting in an unstable OS, a problem which is painful and challenging to debug.
- As rich as the logging is, it remains difficult to contextualize what all fields mean across many related events.
- The existing WDAC cmdlets available in the ConfigCI PowerShell module remain difficult to work with and do not output relevant objects that would enable tests to be written. Additionally, there is no cmdlet available to recover an XML policy from a binary .p7b/.cip policy.
This module aims to address all of the above problems. While the auditing functionality of this module facilitates building code integrity policies, this module does not aim to automate application control policy configuration methodology. Use of this module assumes you are already comfortable building WDAC code integrity policies.
Available Module Functions
Method 1: Import the module manifest directly
Import-Module WDACTools.psd1 # View available exported functions Get-Command -Module WDACTools
Method 2: Place the
WDACTools directory into a desired module path. Upon doing so, module autoloading will automatically load
WDACTools when one of its functions is executed. The following command will show the available module paths:
$Env:PSModulePath -split ';'
New-WDACPolicyConfiguration is used as a helper function to generate code integrity policy configuration options and to supply them to the
Invoke-WDACCodeIntegrityPolicyBuild builds and, optionally, deploys and refreshes code integrity policies locally.
Get-WDACCodeIntegrityEvent retrieves and parses
Microsoft-Windows-CodeIntegrity/Operational PE audit and enforcement events into a format that is more human-readable. This function is designed to facilitate regular code integrity policy baselining.
Get-WDACApplockerScriptMsiEvent retrieves and parses
Microsoft-Windows-AppLocker/MSI and Script audit and enforcement events into a format that is more human-readable. This function is designed to facilitate regular code integrity policy baselining. Non-PE code that is subject to code integrity enforcement is logged to the
Microsoft-Windows-AppLocker/MSI and Script log.
ConvertTo-WDACCodeIntegrityPolicy converts a binary file that contains a Code Integrity policy into XML format. This function is used to audit deployed Code Integrity policies for which the original XML is not present. It can also be used to compare deployed rules against a reference XML file. This function is
ConvertFrom-CIPolicy in reverse.
Get-WDACCodeIntegrityBinaryPolicyCertificate obtains signer information from a signed, binary code integrity policy. This function was developed as the result of Get-AuthenticodeSignature not supporting signed, binary code integrity policies. Signed policies are represented as PKCS#7 ASN.1 SignedData (szOID_RSA_signedData - 1.2.840.113518.104.22.168).
Expected CI Policy Locations
Invoke-WDACCodeIntegrityPolicyBuild expects your policies to reside in specific directories included in this repository.
These are base policies that should rarely change with the exception of relevant policy rule modification (e.g. switching from audit to enforcement mode) and the occasional updating of deny rules in MicrosoftRecommendedBlockRules.xml. Intuitively, deny rules would live as supplemental rules but deny rules are not honored in supplemental rules.
This is where optional supplemental policies reside. These policies are intended to be updated more frequently whereas the base policies should rarely change.
This is where all optional application/vendor-specific policies should reside. For example, if your goal is to allow Google products to execute, a dedicated Google policy should reside here. Having software/vendor-specific policies in here will drastically alleviate the maintenance burden across a complex software landscape. A question that would be expected to arise is, "why can't I just have a ton of app-specific policies as independent supplemental policies?" That's because Microsoft only supports 32 active CI policies.
The policies in this directory will be merged together to form
MergedPolicy.xml in the
Recommended CI Policy Format
WDACTools module was designed to facilitate consistency across all of your policies, it is recommended that your policies have the following characteristics:
- Each policy have an empty policy rule option element. This would take on the following form:
WDACTools is designed to permit supplying policy rule options via code so that consistency is ensured and so that generated policies can be easily tested against expected policy rule options.
- Policy settings Name and ID fields should be named
REPLACEME. Doing so, allows you to specify policy names via code.
Invoke-WDACCodeIntegrityPolicyBuildpopulates each policy ID with the build date (format:
MM_DD_YYYY) as a way to simplify auditing.
<Settings> <Setting Provider="PolicyInfo" Key="Information" ValueName="Name"> <Value> <String>REPLACEME</String> </Value> </Setting> <Setting Provider="PolicyInfo" Key="Information" ValueName="Id"> <Value> <String>REPLACEME</String> </Value> </Setting> </Settings>
Generated Build Artifacts
When policies are built with
Invoke-WDACCodeIntegrityPolicyBuild, all generated XML and binary policies are saved to the
Invoke-WDACCodeIntegrityPolicyBuild supports an optional
-ArtifactPath parameter though that allows you to specify an alternate build artifact path.