Windows Defender Application Control (WDAC) Implementation - Part 2: The Baseline Policy

Part 2 in a guide to setting up Windows Defender Application Control (WDAC)

Windows Defender Application Control (WDAC) Implementation - Part 2: The Baseline Policy
Photo by Shahadat Rahman / Unsplash

The baseline policy is made from two policies:

  • the base policy - this policy whitelists all Microsoft signed apps that are a part of the operating system
  • the supplemental base policy - this policy whitelists anything in common program locations

For my base policy, I use the DefaultMicrosoftEnforced template located in C:\Windows\schemas\CodeIntegrity\ExamplePolicies\DefaultWindows_Enforced.xml.

The Base Policy

Build the base policy by:

<Rules>
  <Rule>
    <Option>Enabled:Unsigned System Integrity Policy</Option>
  </Rule>
  <Rule>
    <Option>Enabled:UMCI</Option>
  </Rule>
  <Rule>
    <Option>Enabled:Update Policy No Reboot</Option>
  </Rule>
  <Rule>
    <Option>Enabled:Allow Supplemental Policies</Option>
  </Rule>
  <Rule>
    <Option>Disabled:Script Enforcement</Option>
  </Rule>
  <Rule>
    <Option>Enabled:Managed Installer</Option>
  </Rule>
  <Rule>
    <Option>Enabled:Invalidate EAs on Reboot</Option>
  </Rule>
  <Rule>
    <Option>Enabled:Dynamic Code Security</Option>
  </Rule>
</Rules>

Now that the policy is complete; convert the policy to a binary .p7b file with the command:

ConvertFrom-CIPolicy -XmlFilePath DefaultWindows_Enforced.xml -BinaryFilePath DefaultWindows_Enforced.p7b

The Supplemental Base Policy

I then create a supplemental policy that whitelists the directories %WINDIR%, %OSDRIVE%\Program Files\*, and %OSDRIVE%\Program Files (x86)\*. This file is named BaseSupplemental.xml

This policy looks like this:

<?xml version="1.0" encoding="utf-8"?>
<SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy" PolicyType="Supplemental Policy">
  <VersionEx>10.0.0.0</VersionEx>
  <PlatformID>{2E07F7E4-194C-4D20-B7C9-6F44A6C5A234}</PlatformID>
  <Rules>
    <Rule>
      <Option>Enabled:Unsigned System Integrity Policy</Option>
    </Rule>
    <Rule>
      <Option>Enabled:Audit Mode</Option>
    </Rule>
    <Rule>
      <Option>Enabled:Advanced Boot Options Menu</Option>
    </Rule>
    <Rule>
      <Option>Required:Enforce Store Applications</Option>
    </Rule>
    <Rule>
      <Option>Enabled:UMCI</Option>
    </Rule>
    <Rule>
      <Option>Disabled:Script Enforcement</Option>
    </Rule>
  </Rules>
  <!--EKUS-->
  <EKUs />
  <!--File Rules-->
  <FileRules>
    <Allow ID="ID_ALLOW_A_1" FriendlyName="%WINDIR%\* FileRule" MinimumFileVersion="0.0.0.0" FilePath="%WINDIR%\*" />
    <Allow ID="ID_ALLOW_A_3" FriendlyName="%OSDRIVE%\Program Files\* FileRule" MinimumFileVersion="0.0.0.0" FilePath="%OSDRIVE%\Program Files\*" />
    <Allow ID="ID_ALLOW_A_4" FriendlyName="%OSDRIVE%\Program Files (x86)\* FileRule" MinimumFileVersion="0.0.0.0" FilePath="%OSDRIVE%\Program Files (x86)\*" />
  </FileRules>
  <!--Signers-->
  <Signers />
  <!--Driver Signing Scenarios-->
  <SigningScenarios>
    <SigningScenario Value="131" ID="ID_SIGNINGSCENARIO_DRIVERS_1" FriendlyName="Auto generated policy on 01-03-2023">
      <ProductSigners />
    </SigningScenario>
    <SigningScenario Value="12" ID="ID_SIGNINGSCENARIO_WINDOWS" FriendlyName="Auto generated policy on 01-03-2023">
      <ProductSigners>
        <FileRulesRef>
          <FileRuleRef RuleID="ID_ALLOW_A_1" />
          <FileRuleRef RuleID="ID_ALLOW_A_3" />
          <FileRuleRef RuleID="ID_ALLOW_A_4" />
        </FileRulesRef>
      </ProductSigners>
    </SigningScenario>
  </SigningScenarios>
  <UpdatePolicySigners />
  <CiSigners />
  <HvciOptions>0</HvciOptions>
  <Settings>
    <Setting Provider="PolicyInfo" Key="Information" ValueName="Name">
      <Value>
        <String>1st Supplemental Policy</String>
      </Value>
    </Setting>
  </Settings>
  <BasePolicyID>{959A0F15-8985-4551-A208-5FFE9EDB3A70}</BasePolicyID>
  <PolicyID>{7457CF3F-8649-42D9-AEAB-723118FECBEB}</PolicyID>
</SiPolicy>

Ensure that the BasePolicyID element uses the GUID from your base policy that you collected earlier, and that the PolicyID element is a unique GUID (tip: use https://guidgenerator.com/ to generate suitable GUID's). The GUID needs to be entered with the curly braces around the GUID.

Again, convert the policy to a binary .p7b file with the command:

ConvertFrom-CIPolicy -XmlFilePath BaseSupplemental.xml -BinaryFilePath BaseSupplemental.p7b

These two policies form our baseline WDAC policy.