In our first blog post on Windows Defender Application Control (WDAC), we created a code integrity policy that was built by scanning a gold imaged system (via the New-CIPolicy cmdlet) to generate the base rules for our code integrity policy. When we ran the sweep, we did so using the PCACertificate level to have a middle-ground approach between a locked down security policy and ease of management in relation to maintaining the code integrity policy.
But what happens if you were to install a program after having created the code integrity policy? If the policy were to be in enforcement mode, the application would be blocked by WDAC (unless signed by a trusted certificate). However, since the policy we’ve created is in audit mode, the application is logged in the Microsoft-Windows-CodeIntegrity/Operational event log and is allowed to execute.
For example, I installed Google Chrome, VSCode, and other applications on my system after creating the code integrity policy. After I run both, I can see the following sample set of logs in the CodeIntegrity event log:
Thankfully, the New-CIPolicy cmdlet has a built-in switch (-Audit) that will parse the Code Integrity event log to search for binaries that would otherwise be blocked if WDAC was configured to be in enforcement mode. To create rules based off what has been captured in the audit log, you can run the following command:
New-CIPolicy -Audit -Level PCACertificate -UserPEs -FilePath C:\Windows\System32\CodeIntegrity\AuditSweep.xml
Now that a new code integrity policy has been generated, the next step is to merge the new policy with our existing policy. In order to merge policies, we need to interact with the XML versions of the policies (not the .p7b format), via the Merge-CIPolicy cmdlet. You should use the -PolicyPaths parameter to provide the full paths to the individual policies that you want to merge, and the -OutputFilePath will be the location that the merged policy is saved to. Your command will look similar to the following:
Merge-CIPolicy -PolicyPaths C:\Windows\System32\CodeIntegrity\BaseScan.xml, C:\Windows\System32\CodeIntegrity\AuditSweep.xml -OutputFilePath C:\Windows\System32\CodeIntegrity\MergedRules.xml
You could take the MergedRules.xml file, convert it to a .p7b file via the ConvertFrom-CIPolicy and test the updated rules in audit mode. However, our overall approach does have a problem. By scanning everything currently on the gold imaged system, we will “pick up” and inherently trust binaries that might be better of as untrusted. For example, msbuild.exe would be trusted, and if we’re trusting Microsoft signed applications, other binaries such as csi.exe, or dnx.exe would allow you to execute arbitrary code (assuming you brought those files onto the system you are targeting if not already present). So, the logical question is, how can you start to limit the allowed applications based on the original code integrity policy?
Thankfully, Matt Graeber began curating a list of Device Guard bypasses, and has published a code integrity policy which explicitly blocks known dangerous binaries. Our next step will be merging our code integrity policy with the rules Matt published.
The first step is to download a copy of the code integrity policy containing the rules Device Guard bypass mitigation rules. Now, we’re actually going to use a combination of Get-CIPolicy and Merge-CIPolicy cmdlets.
The Get-CIPolicy cmdlet will parse the supplied code integrity file and capture the rules contained within it. In our case, we’re going to store those rules in a variable. The Merge-CIPolicy cmdlet can also take rule output from Get-CIPolicy as input, so we will combine the parsed rules along with the code integrity policy that we just created (the MergedRules.xml policy). This should look similar to the image below.
Finally, we can take the AuditandBlocked.xml code integrity file, convert it into its .p7b format, reboot, and test out merged rules.
Hopefully this post helps demonstrate how to easily create WDAC rules based on your event log entries, and how to easily merge newly created rules into an existing code integrity policy. Thank you also to Matt Graeber for documenting his approach to updating a code integrity policy, available here. If you have any questions, feel free to contact us at FortyNorth Security.