Skip to content

Commit

Permalink
WDACConfig module update v0.2.1
Browse files Browse the repository at this point in the history
1. Added -AllowFileNameFallbacks parameter by default when creating policies. It's a great parameter that helps include files that do not have an OriginalFileName.

2. Fixed the Microsoft recommended Block lists URLs in the code because they were changed and had to be updated. #83

3. Improved code quality (Security, readability, typos in the comments etc.)
  • Loading branch information
HotCakeX committed Aug 13, 2023
1 parent d05b88f commit a0b7d91
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 155 deletions.
22 changes: 11 additions & 11 deletions WDACConfig/ArgumentCompleters.ps1
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# argument tab auto-completion for SignToolPath param to show only .exe files in the current directory
$ArgumentCompleterSignToolPath = {
[scriptblock]$ArgumentCompleterSignToolPath = {
Get-ChildItem | Where-Object { $_.extension -like '*.exe' } | ForEach-Object { return "`"$_`"" }
}

# argument tab auto-completion for CertPath param to show only .cer files in current directory and 2 sub-directories recursively
$ArgumentCompleterCertPath = {
[scriptblock]$ArgumentCompleterCertPath = {
# Note the use of -Depth 1
# Enclosing the $results = ... assignment in (...) also passes the value through.
($results = Get-ChildItem -Depth 2 -Filter *.cer | ForEach-Object { "`"$_`"" })
Expand All @@ -16,7 +16,7 @@ $ArgumentCompleterCertPath = {

# argument tab auto-completion for Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
# https://stackoverflow.com/questions/76141864/how-to-make-a-powershell-argument-completer-that-only-suggests-files-not-already/76142865
$ArgumentCompleterPolicyPaths = {
[scriptblock]$ArgumentCompleterPolicyPaths = {
# Get the current command and the already bound parameters
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

Expand All @@ -39,15 +39,15 @@ $ArgumentCompleterPolicyPaths = {
}

# argument tab auto-completion for Certificate common name
$ArgumentCompleterCertificateCN = {
[scriptblock]$ArgumentCompleterCertificateCN = {
$certs = foreach ($cert in (Get-ChildItem 'Cert:\CurrentUser\my')) {
(($cert.Subject -split ',' | Select-Object -First 1) -replace 'CN=', '').Trim()
}
$certs | ForEach-Object { return "`"$_`"" }
}

# Argument tab auto-completion for installed Appx package names
$ArgumentCompleterAppxPackageNames = {
[scriptblock]$ArgumentCompleterAppxPackageNames = {
# Get the current command and the already bound parameters
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
# Get the app package names that match the word to complete
Expand All @@ -57,7 +57,7 @@ $ArgumentCompleterAppxPackageNames = {
}

# argument tab auto-completion for Base Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
$ArgumentCompleterPolicyPathsBasePoliciesOnly = {
[scriptblock]$ArgumentCompleterPolicyPathsBasePoliciesOnly = {
# Get the current command and the already bound parameters
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

Expand Down Expand Up @@ -87,7 +87,7 @@ $ArgumentCompleterPolicyPathsBasePoliciesOnly = {
}

# argument tab auto-completion for Supplemental Policy Paths to show only .xml files and only suggest files that haven't been already selected by user
$ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
[scriptblock]$ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
# Get the current command and the already bound parameters
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

Expand Down Expand Up @@ -117,7 +117,7 @@ $ArgumentCompleterPolicyPathsSupplementalPoliciesOnly = {
}

# Opens Folder picker GUI so that user can select folders to be processed
$ArgumentCompleterFolderPathsPicker = {
[scriptblock]$ArgumentCompleterFolderPathsPicker = {
# Load the System.Windows.Forms assembly
Add-Type -AssemblyName System.Windows.Forms
# non-top-most, works better with window focus
Expand All @@ -128,7 +128,7 @@ $ArgumentCompleterFolderPathsPicker = {
}

# Opens File picker GUI so that user can select an .exe file - for SignTool.exe
$ArgumentCompleterExeFilePathsPicker = {
[scriptblock]$ArgumentCompleterExeFilePathsPicker = {
# Load the System.Windows.Forms assembly
Add-Type -AssemblyName System.Windows.Forms
# Create a new OpenFileDialog object
Expand All @@ -144,7 +144,7 @@ $ArgumentCompleterExeFilePathsPicker = {
}

# Opens File picker GUI so that user can select a .cer file
$ArgumentCompleterCerFilePathsPicker = {
[scriptblock]$ArgumentCompleterCerFilePathsPicker = {
# Load the System.Windows.Forms assembly
Add-Type -AssemblyName System.Windows.Forms
# Create a new OpenFileDialog object
Expand All @@ -160,7 +160,7 @@ $ArgumentCompleterCerFilePathsPicker = {
}

# Opens File picker GUI so that user can select a .xml file
$ArgumentCompleterXmlFilePathsPicker = {
[scriptblock]$ArgumentCompleterXmlFilePathsPicker = {
# Load the System.Windows.Forms assembly
Add-Type -AssemblyName System.Windows.Forms
# Create a new OpenFileDialog object
Expand Down
10 changes: 5 additions & 5 deletions WDACConfig/Confirm-WDACConfig.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ function Confirm-WDACConfig {
if (-NOT $SkipVersionCheck) { . Update-self }

# Script block to show only non-system Base policies
$OnlyBasePoliciesBLOCK = {
[scriptblock]$OnlyBasePoliciesBLOCK = {
$BasePolicies = (CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.PolicyID -eq $_.BasePolicyID }
&$WriteLavender "`nThere are currently $(($BasePolicies.count)) Non-system Base policies deployed"
$BasePolicies
}
# Script block to show only non-system Supplemental policies
$OnlySupplementalPoliciesBLOCK = {
[scriptblock]$OnlySupplementalPoliciesBLOCK = {
$SupplementalPolicies = (CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.PolicyID -ne $_.BasePolicyID }
&$WriteLavender "`nThere are currently $(($SupplementalPolicies.count)) Non-system Supplemental policies deployed`n"
$SupplementalPolicies
Expand All @@ -52,13 +52,13 @@ function Confirm-WDACConfig {
if ($CheckSmartAppControlStatus) {
Get-MpComputerStatus | Select-Object -Property SmartAppControlExpiration, SmartAppControlState
if ((Get-MpComputerStatus).SmartAppControlState -eq 'Eval') {
&$WritePink "Smart App Control is in Evaluation mode.`n"
&$WritePink "`nSmart App Control is in Evaluation mode."
}
elseif ((Get-MpComputerStatus).SmartAppControlState -eq 'On') {
&$WritePink "Smart App Control is turned on.`n"
&$WritePink "`nSmart App Control is turned on."
}
elseif ((Get-MpComputerStatus).SmartAppControlState -eq 'Off') {
&$WritePink "Smart App Control is turned off.`n"
&$WritePink "`nSmart App Control is turned off."
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions WDACConfig/Deploy-SignedWDACConfig.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ function Deploy-SignedWDACConfig {
ConfirmImpact = 'High'
)]
Param(
[ValidatePattern('\.cer$')]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
[parameter(Mandatory = $false)][System.String]$CertPath,

[ValidatePattern('\.xml$')]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
[parameter(Mandatory = $true)][System.String[]]$PolicyPaths,

[ValidatePattern('\.cer$')]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' }, ErrorMessage = 'The path you selected is not a file path.')]
[parameter(Mandatory = $false)][System.String]$CertPath,

[ValidateScript({
$certs = foreach ($cert in (Get-ChildItem 'Cert:\CurrentUser\my')) {
Expand Down Expand Up @@ -104,9 +104,9 @@ function Deploy-SignedWDACConfig {
foreach ($PolicyPath in $PolicyPaths) {

$xml = [xml](Get-Content $PolicyPath)
$PolicyType = $xml.SiPolicy.PolicyType
$PolicyID = $xml.SiPolicy.PolicyID
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
[System.String]$PolicyType = $xml.SiPolicy.PolicyType
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
Remove-Item -Path ".\$PolicyID.cip" -ErrorAction SilentlyContinue
if ($PolicyType -eq 'Supplemental Policy') {
Add-SignerRule -FilePath $PolicyPath -CertificatePath $CertPath -Update -User -Kernel
Expand All @@ -133,7 +133,7 @@ function Deploy-SignedWDACConfig {
Remove-Item ".\$PolicyID.cip" -Force
Rename-Item "$PolicyID.cip.p7" -NewName "$PolicyID.cip" -Force
CiTool --update-policy ".\$PolicyID.cip" -json | Out-Null
Write-Host "`n`npolicy with the following details has been Signed and Deployed in Enforced Mode:" -ForegroundColor Green
Write-Host "`npolicy with the following details has been Signed and Deployed in Enforced Mode:" -ForegroundColor Green
Write-Output "PolicyName = $PolicyName"
Write-Output "PolicyGUID = $PolicyID`n"
Remove-Item -Path ".\$PolicyID.cip" -Force
Expand Down
40 changes: 22 additions & 18 deletions WDACConfig/Edit-SignedWDACConfig.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,9 @@ function Edit-SignedWDACConfig {
Remove-Item -Path ".\SupplementalPolicy$SuppPolicyName.xml" -Force -ErrorAction SilentlyContinue
# Get the current date so that instead of the entire event viewer logs, only audit logs created after running this module will be captured
# The notice about variable being assigned and never used should be ignored - it's being dot-sourced from Resources file
$Date = Get-Date
[datetime]$Date = Get-Date
# An empty array that holds the Policy XML files - This array will eventually be used to create the final Supplemental policy
$PolicyXMLFilesArray = @()
[System.Array]$PolicyXMLFilesArray = @()

################################### Initiate Live Audit Mode ###################################

Expand All @@ -269,8 +269,8 @@ function Edit-SignedWDACConfig {

# Defining Base policy
$xml = [xml](Get-Content $PolicyPath)
$PolicyID = $xml.SiPolicy.PolicyID
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string

# Remove any cip file if there is any
Remove-Item -Path '.\*.cip' -Force -ErrorAction SilentlyContinue
Expand Down Expand Up @@ -335,7 +335,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Pause

# Store the program paths that user browses for in an array
$ProgramsPaths = @()
[System.Array]$ProgramsPaths = @()
Write-Host "`nSelect program directories to scan" -ForegroundColor Cyan
# Showing folder picker GUI to the user for folder path selection
do {
Expand Down Expand Up @@ -469,7 +469,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
# Any other attempts such as "Get-FileHash" or "Get-AuthenticodeSignature" fail and ConfigCI Module cmdlets totally ignore these files and do not create allow rules for them

# Finding the file(s) first and storing them in an array
$ExesWithNoHash = @()
[System.Array]$ExesWithNoHash = @()
# looping through each user-selected path(s)
foreach ($ProgramsPath in $ProgramsPaths) {
# Making sure the currently processing path has any .exe in it
Expand All @@ -496,7 +496,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Write-Debug -Message "The following Kernel protected files detected, creating allow rules for them:`n"
if ($Debug) { $ExesWithNoHash | ForEach-Object { Write-Debug -Message "$_" } }

$KernelProtectedHashesBlock = {
[scriptblock]$KernelProtectedHashesBlock = {
foreach ($event in Get-WinEvent -FilterHashtable @{LogName = 'Microsoft-Windows-CodeIntegrity/Operational'; ID = 3076 } -ErrorAction SilentlyContinue | Where-Object { $_.TimeCreated -ge $Date } ) {
$xml = [xml]$event.toxml()
$xml.event.eventdata.data |
Expand Down Expand Up @@ -621,7 +621,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Remove-Item -Path '.\ProgramDir_ScanResults*.xml' -Force -ErrorAction SilentlyContinue
Remove-Item -Path ".\SupplementalPolicy$SuppPolicyName.xml" -Force -ErrorAction SilentlyContinue
# An empty array that holds the Policy XML files - This array will eventually be used to create the final Supplemental policy
$PolicyXMLFilesArray = @()
[System.Array]$PolicyXMLFilesArray = @()

#Initiate Live Audit Mode

Expand All @@ -634,8 +634,8 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item

# Defining Base policy
$xml = [xml](Get-Content $PolicyPath)
$PolicyID = $xml.SiPolicy.PolicyID
$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string
[System.String]$PolicyID = $xml.SiPolicy.PolicyID
[System.String]$PolicyName = ($xml.SiPolicy.Settings.Setting | Where-Object { $_.provider -eq 'PolicyInfo' -and $_.valuename -eq 'Name' -and $_.key -eq 'Information' }).value.string

# Remove any cip file if there is any
Remove-Item -Path '.\*.cip' -Force -ErrorAction SilentlyContinue
Expand Down Expand Up @@ -700,7 +700,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Pause

# Store the program paths that user browses for in an array
$ProgramsPaths = @()
[System.Array]$ProgramsPaths = @()
Write-Host "`nSelect program directories to scan`n" -ForegroundColor Cyan
# Showing folder picker GUI to the user for folder path selection
do {
Expand Down Expand Up @@ -906,17 +906,19 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Copy-Item -Path 'C:\Windows\schemas\CodeIntegrity\ExamplePolicies\DefaultWindows_Enforced.xml' -Destination '.\DefaultWindows_Enforced.xml'

# Allowing SignTool to be able to run after Default Windows base policy is deployed
&$WriteViolet "`nCreating allow rules for SignTool.exe in the DefaultWindows base policy so you can continue using it after deploying the DefaultWindows base policy."
&$WriteTeaGreen "`nCreating allow rules for SignTool.exe in the DefaultWindows base policy so you can continue using it after deploying the DefaultWindows base policy."
New-Item -Path "$env:TEMP\TemporarySignToolFile" -ItemType Directory -Force | Out-Null
Copy-Item -Path $SignToolPathFinal -Destination "$env:TEMP\TemporarySignToolFile" -Force
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -FilePath .\SignTool.xml
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\SignTool.xml
# Due to a bug Have to repeat this process twice: https://github.com/MicrosoftDocs/WDAC-Toolkit/issues/278
New-CIPolicy -ScanPath "$env:TEMP\TemporarySignToolFile" -Level FilePublisher -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\SignTool.xml
# Delete the Temporary folder in the TEMP folder
Remove-Item -Recurse -Path "$env:TEMP\TemporarySignToolFile" -Force
if (!$Debug) { Remove-Item -Recurse -Path "$env:TEMP\TemporarySignToolFile" -Force }

# Scan PowerShell core directory and add them to the Default Windows base policy so that the module can be used after it's been deployed
if (Test-Path 'C:\Program Files\PowerShell') {
&$WriteViolet "`nCreating allow rules for PowerShell in the DefaultWindows base policy so you can continue using this module after deploying it."
New-CIPolicy -ScanPath 'C:\Program Files\PowerShell' -Level FilePublisher -NoScript -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -FilePath .\AllowPowerShell.xml
New-CIPolicy -ScanPath 'C:\Program Files\PowerShell' -Level FilePublisher -NoScript -Fallback Hash -UserPEs -UserWriteablePaths -MultiplePolicyFormat -AllowFileNameFallbacks -FilePath .\AllowPowerShell.xml
Merge-CIPolicy -PolicyPaths .\DefaultWindows_Enforced.xml, .\AllowPowerShell.xml, .\SignTool.xml, '.\Microsoft recommended block rules.xml' -OutputFilePath .\BasePolicy.xml | Out-Null
}
else {
Expand All @@ -931,8 +933,10 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
if ($UpdateBasePolicy -and $RequireEVSigners) { Set-RuleOption -FilePath .\BasePolicy.xml -Option 8 }

# Remove the extra files create during module operation that are no longer necessary
Remove-Item '.\AllowPowerShell.xml', '.\SignTool.xml', '.\AllowMicrosoft.xml', '.\DefaultWindows_Enforced.xml' -Force -ErrorAction SilentlyContinue
Remove-Item '.\Microsoft recommended block rules.xml' -Force
if (!$Debug) {
Remove-Item '.\AllowPowerShell.xml', '.\SignTool.xml', '.\AllowMicrosoft.xml', '.\DefaultWindows_Enforced.xml' -Force -ErrorAction SilentlyContinue
Remove-Item '.\Microsoft recommended block rules.xml' -Force
}

# Get the policy ID of the currently deployed base policy based on the policy name that user selected
$CurrentID = ((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsSystemPolicy -ne 'True' } | Where-Object { $_.Friendlyname -eq $CurrentBasePolicyName }).BasePolicyID
Expand Down Expand Up @@ -976,7 +980,7 @@ CiTool --update-policy "$((Get-Location).Path)\$PolicyID.cip" -json; Remove-Item
Remove-Item ".\$CurrentID.cip" -Force
Remove-Item $PolicyFiles[$NewBasePolicyType] -Force -ErrorAction SilentlyContinue
Rename-Item -Path '.\BasePolicy.xml' -NewName $PolicyFiles[$NewBasePolicyType]
&$WriteSubtleRainbow "Base Policy has been successfully updated to $NewBasePolicyType"
&$WritePink "Base Policy has been successfully updated to $NewBasePolicyType"
&$WriteLavender 'Keep in mind that your previous policy path saved in User Configurations is no longer valid as you just changed your Base policy.'
}
}
Expand Down
Loading

0 comments on commit a0b7d91

Please sign in to comment.