├── .gitignore ├── AppSpecificPolicies └── AppSpecificPolicyTemplate.xml ├── BasePolicies └── .empty ├── BuildAndDeployPolicies.psm1 ├── BuildArtifacts └── .empty ├── CIPolicyParser.psm1 ├── Examples └── ExamplePolicyBuilder.ps1 ├── LICENSE ├── Readme.md ├── SupplementalPolicies └── .empty ├── WDACAuditing.psm1 └── WDACTools.psd1 /.gitignore: -------------------------------------------------------------------------------- 1 | *.cip 2 | *.p7b 3 | *.xml 4 | !AppSpecificPolicyTemplate.xml -------------------------------------------------------------------------------- /AppSpecificPolicies/AppSpecificPolicyTemplate.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 1.0.0.0 4 | {FEEDACDC-BEEF-CACE-F00D-FEEDACDCF00D} 5 | {817C8595-ADB5-481B-88E9-ADE1D2A4896D} 6 | {2E07F7E4-194C-4D20-B7C9-6F44A6C5A234} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | REPLACEME 25 | 26 | 27 | 28 | 29 | REPLACEME 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /BasePolicies/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattifestation/WDACTools/07be9ddfed49b56dd1952f7eb0361f6d540c4bf5/BasePolicies/.empty -------------------------------------------------------------------------------- /BuildAndDeployPolicies.psm1: -------------------------------------------------------------------------------- 1 | function ConvertTo-WDACPolicyRuleValue { 2 | <# 3 | .SYNOPSIS 4 | 5 | A helper function to convert Windows Defender Application Control (WDAC) policy rule options to numeric values which are required for the Set-RuleOption cmdlet. 6 | 7 | .DESCRIPTION 8 | 9 | ConvertTo-WDACPolicyRuleValue converts human-readable WDAC policy rule options to numeric values for use by the Set-RuleOption cmdlet. Due to the poor design of Set-RuleOption, you cannot supply these string values and must supply integeter values which is not intuitive or user-friendly. This function makes calling Set-RuleOption more intuitive. 10 | 11 | This function is not designed to be exposed to users. Functions with parameters that support policy rules options should support tab-completion for the human-readble values. 12 | 13 | Author: Matthew Graeber 14 | 15 | .PARAMETER PolicyOptionStrings 16 | 17 | Specifies an array of human-readble policy rule options that want to be set. 18 | 19 | .EXAMPLE 20 | 21 | ConvertTo-WDACPolicyRuleValue -PolicyOptionStrings 'Enabled:UMCI', 'Enabled:Boot Menu Protection', 'Enabled:Audit Mode' 22 | 23 | Returns an array of integer values representing the requested policy rule options. These values can then be more easily supplied to a subsequent call to Set-RuleOption. 24 | #> 25 | 26 | [OutputType([Int[]])] 27 | [CmdletBinding()] 28 | param ( 29 | [Parameter(Mandatory, Position = 0)] 30 | [ValidateSet('Enabled:UMCI', 31 | 'Enabled:Boot Menu Protection', 32 | 'Required:WHQL', 33 | 'Enabled:Audit Mode', 34 | 'Disabled:Flight Signing', 35 | 'Enabled:Inherit Default Policy', 36 | 'Enabled:Unsigned System Integrity Policy', 37 | 'Allowed:Debug Policy Augmented', 38 | 'Required:EV Signers', 39 | 'Enabled:Advanced Boot Options Menu', 40 | 'Enabled:Boot Audit On Failure', 41 | 'Disabled:Script Enforcement', 42 | 'Required:Enforce Store Applications', 43 | 'Enabled:Managed Installer', 44 | 'Enabled:Intelligent Security Graph Authorization', 45 | 'Enabled:Invalidate EAs on Reboot', 46 | 'Enabled:Update Policy No Reboot', 47 | 'Enabled:Allow Supplemental Policies', 48 | 'Disabled:Runtime FilePath Rule Protection', 49 | 'Enabled:Dynamic Code Security', 50 | 'Enabled:Revoked Expired As Unsigned')] 51 | [String[]] $PolicyOptionStrings 52 | ) 53 | 54 | $RuleOptionMapping = @{ 55 | 'Enabled:UMCI' = 0 56 | 'Enabled:Boot Menu Protection' = 1 57 | 'Required:WHQL' = 2 58 | 'Enabled:Audit Mode' = 3 59 | 'Disabled:Flight Signing' = 4 60 | 'Enabled:Inherit Default Policy' = 5 61 | 'Enabled:Unsigned System Integrity Policy' = 6 62 | 'Allowed:Debug Policy Augmented' = 7 63 | 'Required:EV Signers' = 8 64 | 'Enabled:Advanced Boot Options Menu' = 9 65 | 'Enabled:Boot Audit On Failure' = 10 66 | 'Disabled:Script Enforcement' = 11 67 | 'Required:Enforce Store Applications' = 12 68 | 'Enabled:Managed Installer' = 13 69 | 'Enabled:Intelligent Security Graph Authorization' = 14 70 | 'Enabled:Invalidate EAs on Reboot' = 15 71 | 'Enabled:Update Policy No Reboot' = 16 72 | 'Enabled:Allow Supplemental Policies' = 17 73 | 'Disabled:Runtime FilePath Rule Protection' = 18 74 | 'Enabled:Dynamic Code Security' = 19 75 | 'Enabled:Revoked Expired As Unsigned' = 20 76 | } 77 | 78 | foreach ($PolicyOptionString in $PolicyOptionStrings) { 79 | $RuleOptionMapping[$PolicyOptionString] 80 | } 81 | } 82 | 83 | function New-WDACPolicyConfiguration { 84 | <# 85 | .SYNOPSIS 86 | 87 | A helper function used to specify a code integrity policy configuration. 88 | 89 | .DESCRIPTION 90 | 91 | New-WDACPolicyConfiguration is used as a helper function to generate code integrity policy configuration options and to supply them to the Invoke-WDACCodeIntegrityPolicyBuild function. 92 | 93 | The objects output by New-WDACPolicyConfiguration are intended to be supplied as arguments to the following parameters in Invoke-WDACCodeIntegrityPolicyBuild: -BasePolicyConfiguration, -SupplementalPolicyConfiguration, -MergedPolicyConfiguration 94 | 95 | Author: Matthew Graeber 96 | 97 | .PARAMETER BasePolicy 98 | 99 | Specifies that a base policy is to be configured and built. Base policies must reside in the "BasePolicies" directory. 100 | 101 | When this switch is specified, the object output is supplied to the -BasePolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 102 | 103 | .PARAMETER SupplementalPolicy 104 | 105 | Specifies that a supplemental policy is to be configured and built. Supplemental policies must reside in the "SupplementalPolicies" directory. 106 | 107 | When this switch is specified, the object output is supplied to the -SupplementalPolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 108 | 109 | .PARAMETER MergedPolicy 110 | 111 | Specifies that a supplemental policy is to be configured and built by merging multiple policies together. Supplemental policies designed for merging must reside in the "AppSpecificPolicies" directory. 112 | 113 | When this switch is specified, the object output is supplied to the -MergedPolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 114 | 115 | .PARAMETER FileName 116 | 117 | Specifies the filename of the XML policy file. This parameter only applies when the -BasePolicy or -SupplementalPolicy switches are supplied. 118 | 119 | .PARAMETER PolicyName 120 | 121 | Specifies the name of the policy. Upon deployment of your policy, this policy name will be surfaced in the event log. 122 | 123 | .PARAMETER PolicyRuleOptions 124 | 125 | Specifies the policy rule options that you want to supply to the specified policy. This parameter supports tab-completion. 126 | 127 | .PARAMETER BasePolicyToSupplement 128 | 129 | Specifies the base policy that the merged, application-specific policy is a supplement to. This parameter is mandatory when -MergedPolicy is specified. 130 | 131 | .EXAMPLE 132 | 133 | $BaseDriverPolicy = New-WDACPolicyConfiguration -BasePolicy -FileName 'BaseDriverPolicy.xml' -PolicyName 'BaseDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode' 134 | 135 | Specifies configuration options for a base policy. The object output would then be supplied to the -BasePolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 136 | 137 | .EXAMPLE 138 | 139 | $SupplementalSurfacePolicy = New-WDACPolicyConfiguration -SupplementalPolicy -FileName 'MicrosoftSurfaceDriverPolicy.xml' -PolicyName '3rdPartyDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode' 140 | 141 | Specifies configuration options for a supplemental policy. The object output would then be supplied to the -SupplementalPolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 142 | 143 | .EXAMPLE 144 | 145 | $MergedPolicyConfiguration = New-WDACPolicyConfiguration -MergedPolicy -PolicyName 'Merged3rdPartySoftwareRuleset' -BasePolicyToSupplement 'BaseUserModeRuleset' -PolicyRuleOptions 'Enabled:Audit Mode' 146 | 147 | Specifies configuration options for a merged supplemental policy (i.e. the policies that reside in the "AppSpecificPolicies" directory). The object output would then be supplied to the -MergedPolicyConfiguration parameter in Invoke-WDACCodeIntegrityPolicyBuild. 148 | #> 149 | 150 | [CmdletBinding(DefaultParameterSetName = 'Base')] 151 | param ( 152 | [Parameter(Mandatory, ParameterSetName = 'Base')] 153 | [Switch] 154 | $BasePolicy, 155 | 156 | [Parameter(Mandatory, ParameterSetName = 'Supplemental')] 157 | [Switch] 158 | $SupplementalPolicy, 159 | 160 | [Parameter(Mandatory, ParameterSetName = 'Merged')] 161 | [Switch] 162 | $MergedPolicy, 163 | 164 | [Parameter(Mandatory, ParameterSetName = 'Merged')] 165 | [String] 166 | [ValidateNotNullOrEmpty()] 167 | $BasePolicyToSupplement, 168 | 169 | [Parameter(Mandatory, ParameterSetName = 'Base')] 170 | [Parameter(Mandatory, ParameterSetName = 'Supplemental')] 171 | [String] 172 | $FileName, 173 | 174 | [Parameter(Mandatory)] 175 | [String] 176 | $PolicyName, 177 | 178 | [String[]] 179 | [ValidateSet('Enabled:UMCI', 180 | 'Enabled:Boot Menu Protection', 181 | 'Required:WHQL', 182 | 'Enabled:Audit Mode', 183 | 'Disabled:Flight Signing', 184 | 'Enabled:Inherit Default Policy', 185 | 'Enabled:Unsigned System Integrity Policy', 186 | 'Allowed:Debug Policy Augmented', 187 | 'Required:EV Signers', 188 | 'Enabled:Advanced Boot Options Menu', 189 | 'Enabled:Boot Audit On Failure', 190 | 'Disabled:Script Enforcement', 191 | 'Required:Enforce Store Applications', 192 | 'Enabled:Managed Installer', 193 | 'Enabled:Intelligent Security Graph Authorization', 194 | 'Enabled:Invalidate EAs on Reboot', 195 | 'Enabled:Update Policy No Reboot', 196 | 'Enabled:Allow Supplemental Policies', 197 | 'Disabled:Runtime FilePath Rule Protection', 198 | 'Enabled:Dynamic Code Security', 199 | 'Enabled:Revoked Expired As Unsigned')] 200 | $PolicyRuleOptions 201 | ) 202 | 203 | if ($BasePolicy) { 204 | $ConfigurationProperties = [Ordered] @{ 205 | PSTypeName = 'WDACBasePolicyConfiguration' 206 | FileName = $FileName 207 | PolicyName = $PolicyName 208 | PolicyRuleOptions = $PolicyRuleOptions 209 | } 210 | } 211 | 212 | if ($SupplementalPolicy) { 213 | $ConfigurationProperties = [Ordered] @{ 214 | PSTypeName = 'WDACSupplementalPolicyConfiguration' 215 | FileName = $FileName 216 | PolicyName = $PolicyName 217 | PolicyRuleOptions = $PolicyRuleOptions 218 | } 219 | } 220 | 221 | if ($MergedPolicy) { 222 | $ConfigurationProperties = [Ordered] @{ 223 | PSTypeName = 'WDACMergedPolicyConfiguration' 224 | PolicyName = $PolicyName 225 | PolicyRuleOptions = $PolicyRuleOptions 226 | BasePolicyToSupplement = $BasePolicyToSupplement 227 | } 228 | } 229 | 230 | New-Object -TypeName PSObject -Property $ConfigurationProperties 231 | } 232 | 233 | function Invoke-WDACCodeIntegrityPolicyBuild { 234 | <# 235 | .SYNOPSIS 236 | 237 | Facilitates building and deploying multiple base and supplemental code integrity policies. 238 | 239 | .DESCRIPTION 240 | 241 | Invoke-WDACCodeIntegrityPolicyBuild builds and, optionally, deploys and refreshes code integrity policies locally. 242 | 243 | Author: Matthew Graeber 244 | 245 | .PARAMETER CommonBasePolicyRuleOptions 246 | 247 | Specifies a set of policy rule options to apply to all generated policy files. This parameter was designed to facilitate consistency 248 | 249 | .PARAMETER BasePolicyConfiguration 250 | 251 | Specifies one or more base policy configurations that were generated by New-WDACPolicyConfiguration. 252 | 253 | .PARAMETER SupplementalPolicyConfiguration 254 | 255 | Specifies one or more supplemental policy configurations that were generated by New-WDACPolicyConfiguration. 256 | 257 | .PARAMETER MergedPolicyConfiguration 258 | 259 | Specifies a merged supplemental policy configuration that was generated by New-WDACPolicyConfiguration. 260 | 261 | .PARAMETER ArtifactPath 262 | 263 | By default, generated artifacts (code integrity policy XML and binary code integrity policy .cip files) are written to the "BuildArtifacts" directory. This parameter allows you to specify an alternate build artifact directory. The directory must already exist. 264 | 265 | .PARAMETER Deploy 266 | 267 | Copies generated binary policy files to %windir%\System32\CodeIntegrity\CiPolicies\Active. If this option is selected, the policy won't be updated until the next reboot. 268 | 269 | .PARAMETER DeployAndUpdate 270 | 271 | Copies generated binary policy files to %windir%\System32\CodeIntegrity\CiPolicies\Active and refreshes the rules so that policy changes take effect immediately. 272 | 273 | .EXAMPLE 274 | 275 | $CommonBasePolicyRuleOptions = @( 276 | 'Enabled:Unsigned System Integrity Policy', 277 | 'Enabled:Advanced Boot Options Menu', 278 | 'Enabled:Update Policy No Reboot', 279 | 'Enabled:Allow Supplemental Policies', 280 | 'Disabled:Flight Signing', 281 | 'Required:WHQL', 282 | 'Enabled:Boot Audit On Failure' 283 | ) 284 | 285 | $BasePolicyConfigurations = @( 286 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'BaseDriverPolicy.xml' -PolicyName 'BaseDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode'), 287 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'BaseUserPolicy.xml' -PolicyName 'BaseUserModeRuleset' -PolicyRuleOptions 'Disabled:Script Enforcement', 'Enabled:UMCI', 'Enabled:Audit Mode'), 288 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'MicrosoftRecommendedBlockRules.xml' -PolicyName 'MicrosoftRecommendedBlockRuleset' -PolicyRuleOptions 'Disabled:Script Enforcement', 'Enabled:UMCI', 'Enabled:Audit Mode') 289 | ) 290 | 291 | $SupplementalPolicyConfigurations = @( 292 | (New-WDACPolicyConfiguration -SupplementalPolicy -FileName 'MicrosoftSurfaceDriverPolicy.xml' -PolicyName '3rdPartyDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode') 293 | ) 294 | 295 | $MergedPolicyConfiguration = New-WDACPolicyConfiguration -MergedPolicy -PolicyName 'Merged3rdPartySoftwareRuleset' -BasePolicyToSupplement 'BaseUserModeRuleset' -PolicyRuleOptions 'Enabled:Audit Mode' 296 | 297 | $CodeIntegrityPoliciesArgs = @{ 298 | CommonBasePolicyRuleOptions = $CommonBasePolicyRuleOptions 299 | BasePolicyConfiguration = $BasePolicyConfigurations 300 | SupplementalPolicyConfiguration = $SupplementalPolicyConfigurations 301 | MergedPolicyConfiguration = $MergedPolicyConfiguration 302 | } 303 | 304 | Invoke-WDACCodeIntegrityPolicyBuild @CodeIntegrityPoliciesArgs 305 | 306 | This code specifies several policy configurations, converts them to binary form, and saves the resulting binary policy files to the "BuildArtifacts" directory. 307 | #> 308 | 309 | [CmdletBinding(DefaultParameterSetName = 'Deploy')] 310 | param ( 311 | [Parameter()] 312 | [ValidateSet('Enabled:UMCI', 313 | 'Enabled:Boot Menu Protection', 314 | 'Required:WHQL', 315 | 'Enabled:Audit Mode', 316 | 'Disabled:Flight Signing', 317 | 'Enabled:Inherit Default Policy', 318 | 'Enabled:Unsigned System Integrity Policy', 319 | 'Allowed:Debug Policy Augmented', 320 | 'Required:EV Signers', 321 | 'Enabled:Advanced Boot Options Menu', 322 | 'Enabled:Boot Audit On Failure', 323 | 'Disabled:Script Enforcement', 324 | 'Required:Enforce Store Applications', 325 | 'Enabled:Managed Installer', 326 | 'Enabled:Intelligent Security Graph Authorization', 327 | 'Enabled:Invalidate EAs on Reboot', 328 | 'Enabled:Update Policy No Reboot', 329 | 'Enabled:Allow Supplemental Policies', 330 | 'Disabled:Runtime FilePath Rule Protection', 331 | 'Enabled:Dynamic Code Security', 332 | 'Enabled:Revoked Expired As Unsigned')] 333 | [String[]] 334 | $CommonBasePolicyRuleOptions, 335 | 336 | [Parameter(Mandatory)] 337 | [PSTypeName('WDACBasePolicyConfiguration')] 338 | [PSObject[]] 339 | $BasePolicyConfiguration, 340 | 341 | [PSTypeName('WDACSupplementalPolicyConfiguration')] 342 | [PSObject[]] 343 | $SupplementalPolicyConfiguration, 344 | 345 | [PSTypeName('WDACMergedPolicyConfiguration')] 346 | [PSObject] 347 | $MergedPolicyConfiguration, 348 | 349 | [String] 350 | [ValidateScript({Test-Path -Path $_ -PathType Container})] 351 | $ArtifactPath, 352 | 353 | [Parameter(ParameterSetName = 'Deploy')] 354 | [Switch] 355 | $Deploy, 356 | 357 | [Parameter(ParameterSetName = 'DeployAndUpdate')] 358 | [Switch] 359 | $DeployAndUpdate 360 | ) 361 | 362 | # Policy ID will be set to the day's date. 363 | $DateString = (Get-Date).ToString('MM_dd_yyyy') 364 | 365 | $CommonBasePolicyRuleOptionValues = ConvertTo-WDACPolicyRuleValue -PolicyOptionStrings $CommonBasePolicyRuleOptions 366 | 367 | $ArtifactBasePath = "$PSScriptRoot\BuildArtifacts" 368 | 369 | $MergedPolicy = $null 370 | 371 | if ($ArtifactPath) { 372 | $ArtifactBasePath = $ArtifactPath 373 | } 374 | 375 | # Configure and build base policies 376 | $BasePolicies = foreach ($BaseConfig in $BasePolicyConfiguration) { 377 | $BasePolicyPath = "$PSScriptRoot\BasePolicies\$($BaseConfig.FileName)" 378 | 379 | # Each base template policy will be copied to this location prior to configuration. 380 | $BasePolicyBuildPath = "$ArtifactBasePath\$($BaseConfig.FileName)" 381 | 382 | [Xml] $PolicyXml = Get-Content -Path $BasePolicyPath -Raw 383 | 384 | $PolicyID = $PolicyXml.SiPolicy.PolicyID 385 | # $BasePolicyID = $PolicyXml.SiPolicy.BasePolicyID 386 | 387 | Copy-Item -Path $BasePolicyPath -Destination $BasePolicyBuildPath 388 | 389 | if ($CommonBasePolicyRuleOptionValues) { 390 | foreach ($CommonBaseRuleOptionValue in $CommonBasePolicyRuleOptionValues) { 391 | Set-RuleOption -FilePath $BasePolicyBuildPath -Option $CommonBaseRuleOptionValue 392 | } 393 | } 394 | 395 | $BaseConfigurationPolicyRuleOptionValues = $null 396 | 397 | if ($BaseConfig.PolicyRuleOptions) { 398 | $BaseConfigurationPolicyRuleOptionValues = ConvertTo-WDACPolicyRuleValue -PolicyOptionStrings $BaseConfig.PolicyRuleOptions 399 | } 400 | 401 | foreach ($RuleOption in $BaseConfigurationPolicyRuleOptionValues) { 402 | Set-RuleOption -FilePath $BasePolicyBuildPath -Option $RuleOption 403 | } 404 | 405 | Set-CIPolicyIdInfo -FilePath $BasePolicyBuildPath -PolicyName $BaseConfig.PolicyName -PolicyId $DateString -WarningAction SilentlyContinue 406 | 407 | [Xml] $BuiltPolicyXml = Get-Content -Path $BasePolicyBuildPath -Raw 408 | 409 | ConvertFrom-CIPolicy -XmlFilePath $BasePolicyBuildPath -BinaryFilePath "$ArtifactBasePath\$PolicyID.cip" | ForEach-Object { 410 | # ConvertFrom-CIPolicy returns a string consisting of the binary CI policy file. Resolve the path. 411 | $FileInfo = Get-Item -Path $_ 412 | $XmlFileInfo = Get-Item -Path $BasePolicyBuildPath 413 | 414 | $PolicyProperties = [Ordered] @{ 415 | PolicyType = 'Base' 416 | XmlFileInfo = $XmlFileInfo 417 | BinaryFileInfo = $FileInfo 418 | PolicyID = $BuiltPolicyXml.SiPolicy.PolicyID 419 | BasePolicyID = $BuiltPolicyXml.SiPolicy.BasePolicyID 420 | PolicyInfoName = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Name' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 421 | PolicyInfoID = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Id' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 422 | } 423 | 424 | New-Object -TypeName PSObject -Property $PolicyProperties 425 | } 426 | } 427 | 428 | # Configure and build supplemental policies 429 | if ($SupplementalPolicyConfiguration) 430 | { 431 | $SupplementalPolicies = foreach ($SupplementalConfig in $SupplementalPolicyConfiguration) { 432 | $SupplementalPolicyPath = "$PSScriptRoot\SupplementalPolicies\$($SupplementalConfig.FileName)" 433 | 434 | # Each base template policy will be copied to this location prior to configuration. 435 | $SupplementalPolicyBuildPath = "$ArtifactBasePath\$($SupplementalConfig.FileName)" 436 | 437 | [Xml] $PolicyXml = Get-Content -Path $SupplementalPolicyPath -Raw 438 | 439 | $PolicyID = $PolicyXml.SiPolicy.PolicyID 440 | 441 | Copy-Item -Path $SupplementalPolicyPath -Destination $SupplementalPolicyBuildPath 442 | 443 | if ($CommonBasePolicyRuleOptions) { 444 | foreach ($CommonBaseRuleOption in $CommonBasePolicyRuleOptionValues) { 445 | Set-RuleOption -FilePath $SupplementalPolicyBuildPath -Option $CommonBaseRuleOption 446 | } 447 | } 448 | 449 | $SupplementalConfigurationPolicyRuleOptionValues = $null 450 | 451 | if ($SupplementalConfig.PolicyRuleOptions) { 452 | $SupplementalConfigurationPolicyRuleOptionValues = ConvertTo-WDACPolicyRuleValue -PolicyOptionStrings $SupplementalConfig.PolicyRuleOptions 453 | } 454 | 455 | foreach ($RuleOption in $SupplementalConfigurationPolicyRuleOptionValues) { 456 | Set-RuleOption -FilePath $SupplementalPolicyBuildPath -Option $RuleOption 457 | } 458 | 459 | # Delete the "Enabled:Allow Supplemental Policies" if it was specified in the common policy rule option config. 460 | Set-RuleOption -FilePath $SupplementalPolicyBuildPath -Option 17 -Delete 461 | 462 | Set-CIPolicyIdInfo -FilePath $SupplementalPolicyBuildPath -PolicyName $SupplementalConfig.PolicyName -PolicyId $DateString -WarningAction SilentlyContinue 463 | 464 | [Xml] $BuiltPolicyXml = Get-Content -Path $SupplementalPolicyBuildPath -Raw 465 | 466 | ConvertFrom-CIPolicy -XmlFilePath $SupplementalPolicyBuildPath -BinaryFilePath "$ArtifactBasePath\$PolicyID.cip" | ForEach-Object { 467 | # ConvertFrom-CIPolicy returns a string consisting of the binary CI policy file. Resolve the path. 468 | $FileInfo = Get-Item -Path $_ 469 | $XmlFileInfo = Get-Item -Path $SupplementalPolicyBuildPath 470 | 471 | $PolicyProperties = [Ordered] @{ 472 | PolicyType = 'Supplemental' 473 | XmlFileInfo = $XmlFileInfo 474 | BinaryFileInfo = $FileInfo 475 | PolicyID = $BuiltPolicyXml.SiPolicy.PolicyID 476 | BasePolicyID = $BuiltPolicyXml.SiPolicy.BasePolicyID 477 | PolicyInfoName = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Name' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 478 | PolicyInfoID = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Id' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 479 | } 480 | 481 | New-Object -TypeName PSObject -Property $PolicyProperties 482 | } 483 | } 484 | } 485 | 486 | # Build the app-specific policy 487 | if ($MergedPolicyConfiguration) { 488 | if (-not ($BasePolicies | Where-Object { $_.PolicyInfoName -eq $MergedPolicyConfiguration.BasePolicyToSupplement })) { 489 | Write-Error "The merged, application-specific supplemental policy is expected to supplement the following base policy that was not supplied: $($MergedPolicyConfiguration.BasePolicyToSupplement)" 490 | return 491 | } 492 | 493 | $BasePolicyID = $BasePolicies | Where-Object { $_.PolicyInfoName -eq $MergedPolicyConfiguration.BasePolicyToSupplement } | Select-Object -ExpandProperty BasePolicyId 494 | 495 | $CopiedAppTemplateDestination = "$ArtifactBasePath\AppSpecificPolicyTemplate.xml" 496 | 497 | # Copy the application-specific template policy to the artifacts directory. 498 | # This is done because the BasePolicyID element is going to be updated in the XML. 499 | # Assign the application-specific supplemental policy base policy ID to the base policy name specified. 500 | 501 | # I'd love to use the supported cmdlet for this but I really don't like that you can't avoid 502 | # Having the PolicyID reset. 503 | # Set-CIPolicyIdInfo -FilePath $CopiedAppTemplateDestination -SupplementsBasePolicyID $BasePolicyID 504 | 505 | $XmlString = Get-Content -Path "$PSScriptRoot\AppSpecificPolicies\AppSpecificPolicyTemplate.xml" -Raw 506 | 507 | $BasePolicyIdToReplace = [Xml] $XmlString | Select-Object -ExpandProperty SiPolicy | Select-Object -ExpandProperty BasePolicyId 508 | 509 | $ReplacedXmlString = $XmlString -replace "$BasePolicyIdToReplace", "$BasePolicyID" 510 | 511 | Out-File -FilePath $CopiedAppTemplateDestination -InputObject $ReplacedXmlString -Encoding utf8 -ErrorAction Stop 512 | 513 | # AppSpecificPolicyTemplate.xml is used for maintaining file rule options. 514 | # Note: AppSpecificPolicyTemplate.xml must be the first policy file specified as this is what Merge-CIPolicy takes policy options from. 515 | $AppSpecificPolicyFiles = New-Object -TypeName String[](0) 516 | 517 | $AppSpecificPolicyFiles += $CopiedAppTemplateDestination 518 | Get-ChildItem "$PSScriptRoot\AppSpecificPolicies\*.xml" -Exclude 'AppSpecificPolicyTemplate.xml' | 519 | Select-Object -ExpandProperty FullName | 520 | ForEach-Object { $AppSpecificPolicyFiles += $_ } 521 | 522 | $MergedPolicyPath = "$ArtifactBasePath\MergedPolicy.xml" 523 | 524 | $null = Merge-CIPolicy -OutputFilePath $MergedPolicyPath -PolicyPaths ([String[]] $AppSpecificPolicyFiles) 525 | 526 | [Xml] $PolicyXml = Get-Content -Path $MergedPolicyPath -Raw 527 | 528 | $PolicyID = $PolicyXml.SiPolicy.PolicyID 529 | 530 | if ($CommonBasePolicyRuleOptions) 531 | { 532 | foreach ($CommonBaseRuleOption in $CommonBasePolicyRuleOptionValues) { 533 | Set-RuleOption -FilePath $MergedPolicyPath -Option $CommonBaseRuleOption 534 | } 535 | } 536 | 537 | $MergedConfigurationPolicyRuleOptionValues = $null 538 | 539 | if ($MergedPolicyConfiguration.PolicyRuleOptions) { 540 | $MergedConfigurationPolicyRuleOptionValues = ConvertTo-WDACPolicyRuleValue -PolicyOptionStrings $MergedPolicyConfiguration.PolicyRuleOptions 541 | } 542 | 543 | foreach ($RuleOption in $MergedConfigurationPolicyRuleOptionValues) { 544 | Set-RuleOption -FilePath $MergedPolicyPath -Option $RuleOption 545 | } 546 | 547 | # Delete the "Enabled:Allow Supplemental Policies" if it was specified in the common policy rule option config. 548 | Set-RuleOption -FilePath $MergedPolicyPath -Option 17 -Delete 549 | 550 | Set-CIPolicyIdInfo -FilePath $MergedPolicyPath -PolicyName $MergedPolicyConfiguration.PolicyName -PolicyId $DateString -WarningAction SilentlyContinue 551 | 552 | [Xml] $BuiltPolicyXml = Get-Content -Path $MergedPolicyPath -Raw 553 | 554 | ConvertFrom-CIPolicy -XmlFilePath $MergedPolicyPath -BinaryFilePath "$ArtifactBasePath\$PolicyID.cip" | ForEach-Object { 555 | # ConvertFrom-CIPolicy returns a string consisting of the binary CI policy file. Resolve the path. 556 | $FileInfo = Get-Item -Path $_ 557 | $XmlFileInfo = Get-Item -Path $MergedPolicyPath 558 | 559 | $PolicyProperties = [Ordered] @{ 560 | PolicyType = 'MergedSupplemental' 561 | XmlFileInfo = $XmlFileInfo 562 | BinaryFileInfo = $FileInfo 563 | PolicyID = $BuiltPolicyXml.SiPolicy.PolicyID 564 | BasePolicyID = $BuiltPolicyXml.SiPolicy.BasePolicyID 565 | PolicyInfoName = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Name' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 566 | PolicyInfoID = ($BuiltPolicyXml.SiPolicy.Settings.Setting | Where-Object { $_.ValueName -eq 'Id' } | Select-Object -ExpandProperty Value | Select-Object -ExpandProperty String) 567 | } 568 | 569 | $MergedPolicy = New-Object -TypeName PSObject -Property $PolicyProperties 570 | } 571 | } 572 | 573 | # Build a list of the generated binary policy files so that only those files are deployed 574 | # when -Deploy or -DeployAndUpdate are specified. 575 | $BinaryPolicyFiles = New-Object -TypeName String[](0) 576 | 577 | if ($BasePolicies) { 578 | $BasePolicies 579 | $BasePolicies | ForEach-Object { $BinaryPolicyFiles += $_.BinaryFileInfo } 580 | } 581 | 582 | if ($SupplementalPolicies) { 583 | $SupplementalPolicies 584 | $SupplementalPolicies | ForEach-Object { $BinaryPolicyFiles += $_.BinaryFileInfo } 585 | } 586 | 587 | if ($MergedPolicy) { 588 | $MergedPolicy 589 | $BinaryPolicyFiles += $MergedPolicy.BinaryFileInfo 590 | } 591 | 592 | # Copy all binary policy files to the relevant WDAC CI policy directory. 593 | if ($Deploy -or $DeployAndUpdate) { 594 | $BinaryPolicyFiles | Get-ChildItem | ForEach-Object { 595 | $DestinationDir = "$Env:windir\System32\CodeIntegrity\CiPolicies\Active" 596 | 597 | Write-Verbose "Copying $($_.FullName) to $DestinationDir." 598 | $_ | Copy-Item -Destination $DestinationDir -PassThru 599 | } 600 | } 601 | 602 | # Refresh all active code integrity policies so that the changes can take effect immediately without needing to reboot. 603 | if ($DeployAndUpdate) { 604 | Get-ChildItem -Path "$Env:windir\System32\CodeIntegrity\CiPolicies\Active\*.cip" | ForEach-Object { 605 | Write-Verbose "Applying the following policy: $($_.FullName)" 606 | 607 | $Result = Invoke-CimMethod -Namespace root\Microsoft\Windows\CI -ClassName PS_UpdateAndCompareCIPolicy -MethodName Update -Arguments @{ FilePath = $_.FullName } 608 | if ($Result.ReturnValue -ne 0) { 609 | Write-Error "The following policy failed to refresh: $($_.FullName). Return value: $($Result.ReturnValue)" 610 | } 611 | } 612 | } 613 | } 614 | 615 | filter Update-WDACBinaryCodeIntegrityPolicy { 616 | <# 617 | .SYNOPSIS 618 | 619 | Refreshes a binary code integrity policy without requiring a reboot. 620 | 621 | .DESCRIPTION 622 | 623 | Update-WDACBinaryCodeIntegrityPolicy is used to explicitly refresh one or more binary code integrity policies without requiring a reboot. In order to support this scenario, your base policy must be configured with the "Enabled:Update Policy No Reboot" option. 624 | 625 | Author: Matthew Graeber 626 | 627 | .PARAMETER Path 628 | 629 | Specifies the path to a binary code integrity file that you would like to explicitly update without rebooting. A binary code integrity policy will have a file extension of .p7b or .cip in a multi-policy scenario. 630 | 631 | .EXAMPLE 632 | 633 | Update-WDACBinaryPolicy -Path C:\Windows\System32\CodeIntegrity\SIPolicy.p7b 634 | 635 | Updating a single policy. 636 | 637 | .EXAMPLE 638 | 639 | Get-ChildItem -Path "$Env:windir\System32\CodeIntegrity\CiPolicies\Active\*.cip" | Update-WDACBinaryCodeIntegrityPolicy 640 | 641 | Updating all policies in a multi-policy scenario. 642 | #> 643 | 644 | [CmdletBinding()] 645 | param ( 646 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] 647 | [String] 648 | [ValidateNotNullOrEmpty()] 649 | [Alias('FullName')] 650 | $Path 651 | ) 652 | 653 | $FullPath = Resolve-Path $Path 654 | 655 | $Result = Invoke-CimMethod -Namespace root\Microsoft\Windows\CI -ClassName PS_UpdateAndCompareCIPolicy -MethodName Update -Arguments @{ FilePath = $FullPath.Path } 656 | 657 | if ($Result.ReturnValue -ne 0) { 658 | Write-Error "The following policy failed to refresh: $($FullPath.Path). Return value: $($Result.ReturnValue)" 659 | } 660 | } 661 | 662 | function Disable-WDACDeployedPolicy { 663 | <# 664 | .SYNOPSIS 665 | 666 | Disables the currently deployed code integrity policy. Note: this does not delete deployed policy files in %windir%\System32\CodeIntegrity. Those should be removed manually, if desired. 667 | 668 | .EXAMPLE 669 | 670 | Disable-WDACDeployedPolicy 671 | #> 672 | 673 | Invoke-CimMethod -Namespace root\Microsoft\Windows\CI -ClassName PS_UpdateAndCompareCIPolicy -MethodName Delete 674 | } -------------------------------------------------------------------------------- /BuildArtifacts/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattifestation/WDACTools/07be9ddfed49b56dd1952f7eb0361f6d540c4bf5/BuildArtifacts/.empty -------------------------------------------------------------------------------- /CIPolicyParser.psm1: -------------------------------------------------------------------------------- 1 | function ConvertTo-WDACCodeIntegrityPolicy { 2 | <# 3 | .SYNOPSIS 4 | 5 | Converts a binary file that contains a Code Integrity policy into XML format. 6 | 7 | Author: Matthew Graeber (@mattifestation) 8 | Contributors: James Forshaw (@tiraniddo) - thanks for the major bug fixes! 9 | License: BSD 3-Clause 10 | 11 | Modified to add propert PKCS#7 support and the new DG policy header version. 12 | 13 | .DESCRIPTION 14 | 15 | 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. 16 | 17 | Note: the process of converting an XML file to a binary policy is lossy. ID, Name, and FriendlyName attributes are all lost in the process. ConvertTo-WDACCodeIntegrityPolicy auto-generates ID and Name properties when necessary. 18 | 19 | ConvertTo-WDACCodeIntegrityPolicy supports both signed and unsigned policies. 20 | 21 | .PARAMETER BinaryFilePath 22 | 23 | Specifies the path of the binary policy file that this cmdlet converts. Deployed binary policy files are located in %SystemRoot%\System32\CodeIntegrity\SIPolicy.p7b. 24 | 25 | .PARAMETER XmlFilePath 26 | 27 | Specifies the path for the output converted policy XML file. 28 | 29 | .EXAMPLE 30 | 31 | ConvertTo-WDACCodeIntegrityPolicy -BinaryFilePath C:\Windows\System32\CodeIntegrity\SIPolicy.p7b -XmlFilePath recovered_policy.xml 32 | 33 | .OUTPUTS 34 | 35 | System.IO.FileInfo 36 | 37 | Outputs a recovered Code Integrity policy XML file. 38 | #> 39 | 40 | [CmdletBinding(SupportsShouldProcess)] 41 | [OutputType([System.IO.FileInfo])] 42 | param ( 43 | [Parameter(Position = 0, Mandatory)] 44 | [String] 45 | [ValidateScript({ [IO.File]::Exists((Resolve-Path $_).Path) })] 46 | $BinaryFilePath, 47 | 48 | [Parameter(Position = 1, Mandatory)] 49 | [String] 50 | [ValidateNotNullOrEmpty()] 51 | $XmlFilePath 52 | ) 53 | 54 | Set-StrictMode -Version Latest 55 | 56 | $CorruptPolicyErr = 'The CI policy may be corrupt.' 57 | 58 | $HeaderLengthMax = 0x44 59 | $GuidLength = 0x10 60 | 61 | # Generated code that enables CI policy XML serialization. 62 | $TypeDef = @' 63 | using System.Xml.Serialization; 64 | 65 | namespace CodeIntegrity { 66 | [System.FlagsAttribute()] 67 | public enum PolicyRules { 68 | EnabledUMCI = 0x00000004, 69 | EnabledBootMenuProtection = 0x00000008, 70 | EnabledIntelligentSecurityGraphAuthorization = 0x00000010, 71 | EnabledInvalidateEAsonReboot = 0x00000020, 72 | EnabledWindowsLockdownTrialMode = 0x00000040, 73 | RequiredWHQL = 0x00000080, 74 | EnabledDeveloperModeDynamicCodeTrust = 0x00000100, 75 | EnabledAllowSupplementalPolicies = 0x00000400, 76 | DisabledRuntimeFilePathRuleProtection = 0x00000800, 77 | EnabledRevokedExpiredAsUnsigned = 0x00002000, 78 | EnabledAuditMode = 0x00010000, 79 | DisabledFlightSigning = 0x00020000, 80 | EnabledInheritDefaultPolicy = 0x00040000, 81 | EnabledUnsignedSystemIntegrityPolicy = 0x00080000, 82 | EnabledDynamicCodeSecurity = 0x00100000, 83 | RequiredEVSigners = 0x00200000, 84 | EnabledBootAuditOnFailure = 0x00400000, 85 | EnabledAdvancedBootOptionsMenu = 0x00800000, 86 | DisabledScriptEnforcement = 0x01000000, 87 | RequiredEnforceStoreApplications = 0x02000000, 88 | EnabledSecureSettingPolicy = 0x04000000, 89 | EnabledManagedInstaller = 0x08000000, 90 | EnabledUpdatePolicyNoReboot = 0x10000000, 91 | EnabledConditionalWindowsLockdownPolicy = 0x20000000 92 | } 93 | 94 | // The following code was generated with: xsd.exe C:\Windows\schemas\CodeIntegrity\cipolicy.xsd /classes /namespace:CodeIntegrity 95 | 96 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 97 | [System.SerializableAttribute()] 98 | [System.Diagnostics.DebuggerStepThroughAttribute()] 99 | [System.ComponentModel.DesignerCategoryAttribute("code")] 100 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 101 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 102 | public partial class Macros { 103 | 104 | private MacrosMacro[] macroField; 105 | 106 | /// 107 | [System.Xml.Serialization.XmlElementAttribute("Macro")] 108 | public MacrosMacro[] Macro { 109 | get { 110 | return this.macroField; 111 | } 112 | set { 113 | this.macroField = value; 114 | } 115 | } 116 | } 117 | 118 | /// 119 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 120 | [System.SerializableAttribute()] 121 | [System.Diagnostics.DebuggerStepThroughAttribute()] 122 | [System.ComponentModel.DesignerCategoryAttribute("code")] 123 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 124 | public partial class MacrosMacro { 125 | 126 | private string idField; 127 | 128 | private string valueField; 129 | 130 | /// 131 | [System.Xml.Serialization.XmlAttributeAttribute()] 132 | public string Id { 133 | get { 134 | return this.idField; 135 | } 136 | set { 137 | this.idField = value; 138 | } 139 | } 140 | 141 | /// 142 | [System.Xml.Serialization.XmlAttributeAttribute()] 143 | public string Value { 144 | get { 145 | return this.valueField; 146 | } 147 | set { 148 | this.valueField = value; 149 | } 150 | } 151 | } 152 | 153 | /// 154 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 155 | [System.SerializableAttribute()] 156 | [System.Diagnostics.DebuggerStepThroughAttribute()] 157 | [System.ComponentModel.DesignerCategoryAttribute("code")] 158 | [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-microsoft-com:sipolicy")] 159 | public partial class RuleType { 160 | 161 | private OptionType itemField; 162 | 163 | /// 164 | [System.Xml.Serialization.XmlElementAttribute("Option")] 165 | public OptionType Item { 166 | get { 167 | return this.itemField; 168 | } 169 | set { 170 | this.itemField = value; 171 | } 172 | } 173 | } 174 | 175 | /// 176 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 177 | [System.SerializableAttribute()] 178 | [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-microsoft-com:sipolicy")] 179 | public enum OptionType { 180 | 181 | /// 182 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:UMCI")] 183 | EnabledUMCI, 184 | 185 | /// 186 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Boot Menu Protection")] 187 | EnabledBootMenuProtection, 188 | 189 | /// 190 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Intelligent Security Graph Authorization")] 191 | EnabledIntelligentSecurityGraphAuthorization, 192 | 193 | /// 194 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Invalidate EAs on Reboot")] 195 | EnabledInvalidateEAsonReboot, 196 | 197 | /// 198 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Windows Lockdown Trial Mode")] 199 | EnabledWindowsLockdownTrialMode, 200 | 201 | /// 202 | [System.Xml.Serialization.XmlEnumAttribute("Required:WHQL")] 203 | RequiredWHQL, 204 | 205 | /// 206 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Developer Mode Dynamic Code Trust")] 207 | EnabledDeveloperModeDynamicCodeTrust, 208 | 209 | /// 210 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Allow Supplemental Policies")] 211 | EnabledAllowSupplementalPolicies, 212 | 213 | /// 214 | [System.Xml.Serialization.XmlEnumAttribute("Disabled:Runtime FilePath Rule Protection")] 215 | DisabledRuntimeFilePathRuleProtection, 216 | 217 | /// 218 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Revoked Expired As Unsigned")] 219 | EnabledRevokedExpiredAsUnsigned, 220 | 221 | /// 222 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Audit Mode")] 223 | EnabledAuditMode, 224 | 225 | /// 226 | [System.Xml.Serialization.XmlEnumAttribute("Disabled:Flight Signing")] 227 | DisabledFlightSigning, 228 | 229 | /// 230 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Inherit Default Policy")] 231 | EnabledInheritDefaultPolicy, 232 | 233 | /// 234 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Unsigned System Integrity Policy")] 235 | EnabledUnsignedSystemIntegrityPolicy, 236 | 237 | /// 238 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Dynamic Code Security")] 239 | EnabledDynamicCodeSecurity, 240 | 241 | /// 242 | [System.Xml.Serialization.XmlEnumAttribute("Required:EV Signers")] 243 | RequiredEVSigners, 244 | 245 | /// 246 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Boot Audit On Failure")] 247 | EnabledBootAuditOnFailure, 248 | 249 | /// 250 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Advanced Boot Options Menu")] 251 | EnabledAdvancedBootOptionsMenu, 252 | 253 | /// 254 | [System.Xml.Serialization.XmlEnumAttribute("Disabled:Script Enforcement")] 255 | DisabledScriptEnforcement, 256 | 257 | /// 258 | [System.Xml.Serialization.XmlEnumAttribute("Required:Enforce Store Applications")] 259 | RequiredEnforceStoreApplications, 260 | 261 | /// 262 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Secure Setting Policy")] 263 | EnabledSecureSettingPolicy, 264 | 265 | /// 266 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Managed Installer")] 267 | EnabledManagedInstaller, 268 | 269 | /// 270 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Update Policy No Reboot")] 271 | EnabledUpdatePolicyNoReboot, 272 | 273 | /// 274 | [System.Xml.Serialization.XmlEnumAttribute("Enabled:Conditional Windows Lockdown Policy")] 275 | EnabledConditionalWindowsLockdownPolicy, 276 | } 277 | 278 | /// 279 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 280 | [System.SerializableAttribute()] 281 | [System.Diagnostics.DebuggerStepThroughAttribute()] 282 | [System.ComponentModel.DesignerCategoryAttribute("code")] 283 | [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-microsoft-com:sipolicy")] 284 | public partial class SettingValueType { 285 | 286 | private object itemField; 287 | 288 | /// 289 | [System.Xml.Serialization.XmlElementAttribute("Binary", typeof(byte[]), DataType="hexBinary")] 290 | [System.Xml.Serialization.XmlElementAttribute("Boolean", typeof(bool))] 291 | [System.Xml.Serialization.XmlElementAttribute("DWord", typeof(uint))] 292 | [System.Xml.Serialization.XmlElementAttribute("String", typeof(string))] 293 | public object Item { 294 | get { 295 | return this.itemField; 296 | } 297 | set { 298 | this.itemField = value; 299 | } 300 | } 301 | } 302 | 303 | /// 304 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 305 | [System.SerializableAttribute()] 306 | [System.Diagnostics.DebuggerStepThroughAttribute()] 307 | [System.ComponentModel.DesignerCategoryAttribute("code")] 308 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 309 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 310 | public partial class Setting { 311 | 312 | private SettingValueType valueField; 313 | 314 | private string providerField; 315 | 316 | private string keyField; 317 | 318 | private string valueNameField; 319 | 320 | /// 321 | public SettingValueType Value { 322 | get { 323 | return this.valueField; 324 | } 325 | set { 326 | this.valueField = value; 327 | } 328 | } 329 | 330 | /// 331 | [System.Xml.Serialization.XmlAttributeAttribute()] 332 | public string Provider { 333 | get { 334 | return this.providerField; 335 | } 336 | set { 337 | this.providerField = value; 338 | } 339 | } 340 | 341 | /// 342 | [System.Xml.Serialization.XmlAttributeAttribute()] 343 | public string Key { 344 | get { 345 | return this.keyField; 346 | } 347 | set { 348 | this.keyField = value; 349 | } 350 | } 351 | 352 | /// 353 | [System.Xml.Serialization.XmlAttributeAttribute()] 354 | public string ValueName { 355 | get { 356 | return this.valueNameField; 357 | } 358 | set { 359 | this.valueNameField = value; 360 | } 361 | } 362 | } 363 | 364 | /// 365 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 366 | [System.SerializableAttribute()] 367 | [System.Diagnostics.DebuggerStepThroughAttribute()] 368 | [System.ComponentModel.DesignerCategoryAttribute("code")] 369 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 370 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 371 | public partial class Settings { 372 | 373 | private Setting[] itemsField; 374 | 375 | /// 376 | [System.Xml.Serialization.XmlElementAttribute("Setting")] 377 | public Setting[] Items { 378 | get { 379 | return this.itemsField; 380 | } 381 | set { 382 | this.itemsField = value; 383 | } 384 | } 385 | } 386 | 387 | /// 388 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 389 | [System.SerializableAttribute()] 390 | [System.Diagnostics.DebuggerStepThroughAttribute()] 391 | [System.ComponentModel.DesignerCategoryAttribute("code")] 392 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 393 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 394 | public partial class CertEKU { 395 | 396 | private string idField; 397 | 398 | /// 399 | [System.Xml.Serialization.XmlAttributeAttribute()] 400 | public string ID { 401 | get { 402 | return this.idField; 403 | } 404 | set { 405 | this.idField = value; 406 | } 407 | } 408 | } 409 | 410 | /// 411 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 412 | [System.SerializableAttribute()] 413 | [System.Diagnostics.DebuggerStepThroughAttribute()] 414 | [System.ComponentModel.DesignerCategoryAttribute("code")] 415 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 416 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 417 | public partial class CertOemID { 418 | 419 | private string valueField; 420 | 421 | /// 422 | [System.Xml.Serialization.XmlAttributeAttribute()] 423 | public string Value { 424 | get { 425 | return this.valueField; 426 | } 427 | set { 428 | this.valueField = value; 429 | } 430 | } 431 | } 432 | 433 | /// 434 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 435 | [System.SerializableAttribute()] 436 | [System.Diagnostics.DebuggerStepThroughAttribute()] 437 | [System.ComponentModel.DesignerCategoryAttribute("code")] 438 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 439 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 440 | public partial class CertPublisher { 441 | 442 | private string valueField; 443 | 444 | /// 445 | [System.Xml.Serialization.XmlAttributeAttribute()] 446 | public string Value { 447 | get { 448 | return this.valueField; 449 | } 450 | set { 451 | this.valueField = value; 452 | } 453 | } 454 | } 455 | 456 | /// 457 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 458 | [System.SerializableAttribute()] 459 | [System.Diagnostics.DebuggerStepThroughAttribute()] 460 | [System.ComponentModel.DesignerCategoryAttribute("code")] 461 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 462 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 463 | public partial class CertIssuer { 464 | 465 | private string valueField; 466 | 467 | /// 468 | [System.Xml.Serialization.XmlAttributeAttribute()] 469 | public string Value { 470 | get { 471 | return this.valueField; 472 | } 473 | set { 474 | this.valueField = value; 475 | } 476 | } 477 | } 478 | 479 | /// 480 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 481 | [System.SerializableAttribute()] 482 | [System.Diagnostics.DebuggerStepThroughAttribute()] 483 | [System.ComponentModel.DesignerCategoryAttribute("code")] 484 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 485 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 486 | public partial class CertRoot { 487 | 488 | private CertEnumType typeField; 489 | 490 | private byte[] valueField; 491 | 492 | /// 493 | [System.Xml.Serialization.XmlAttributeAttribute()] 494 | public CertEnumType Type { 495 | get { 496 | return this.typeField; 497 | } 498 | set { 499 | this.typeField = value; 500 | } 501 | } 502 | 503 | /// 504 | [System.Xml.Serialization.XmlAttributeAttribute(DataType="hexBinary")] 505 | public byte[] Value { 506 | get { 507 | return this.valueField; 508 | } 509 | set { 510 | this.valueField = value; 511 | } 512 | } 513 | } 514 | 515 | /// 516 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 517 | [System.SerializableAttribute()] 518 | [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-microsoft-com:sipolicy")] 519 | public enum CertEnumType { 520 | 521 | /// 522 | TBS, 523 | 524 | /// 525 | Wellknown, 526 | } 527 | 528 | /// 529 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 530 | [System.SerializableAttribute()] 531 | [System.Diagnostics.DebuggerStepThroughAttribute()] 532 | [System.ComponentModel.DesignerCategoryAttribute("code")] 533 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 534 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 535 | public partial class ProductSigners { 536 | 537 | private AllowedSigners allowedSignersField; 538 | 539 | private DeniedSigners deniedSignersField; 540 | 541 | private FileRulesRef fileRulesRefField; 542 | 543 | /// 544 | public AllowedSigners AllowedSigners { 545 | get { 546 | return this.allowedSignersField; 547 | } 548 | set { 549 | this.allowedSignersField = value; 550 | } 551 | } 552 | 553 | /// 554 | public DeniedSigners DeniedSigners { 555 | get { 556 | return this.deniedSignersField; 557 | } 558 | set { 559 | this.deniedSignersField = value; 560 | } 561 | } 562 | 563 | /// 564 | public FileRulesRef FileRulesRef { 565 | get { 566 | return this.fileRulesRefField; 567 | } 568 | set { 569 | this.fileRulesRefField = value; 570 | } 571 | } 572 | } 573 | 574 | /// 575 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 576 | [System.SerializableAttribute()] 577 | [System.Diagnostics.DebuggerStepThroughAttribute()] 578 | [System.ComponentModel.DesignerCategoryAttribute("code")] 579 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 580 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 581 | public partial class AllowedSigners { 582 | 583 | private AllowedSigner[] allowedSignerField; 584 | 585 | private string workaroundField; 586 | 587 | /// 588 | [System.Xml.Serialization.XmlElementAttribute("AllowedSigner")] 589 | public AllowedSigner[] AllowedSigner { 590 | get { 591 | return this.allowedSignerField; 592 | } 593 | set { 594 | this.allowedSignerField = value; 595 | } 596 | } 597 | 598 | /// 599 | [System.Xml.Serialization.XmlAttributeAttribute()] 600 | public string Workaround { 601 | get { 602 | return this.workaroundField; 603 | } 604 | set { 605 | this.workaroundField = value; 606 | } 607 | } 608 | } 609 | 610 | /// 611 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 612 | [System.SerializableAttribute()] 613 | [System.Diagnostics.DebuggerStepThroughAttribute()] 614 | [System.ComponentModel.DesignerCategoryAttribute("code")] 615 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 616 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 617 | public partial class AllowedSigner { 618 | 619 | private ExceptDenyRule[] exceptDenyRuleField; 620 | 621 | private string signerIdField; 622 | 623 | /// 624 | [System.Xml.Serialization.XmlElementAttribute("ExceptDenyRule")] 625 | public ExceptDenyRule[] ExceptDenyRule { 626 | get { 627 | return this.exceptDenyRuleField; 628 | } 629 | set { 630 | this.exceptDenyRuleField = value; 631 | } 632 | } 633 | 634 | /// 635 | [System.Xml.Serialization.XmlAttributeAttribute()] 636 | public string SignerId { 637 | get { 638 | return this.signerIdField; 639 | } 640 | set { 641 | this.signerIdField = value; 642 | } 643 | } 644 | } 645 | 646 | /// 647 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 648 | [System.SerializableAttribute()] 649 | [System.Diagnostics.DebuggerStepThroughAttribute()] 650 | [System.ComponentModel.DesignerCategoryAttribute("code")] 651 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 652 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 653 | public partial class ExceptDenyRule { 654 | 655 | private string denyRuleIDField; 656 | 657 | /// 658 | [System.Xml.Serialization.XmlAttributeAttribute()] 659 | public string DenyRuleID { 660 | get { 661 | return this.denyRuleIDField; 662 | } 663 | set { 664 | this.denyRuleIDField = value; 665 | } 666 | } 667 | } 668 | 669 | /// 670 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 671 | [System.SerializableAttribute()] 672 | [System.Diagnostics.DebuggerStepThroughAttribute()] 673 | [System.ComponentModel.DesignerCategoryAttribute("code")] 674 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 675 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 676 | public partial class DeniedSigners { 677 | 678 | private DeniedSigner[] deniedSignerField; 679 | 680 | private string workaroundField; 681 | 682 | /// 683 | [System.Xml.Serialization.XmlElementAttribute("DeniedSigner")] 684 | public DeniedSigner[] DeniedSigner { 685 | get { 686 | return this.deniedSignerField; 687 | } 688 | set { 689 | this.deniedSignerField = value; 690 | } 691 | } 692 | 693 | /// 694 | [System.Xml.Serialization.XmlAttributeAttribute()] 695 | public string Workaround { 696 | get { 697 | return this.workaroundField; 698 | } 699 | set { 700 | this.workaroundField = value; 701 | } 702 | } 703 | } 704 | 705 | /// 706 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 707 | [System.SerializableAttribute()] 708 | [System.Diagnostics.DebuggerStepThroughAttribute()] 709 | [System.ComponentModel.DesignerCategoryAttribute("code")] 710 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 711 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 712 | public partial class DeniedSigner { 713 | 714 | private ExceptAllowRule[] exceptAllowRuleField; 715 | 716 | private string signerIdField; 717 | 718 | /// 719 | [System.Xml.Serialization.XmlElementAttribute("ExceptAllowRule")] 720 | public ExceptAllowRule[] ExceptAllowRule { 721 | get { 722 | return this.exceptAllowRuleField; 723 | } 724 | set { 725 | this.exceptAllowRuleField = value; 726 | } 727 | } 728 | 729 | /// 730 | [System.Xml.Serialization.XmlAttributeAttribute()] 731 | public string SignerId { 732 | get { 733 | return this.signerIdField; 734 | } 735 | set { 736 | this.signerIdField = value; 737 | } 738 | } 739 | } 740 | 741 | /// 742 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 743 | [System.SerializableAttribute()] 744 | [System.Diagnostics.DebuggerStepThroughAttribute()] 745 | [System.ComponentModel.DesignerCategoryAttribute("code")] 746 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 747 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 748 | public partial class ExceptAllowRule { 749 | 750 | private string allowRuleIDField; 751 | 752 | /// 753 | [System.Xml.Serialization.XmlAttributeAttribute()] 754 | public string AllowRuleID { 755 | get { 756 | return this.allowRuleIDField; 757 | } 758 | set { 759 | this.allowRuleIDField = value; 760 | } 761 | } 762 | } 763 | 764 | /// 765 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 766 | [System.SerializableAttribute()] 767 | [System.Diagnostics.DebuggerStepThroughAttribute()] 768 | [System.ComponentModel.DesignerCategoryAttribute("code")] 769 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 770 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 771 | public partial class FileRulesRef { 772 | 773 | private FileRuleRef[] fileRuleRefField; 774 | 775 | private string workaroundField; 776 | 777 | /// 778 | [System.Xml.Serialization.XmlElementAttribute("FileRuleRef")] 779 | public FileRuleRef[] FileRuleRef { 780 | get { 781 | return this.fileRuleRefField; 782 | } 783 | set { 784 | this.fileRuleRefField = value; 785 | } 786 | } 787 | 788 | /// 789 | [System.Xml.Serialization.XmlAttributeAttribute()] 790 | public string Workaround { 791 | get { 792 | return this.workaroundField; 793 | } 794 | set { 795 | this.workaroundField = value; 796 | } 797 | } 798 | } 799 | 800 | /// 801 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 802 | [System.SerializableAttribute()] 803 | [System.Diagnostics.DebuggerStepThroughAttribute()] 804 | [System.ComponentModel.DesignerCategoryAttribute("code")] 805 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 806 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 807 | public partial class FileRuleRef { 808 | 809 | private string ruleIDField; 810 | 811 | /// 812 | [System.Xml.Serialization.XmlAttributeAttribute()] 813 | public string RuleID { 814 | get { 815 | return this.ruleIDField; 816 | } 817 | set { 818 | this.ruleIDField = value; 819 | } 820 | } 821 | } 822 | 823 | /// 824 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 825 | [System.SerializableAttribute()] 826 | [System.Diagnostics.DebuggerStepThroughAttribute()] 827 | [System.ComponentModel.DesignerCategoryAttribute("code")] 828 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 829 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 830 | public partial class TestSigners { 831 | 832 | private AllowedSigners allowedSignersField; 833 | 834 | private DeniedSigners deniedSignersField; 835 | 836 | private FileRulesRef fileRulesRefField; 837 | 838 | /// 839 | public AllowedSigners AllowedSigners { 840 | get { 841 | return this.allowedSignersField; 842 | } 843 | set { 844 | this.allowedSignersField = value; 845 | } 846 | } 847 | 848 | /// 849 | public DeniedSigners DeniedSigners { 850 | get { 851 | return this.deniedSignersField; 852 | } 853 | set { 854 | this.deniedSignersField = value; 855 | } 856 | } 857 | 858 | /// 859 | public FileRulesRef FileRulesRef { 860 | get { 861 | return this.fileRulesRefField; 862 | } 863 | set { 864 | this.fileRulesRefField = value; 865 | } 866 | } 867 | } 868 | 869 | /// 870 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 871 | [System.SerializableAttribute()] 872 | [System.Diagnostics.DebuggerStepThroughAttribute()] 873 | [System.ComponentModel.DesignerCategoryAttribute("code")] 874 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 875 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 876 | public partial class TestSigningSigners { 877 | 878 | private AllowedSigners allowedSignersField; 879 | 880 | private DeniedSigners deniedSignersField; 881 | 882 | private FileRulesRef fileRulesRefField; 883 | 884 | /// 885 | public AllowedSigners AllowedSigners { 886 | get { 887 | return this.allowedSignersField; 888 | } 889 | set { 890 | this.allowedSignersField = value; 891 | } 892 | } 893 | 894 | /// 895 | public DeniedSigners DeniedSigners { 896 | get { 897 | return this.deniedSignersField; 898 | } 899 | set { 900 | this.deniedSignersField = value; 901 | } 902 | } 903 | 904 | /// 905 | public FileRulesRef FileRulesRef { 906 | get { 907 | return this.fileRulesRefField; 908 | } 909 | set { 910 | this.fileRulesRefField = value; 911 | } 912 | } 913 | } 914 | 915 | /// 916 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 917 | [System.SerializableAttribute()] 918 | [System.Diagnostics.DebuggerStepThroughAttribute()] 919 | [System.ComponentModel.DesignerCategoryAttribute("code")] 920 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 921 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 922 | public partial class FileAttribRef { 923 | 924 | private string ruleIDField; 925 | 926 | /// 927 | [System.Xml.Serialization.XmlAttributeAttribute()] 928 | public string RuleID { 929 | get { 930 | return this.ruleIDField; 931 | } 932 | set { 933 | this.ruleIDField = value; 934 | } 935 | } 936 | } 937 | 938 | /// 939 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 940 | [System.SerializableAttribute()] 941 | [System.Diagnostics.DebuggerStepThroughAttribute()] 942 | [System.ComponentModel.DesignerCategoryAttribute("code")] 943 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 944 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 945 | public partial class EKUs { 946 | 947 | private EKU[] itemsField; 948 | 949 | /// 950 | [System.Xml.Serialization.XmlElementAttribute("EKU")] 951 | public EKU[] Items { 952 | get { 953 | return this.itemsField; 954 | } 955 | set { 956 | this.itemsField = value; 957 | } 958 | } 959 | } 960 | 961 | /// 962 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 963 | [System.SerializableAttribute()] 964 | [System.Diagnostics.DebuggerStepThroughAttribute()] 965 | [System.ComponentModel.DesignerCategoryAttribute("code")] 966 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 967 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 968 | public partial class EKU { 969 | 970 | private string idField; 971 | 972 | private byte[] valueField; 973 | 974 | private string friendlyNameField; 975 | 976 | /// 977 | [System.Xml.Serialization.XmlAttributeAttribute()] 978 | public string ID { 979 | get { 980 | return this.idField; 981 | } 982 | set { 983 | this.idField = value; 984 | } 985 | } 986 | 987 | /// 988 | [System.Xml.Serialization.XmlAttributeAttribute(DataType="hexBinary")] 989 | public byte[] Value { 990 | get { 991 | return this.valueField; 992 | } 993 | set { 994 | this.valueField = value; 995 | } 996 | } 997 | 998 | /// 999 | [System.Xml.Serialization.XmlAttributeAttribute()] 1000 | public string FriendlyName { 1001 | get { 1002 | return this.friendlyNameField; 1003 | } 1004 | set { 1005 | this.friendlyNameField = value; 1006 | } 1007 | } 1008 | } 1009 | 1010 | /// 1011 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1012 | [System.SerializableAttribute()] 1013 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1014 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1015 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1016 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1017 | public partial class FileRules { 1018 | 1019 | private object[] itemsField; 1020 | 1021 | /// 1022 | [System.Xml.Serialization.XmlElementAttribute("Allow", typeof(Allow))] 1023 | [System.Xml.Serialization.XmlElementAttribute("Deny", typeof(Deny))] 1024 | [System.Xml.Serialization.XmlElementAttribute("FileAttrib", typeof(FileAttrib))] 1025 | public object[] Items { 1026 | get { 1027 | return this.itemsField; 1028 | } 1029 | set { 1030 | this.itemsField = value; 1031 | } 1032 | } 1033 | } 1034 | 1035 | /// 1036 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1037 | [System.SerializableAttribute()] 1038 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1039 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1040 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1041 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1042 | public partial class Allow { 1043 | 1044 | private string idField; 1045 | 1046 | private string friendlyNameField; 1047 | 1048 | private string fileNameField; 1049 | 1050 | private string internalNameField; 1051 | 1052 | private string fileDescriptionField; 1053 | 1054 | private string productNameField; 1055 | 1056 | private string packageFamilyNameField; 1057 | 1058 | private string packageVersionField; 1059 | 1060 | private string minimumFileVersionField; 1061 | 1062 | private string maximumFileVersionField; 1063 | 1064 | private byte[] hashField; 1065 | 1066 | private string appIDsField; 1067 | 1068 | private string filePathField; 1069 | 1070 | /// 1071 | [System.Xml.Serialization.XmlAttributeAttribute()] 1072 | public string ID { 1073 | get { 1074 | return this.idField; 1075 | } 1076 | set { 1077 | this.idField = value; 1078 | } 1079 | } 1080 | 1081 | /// 1082 | [System.Xml.Serialization.XmlAttributeAttribute()] 1083 | public string FriendlyName { 1084 | get { 1085 | return this.friendlyNameField; 1086 | } 1087 | set { 1088 | this.friendlyNameField = value; 1089 | } 1090 | } 1091 | 1092 | /// 1093 | [System.Xml.Serialization.XmlAttributeAttribute()] 1094 | public string FileName { 1095 | get { 1096 | return this.fileNameField; 1097 | } 1098 | set { 1099 | this.fileNameField = value; 1100 | } 1101 | } 1102 | 1103 | /// 1104 | [System.Xml.Serialization.XmlAttributeAttribute()] 1105 | public string InternalName { 1106 | get { 1107 | return this.internalNameField; 1108 | } 1109 | set { 1110 | this.internalNameField = value; 1111 | } 1112 | } 1113 | 1114 | /// 1115 | [System.Xml.Serialization.XmlAttributeAttribute()] 1116 | public string FileDescription { 1117 | get { 1118 | return this.fileDescriptionField; 1119 | } 1120 | set { 1121 | this.fileDescriptionField = value; 1122 | } 1123 | } 1124 | 1125 | /// 1126 | [System.Xml.Serialization.XmlAttributeAttribute()] 1127 | public string ProductName { 1128 | get { 1129 | return this.productNameField; 1130 | } 1131 | set { 1132 | this.productNameField = value; 1133 | } 1134 | } 1135 | 1136 | /// 1137 | [System.Xml.Serialization.XmlAttributeAttribute()] 1138 | public string PackageFamilyName { 1139 | get { 1140 | return this.packageFamilyNameField; 1141 | } 1142 | set { 1143 | this.packageFamilyNameField = value; 1144 | } 1145 | } 1146 | 1147 | /// 1148 | [System.Xml.Serialization.XmlAttributeAttribute()] 1149 | public string PackageVersion { 1150 | get { 1151 | return this.packageVersionField; 1152 | } 1153 | set { 1154 | this.packageVersionField = value; 1155 | } 1156 | } 1157 | 1158 | /// 1159 | [System.Xml.Serialization.XmlAttributeAttribute()] 1160 | public string MinimumFileVersion { 1161 | get { 1162 | return this.minimumFileVersionField; 1163 | } 1164 | set { 1165 | this.minimumFileVersionField = value; 1166 | } 1167 | } 1168 | 1169 | /// 1170 | [System.Xml.Serialization.XmlAttributeAttribute()] 1171 | public string MaximumFileVersion { 1172 | get { 1173 | return this.maximumFileVersionField; 1174 | } 1175 | set { 1176 | this.maximumFileVersionField = value; 1177 | } 1178 | } 1179 | 1180 | /// 1181 | [System.Xml.Serialization.XmlAttributeAttribute(DataType="hexBinary")] 1182 | public byte[] Hash { 1183 | get { 1184 | return this.hashField; 1185 | } 1186 | set { 1187 | this.hashField = value; 1188 | } 1189 | } 1190 | 1191 | /// 1192 | [System.Xml.Serialization.XmlAttributeAttribute()] 1193 | public string AppIDs { 1194 | get { 1195 | return this.appIDsField; 1196 | } 1197 | set { 1198 | this.appIDsField = value; 1199 | } 1200 | } 1201 | 1202 | /// 1203 | [System.Xml.Serialization.XmlAttributeAttribute()] 1204 | public string FilePath { 1205 | get { 1206 | return this.filePathField; 1207 | } 1208 | set { 1209 | this.filePathField = value; 1210 | } 1211 | } 1212 | } 1213 | 1214 | /// 1215 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1216 | [System.SerializableAttribute()] 1217 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1218 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1219 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1220 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1221 | public partial class Deny { 1222 | 1223 | private string idField; 1224 | 1225 | private string friendlyNameField; 1226 | 1227 | private string fileNameField; 1228 | 1229 | private string internalNameField; 1230 | 1231 | private string fileDescriptionField; 1232 | 1233 | private string productNameField; 1234 | 1235 | private string packageFamilyNameField; 1236 | 1237 | private string packageVersionField; 1238 | 1239 | private string minimumFileVersionField; 1240 | 1241 | private string maximumFileVersionField; 1242 | 1243 | private byte[] hashField; 1244 | 1245 | private string appIDsField; 1246 | 1247 | private string filePathField; 1248 | 1249 | /// 1250 | [System.Xml.Serialization.XmlAttributeAttribute()] 1251 | public string ID { 1252 | get { 1253 | return this.idField; 1254 | } 1255 | set { 1256 | this.idField = value; 1257 | } 1258 | } 1259 | 1260 | /// 1261 | [System.Xml.Serialization.XmlAttributeAttribute()] 1262 | public string FriendlyName { 1263 | get { 1264 | return this.friendlyNameField; 1265 | } 1266 | set { 1267 | this.friendlyNameField = value; 1268 | } 1269 | } 1270 | 1271 | /// 1272 | [System.Xml.Serialization.XmlAttributeAttribute()] 1273 | public string FileName { 1274 | get { 1275 | return this.fileNameField; 1276 | } 1277 | set { 1278 | this.fileNameField = value; 1279 | } 1280 | } 1281 | 1282 | /// 1283 | [System.Xml.Serialization.XmlAttributeAttribute()] 1284 | public string InternalName { 1285 | get { 1286 | return this.internalNameField; 1287 | } 1288 | set { 1289 | this.internalNameField = value; 1290 | } 1291 | } 1292 | 1293 | /// 1294 | [System.Xml.Serialization.XmlAttributeAttribute()] 1295 | public string FileDescription { 1296 | get { 1297 | return this.fileDescriptionField; 1298 | } 1299 | set { 1300 | this.fileDescriptionField = value; 1301 | } 1302 | } 1303 | 1304 | /// 1305 | [System.Xml.Serialization.XmlAttributeAttribute()] 1306 | public string ProductName { 1307 | get { 1308 | return this.productNameField; 1309 | } 1310 | set { 1311 | this.productNameField = value; 1312 | } 1313 | } 1314 | 1315 | /// 1316 | [System.Xml.Serialization.XmlAttributeAttribute()] 1317 | public string PackageFamilyName { 1318 | get { 1319 | return this.packageFamilyNameField; 1320 | } 1321 | set { 1322 | this.packageFamilyNameField = value; 1323 | } 1324 | } 1325 | 1326 | /// 1327 | [System.Xml.Serialization.XmlAttributeAttribute()] 1328 | public string PackageVersion { 1329 | get { 1330 | return this.packageVersionField; 1331 | } 1332 | set { 1333 | this.packageVersionField = value; 1334 | } 1335 | } 1336 | 1337 | /// 1338 | [System.Xml.Serialization.XmlAttributeAttribute()] 1339 | public string MinimumFileVersion { 1340 | get { 1341 | return this.minimumFileVersionField; 1342 | } 1343 | set { 1344 | this.minimumFileVersionField = value; 1345 | } 1346 | } 1347 | 1348 | /// 1349 | [System.Xml.Serialization.XmlAttributeAttribute()] 1350 | public string MaximumFileVersion { 1351 | get { 1352 | return this.maximumFileVersionField; 1353 | } 1354 | set { 1355 | this.maximumFileVersionField = value; 1356 | } 1357 | } 1358 | 1359 | /// 1360 | [System.Xml.Serialization.XmlAttributeAttribute(DataType="hexBinary")] 1361 | public byte[] Hash { 1362 | get { 1363 | return this.hashField; 1364 | } 1365 | set { 1366 | this.hashField = value; 1367 | } 1368 | } 1369 | 1370 | /// 1371 | [System.Xml.Serialization.XmlAttributeAttribute()] 1372 | public string AppIDs { 1373 | get { 1374 | return this.appIDsField; 1375 | } 1376 | set { 1377 | this.appIDsField = value; 1378 | } 1379 | } 1380 | 1381 | /// 1382 | [System.Xml.Serialization.XmlAttributeAttribute()] 1383 | public string FilePath { 1384 | get { 1385 | return this.filePathField; 1386 | } 1387 | set { 1388 | this.filePathField = value; 1389 | } 1390 | } 1391 | } 1392 | 1393 | /// 1394 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1395 | [System.SerializableAttribute()] 1396 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1397 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1398 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1399 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1400 | public partial class FileAttrib { 1401 | 1402 | private string idField; 1403 | 1404 | private string friendlyNameField; 1405 | 1406 | private string fileNameField; 1407 | 1408 | private string internalNameField; 1409 | 1410 | private string fileDescriptionField; 1411 | 1412 | private string productNameField; 1413 | 1414 | private string packageFamilyNameField; 1415 | 1416 | private string packageVersionField; 1417 | 1418 | private string minimumFileVersionField; 1419 | 1420 | private string maximumFileVersionField; 1421 | 1422 | private byte[] hashField; 1423 | 1424 | private string appIDsField; 1425 | 1426 | private string filePathField; 1427 | 1428 | /// 1429 | [System.Xml.Serialization.XmlAttributeAttribute()] 1430 | public string ID { 1431 | get { 1432 | return this.idField; 1433 | } 1434 | set { 1435 | this.idField = value; 1436 | } 1437 | } 1438 | 1439 | /// 1440 | [System.Xml.Serialization.XmlAttributeAttribute()] 1441 | public string FriendlyName { 1442 | get { 1443 | return this.friendlyNameField; 1444 | } 1445 | set { 1446 | this.friendlyNameField = value; 1447 | } 1448 | } 1449 | 1450 | /// 1451 | [System.Xml.Serialization.XmlAttributeAttribute()] 1452 | public string FileName { 1453 | get { 1454 | return this.fileNameField; 1455 | } 1456 | set { 1457 | this.fileNameField = value; 1458 | } 1459 | } 1460 | 1461 | /// 1462 | [System.Xml.Serialization.XmlAttributeAttribute()] 1463 | public string InternalName { 1464 | get { 1465 | return this.internalNameField; 1466 | } 1467 | set { 1468 | this.internalNameField = value; 1469 | } 1470 | } 1471 | 1472 | /// 1473 | [System.Xml.Serialization.XmlAttributeAttribute()] 1474 | public string FileDescription { 1475 | get { 1476 | return this.fileDescriptionField; 1477 | } 1478 | set { 1479 | this.fileDescriptionField = value; 1480 | } 1481 | } 1482 | 1483 | /// 1484 | [System.Xml.Serialization.XmlAttributeAttribute()] 1485 | public string ProductName { 1486 | get { 1487 | return this.productNameField; 1488 | } 1489 | set { 1490 | this.productNameField = value; 1491 | } 1492 | } 1493 | 1494 | /// 1495 | [System.Xml.Serialization.XmlAttributeAttribute()] 1496 | public string PackageFamilyName { 1497 | get { 1498 | return this.packageFamilyNameField; 1499 | } 1500 | set { 1501 | this.packageFamilyNameField = value; 1502 | } 1503 | } 1504 | 1505 | /// 1506 | [System.Xml.Serialization.XmlAttributeAttribute()] 1507 | public string PackageVersion { 1508 | get { 1509 | return this.packageVersionField; 1510 | } 1511 | set { 1512 | this.packageVersionField = value; 1513 | } 1514 | } 1515 | 1516 | /// 1517 | [System.Xml.Serialization.XmlAttributeAttribute()] 1518 | public string MinimumFileVersion { 1519 | get { 1520 | return this.minimumFileVersionField; 1521 | } 1522 | set { 1523 | this.minimumFileVersionField = value; 1524 | } 1525 | } 1526 | 1527 | /// 1528 | [System.Xml.Serialization.XmlAttributeAttribute()] 1529 | public string MaximumFileVersion { 1530 | get { 1531 | return this.maximumFileVersionField; 1532 | } 1533 | set { 1534 | this.maximumFileVersionField = value; 1535 | } 1536 | } 1537 | 1538 | /// 1539 | [System.Xml.Serialization.XmlAttributeAttribute(DataType="hexBinary")] 1540 | public byte[] Hash { 1541 | get { 1542 | return this.hashField; 1543 | } 1544 | set { 1545 | this.hashField = value; 1546 | } 1547 | } 1548 | 1549 | /// 1550 | [System.Xml.Serialization.XmlAttributeAttribute()] 1551 | public string AppIDs { 1552 | get { 1553 | return this.appIDsField; 1554 | } 1555 | set { 1556 | this.appIDsField = value; 1557 | } 1558 | } 1559 | 1560 | /// 1561 | [System.Xml.Serialization.XmlAttributeAttribute()] 1562 | public string FilePath { 1563 | get { 1564 | return this.filePathField; 1565 | } 1566 | set { 1567 | this.filePathField = value; 1568 | } 1569 | } 1570 | } 1571 | 1572 | /// 1573 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1574 | [System.SerializableAttribute()] 1575 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1576 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1577 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1578 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1579 | public partial class UpdatePolicySigner { 1580 | 1581 | private string signerIdField; 1582 | 1583 | /// 1584 | [System.Xml.Serialization.XmlAttributeAttribute()] 1585 | public string SignerId { 1586 | get { 1587 | return this.signerIdField; 1588 | } 1589 | set { 1590 | this.signerIdField = value; 1591 | } 1592 | } 1593 | } 1594 | 1595 | /// 1596 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1597 | [System.SerializableAttribute()] 1598 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1599 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1600 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1601 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1602 | public partial class UpdatePolicySigners { 1603 | 1604 | private UpdatePolicySigner[] itemsField; 1605 | 1606 | /// 1607 | [System.Xml.Serialization.XmlElementAttribute("UpdatePolicySigner")] 1608 | public UpdatePolicySigner[] Items { 1609 | get { 1610 | return this.itemsField; 1611 | } 1612 | set { 1613 | this.itemsField = value; 1614 | } 1615 | } 1616 | } 1617 | 1618 | /// 1619 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1620 | [System.SerializableAttribute()] 1621 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1622 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1623 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1624 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1625 | public partial class SupplementalPolicySigner { 1626 | 1627 | private string signerIdField; 1628 | 1629 | /// 1630 | [System.Xml.Serialization.XmlAttributeAttribute()] 1631 | public string SignerId { 1632 | get { 1633 | return this.signerIdField; 1634 | } 1635 | set { 1636 | this.signerIdField = value; 1637 | } 1638 | } 1639 | } 1640 | 1641 | /// 1642 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1643 | [System.SerializableAttribute()] 1644 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1645 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1646 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1647 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1648 | public partial class SupplementalPolicySigners { 1649 | 1650 | private SupplementalPolicySigner[] itemsField; 1651 | 1652 | /// 1653 | [System.Xml.Serialization.XmlElementAttribute("SupplementalPolicySigner")] 1654 | public SupplementalPolicySigner[] Items { 1655 | get { 1656 | return this.itemsField; 1657 | } 1658 | set { 1659 | this.itemsField = value; 1660 | } 1661 | } 1662 | } 1663 | 1664 | /// 1665 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1666 | [System.SerializableAttribute()] 1667 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1668 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1669 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1670 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1671 | public partial class CiSigner { 1672 | 1673 | private string signerIdField; 1674 | 1675 | /// 1676 | [System.Xml.Serialization.XmlAttributeAttribute()] 1677 | public string SignerId { 1678 | get { 1679 | return this.signerIdField; 1680 | } 1681 | set { 1682 | this.signerIdField = value; 1683 | } 1684 | } 1685 | } 1686 | 1687 | /// 1688 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1689 | [System.SerializableAttribute()] 1690 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1691 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1692 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1693 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1694 | public partial class CiSigners { 1695 | 1696 | private CiSigner[] itemsField; 1697 | 1698 | /// 1699 | [System.Xml.Serialization.XmlElementAttribute("CiSigner")] 1700 | public CiSigner[] Items { 1701 | get { 1702 | return this.itemsField; 1703 | } 1704 | set { 1705 | this.itemsField = value; 1706 | } 1707 | } 1708 | } 1709 | 1710 | /// 1711 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1712 | [System.SerializableAttribute()] 1713 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1714 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1715 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1716 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1717 | public partial class Signers { 1718 | 1719 | private Signer[] itemsField; 1720 | 1721 | /// 1722 | [System.Xml.Serialization.XmlElementAttribute("Signer")] 1723 | public Signer[] Items { 1724 | get { 1725 | return this.itemsField; 1726 | } 1727 | set { 1728 | this.itemsField = value; 1729 | } 1730 | } 1731 | } 1732 | 1733 | /// 1734 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1735 | [System.SerializableAttribute()] 1736 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1737 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1738 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1739 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1740 | public partial class Signer { 1741 | 1742 | private CertRoot certRootField; 1743 | 1744 | private CertEKU[] certEKUField; 1745 | 1746 | private CertIssuer certIssuerField; 1747 | 1748 | private CertPublisher certPublisherField; 1749 | 1750 | private CertOemID certOemIDField; 1751 | 1752 | private FileAttribRef[] fileAttribRefField; 1753 | 1754 | private string nameField; 1755 | 1756 | private string idField; 1757 | 1758 | private System.DateTime signTimeAfterField; 1759 | 1760 | private bool signTimeAfterFieldSpecified; 1761 | 1762 | /// 1763 | public CertRoot CertRoot { 1764 | get { 1765 | return this.certRootField; 1766 | } 1767 | set { 1768 | this.certRootField = value; 1769 | } 1770 | } 1771 | 1772 | /// 1773 | [System.Xml.Serialization.XmlElementAttribute("CertEKU")] 1774 | public CertEKU[] CertEKU { 1775 | get { 1776 | return this.certEKUField; 1777 | } 1778 | set { 1779 | this.certEKUField = value; 1780 | } 1781 | } 1782 | 1783 | /// 1784 | public CertIssuer CertIssuer { 1785 | get { 1786 | return this.certIssuerField; 1787 | } 1788 | set { 1789 | this.certIssuerField = value; 1790 | } 1791 | } 1792 | 1793 | /// 1794 | public CertPublisher CertPublisher { 1795 | get { 1796 | return this.certPublisherField; 1797 | } 1798 | set { 1799 | this.certPublisherField = value; 1800 | } 1801 | } 1802 | 1803 | /// 1804 | public CertOemID CertOemID { 1805 | get { 1806 | return this.certOemIDField; 1807 | } 1808 | set { 1809 | this.certOemIDField = value; 1810 | } 1811 | } 1812 | 1813 | /// 1814 | [System.Xml.Serialization.XmlElementAttribute("FileAttribRef")] 1815 | public FileAttribRef[] FileAttribRef { 1816 | get { 1817 | return this.fileAttribRefField; 1818 | } 1819 | set { 1820 | this.fileAttribRefField = value; 1821 | } 1822 | } 1823 | 1824 | /// 1825 | [System.Xml.Serialization.XmlAttributeAttribute()] 1826 | public string Name { 1827 | get { 1828 | return this.nameField; 1829 | } 1830 | set { 1831 | this.nameField = value; 1832 | } 1833 | } 1834 | 1835 | /// 1836 | [System.Xml.Serialization.XmlAttributeAttribute()] 1837 | public string ID { 1838 | get { 1839 | return this.idField; 1840 | } 1841 | set { 1842 | this.idField = value; 1843 | } 1844 | } 1845 | 1846 | /// 1847 | [System.Xml.Serialization.XmlAttributeAttribute()] 1848 | public System.DateTime SignTimeAfter { 1849 | get { 1850 | return this.signTimeAfterField; 1851 | } 1852 | set { 1853 | this.signTimeAfterField = value; 1854 | } 1855 | } 1856 | 1857 | /// 1858 | [System.Xml.Serialization.XmlIgnoreAttribute()] 1859 | public bool SignTimeAfterSpecified { 1860 | get { 1861 | return this.signTimeAfterFieldSpecified; 1862 | } 1863 | set { 1864 | this.signTimeAfterFieldSpecified = value; 1865 | } 1866 | } 1867 | } 1868 | 1869 | /// 1870 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1871 | [System.SerializableAttribute()] 1872 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1873 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1874 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1875 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1876 | public partial class SigningScenarios { 1877 | 1878 | private SigningScenario[] itemsField; 1879 | 1880 | /// 1881 | [System.Xml.Serialization.XmlElementAttribute("SigningScenario")] 1882 | public SigningScenario[] Items { 1883 | get { 1884 | return this.itemsField; 1885 | } 1886 | set { 1887 | this.itemsField = value; 1888 | } 1889 | } 1890 | } 1891 | 1892 | /// 1893 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 1894 | [System.SerializableAttribute()] 1895 | [System.Diagnostics.DebuggerStepThroughAttribute()] 1896 | [System.ComponentModel.DesignerCategoryAttribute("code")] 1897 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 1898 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 1899 | public partial class SigningScenario { 1900 | 1901 | private ProductSigners productSignersField; 1902 | 1903 | private TestSigners testSignersField; 1904 | 1905 | private TestSigningSigners testSigningSignersField; 1906 | 1907 | private string idField; 1908 | 1909 | private string friendlyNameField; 1910 | 1911 | private byte valueField; 1912 | 1913 | private string inheritedScenariosField; 1914 | 1915 | private ushort minimumHashAlgorithmField; 1916 | 1917 | private bool minimumHashAlgorithmFieldSpecified; 1918 | 1919 | /// 1920 | public ProductSigners ProductSigners { 1921 | get { 1922 | return this.productSignersField; 1923 | } 1924 | set { 1925 | this.productSignersField = value; 1926 | } 1927 | } 1928 | 1929 | /// 1930 | public TestSigners TestSigners { 1931 | get { 1932 | return this.testSignersField; 1933 | } 1934 | set { 1935 | this.testSignersField = value; 1936 | } 1937 | } 1938 | 1939 | /// 1940 | public TestSigningSigners TestSigningSigners { 1941 | get { 1942 | return this.testSigningSignersField; 1943 | } 1944 | set { 1945 | this.testSigningSignersField = value; 1946 | } 1947 | } 1948 | 1949 | /// 1950 | [System.Xml.Serialization.XmlAttributeAttribute()] 1951 | public string ID { 1952 | get { 1953 | return this.idField; 1954 | } 1955 | set { 1956 | this.idField = value; 1957 | } 1958 | } 1959 | 1960 | /// 1961 | [System.Xml.Serialization.XmlAttributeAttribute()] 1962 | public string FriendlyName { 1963 | get { 1964 | return this.friendlyNameField; 1965 | } 1966 | set { 1967 | this.friendlyNameField = value; 1968 | } 1969 | } 1970 | 1971 | /// 1972 | [System.Xml.Serialization.XmlAttributeAttribute()] 1973 | public byte Value { 1974 | get { 1975 | return this.valueField; 1976 | } 1977 | set { 1978 | this.valueField = value; 1979 | } 1980 | } 1981 | 1982 | /// 1983 | [System.Xml.Serialization.XmlAttributeAttribute()] 1984 | public string InheritedScenarios { 1985 | get { 1986 | return this.inheritedScenariosField; 1987 | } 1988 | set { 1989 | this.inheritedScenariosField = value; 1990 | } 1991 | } 1992 | 1993 | /// 1994 | [System.Xml.Serialization.XmlAttributeAttribute()] 1995 | public ushort MinimumHashAlgorithm { 1996 | get { 1997 | return this.minimumHashAlgorithmField; 1998 | } 1999 | set { 2000 | this.minimumHashAlgorithmField = value; 2001 | } 2002 | } 2003 | 2004 | /// 2005 | [System.Xml.Serialization.XmlIgnoreAttribute()] 2006 | public bool MinimumHashAlgorithmSpecified { 2007 | get { 2008 | return this.minimumHashAlgorithmFieldSpecified; 2009 | } 2010 | set { 2011 | this.minimumHashAlgorithmFieldSpecified = value; 2012 | } 2013 | } 2014 | } 2015 | 2016 | /// 2017 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 2018 | [System.SerializableAttribute()] 2019 | [System.Diagnostics.DebuggerStepThroughAttribute()] 2020 | [System.ComponentModel.DesignerCategoryAttribute("code")] 2021 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-microsoft-com:sipolicy")] 2022 | [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-microsoft-com:sipolicy", IsNullable=false)] 2023 | public partial class SiPolicy { 2024 | 2025 | private string versionExField; 2026 | 2027 | private string policyTypeIDField; 2028 | 2029 | private string platformIDField; 2030 | 2031 | private string policyIDField; 2032 | 2033 | private string basePolicyIDField; 2034 | 2035 | private RuleType[] rulesField; 2036 | 2037 | private EKU[] eKUsField; 2038 | 2039 | private object[] fileRulesField; 2040 | 2041 | private Signer[] signersField; 2042 | 2043 | private SigningScenario[] signingScenariosField; 2044 | 2045 | private UpdatePolicySigner[] updatePolicySignersField; 2046 | 2047 | private CiSigner[] ciSignersField; 2048 | 2049 | private uint hvciOptionsField; 2050 | 2051 | private bool hvciOptionsFieldSpecified; 2052 | 2053 | private Setting[] settingsField; 2054 | 2055 | private MacrosMacro[] macrosField; 2056 | 2057 | private SupplementalPolicySigner[] supplementalPolicySignersField; 2058 | 2059 | private string friendlyNameField; 2060 | 2061 | private PolicyType policyTypeField; 2062 | 2063 | private bool policyTypeFieldSpecified; 2064 | 2065 | /// 2066 | public string VersionEx { 2067 | get { 2068 | return this.versionExField; 2069 | } 2070 | set { 2071 | this.versionExField = value; 2072 | } 2073 | } 2074 | 2075 | /// 2076 | public string PolicyTypeID { 2077 | get { 2078 | return this.policyTypeIDField; 2079 | } 2080 | set { 2081 | this.policyTypeIDField = value; 2082 | } 2083 | } 2084 | 2085 | /// 2086 | public string PlatformID { 2087 | get { 2088 | return this.platformIDField; 2089 | } 2090 | set { 2091 | this.platformIDField = value; 2092 | } 2093 | } 2094 | 2095 | /// 2096 | public string PolicyID { 2097 | get { 2098 | return this.policyIDField; 2099 | } 2100 | set { 2101 | this.policyIDField = value; 2102 | } 2103 | } 2104 | 2105 | /// 2106 | public string BasePolicyID { 2107 | get { 2108 | return this.basePolicyIDField; 2109 | } 2110 | set { 2111 | this.basePolicyIDField = value; 2112 | } 2113 | } 2114 | 2115 | /// 2116 | [System.Xml.Serialization.XmlArrayItemAttribute("Rule", IsNullable=false)] 2117 | public RuleType[] Rules { 2118 | get { 2119 | return this.rulesField; 2120 | } 2121 | set { 2122 | this.rulesField = value; 2123 | } 2124 | } 2125 | 2126 | /// 2127 | [System.Xml.Serialization.XmlArrayItemAttribute("EKU", IsNullable=false)] 2128 | public EKU[] EKUs { 2129 | get { 2130 | return this.eKUsField; 2131 | } 2132 | set { 2133 | this.eKUsField = value; 2134 | } 2135 | } 2136 | 2137 | /// 2138 | [System.Xml.Serialization.XmlArrayItemAttribute("Allow", typeof(Allow), IsNullable=false)] 2139 | [System.Xml.Serialization.XmlArrayItemAttribute("Deny", typeof(Deny), IsNullable=false)] 2140 | [System.Xml.Serialization.XmlArrayItemAttribute("FileAttrib", typeof(FileAttrib), IsNullable=false)] 2141 | public object[] FileRules { 2142 | get { 2143 | return this.fileRulesField; 2144 | } 2145 | set { 2146 | this.fileRulesField = value; 2147 | } 2148 | } 2149 | 2150 | /// 2151 | [System.Xml.Serialization.XmlArrayItemAttribute("Signer", IsNullable=false)] 2152 | public Signer[] Signers { 2153 | get { 2154 | return this.signersField; 2155 | } 2156 | set { 2157 | this.signersField = value; 2158 | } 2159 | } 2160 | 2161 | /// 2162 | [System.Xml.Serialization.XmlArrayItemAttribute("SigningScenario", IsNullable=false)] 2163 | public SigningScenario[] SigningScenarios { 2164 | get { 2165 | return this.signingScenariosField; 2166 | } 2167 | set { 2168 | this.signingScenariosField = value; 2169 | } 2170 | } 2171 | 2172 | /// 2173 | [System.Xml.Serialization.XmlArrayItemAttribute("UpdatePolicySigner", IsNullable=false)] 2174 | public UpdatePolicySigner[] UpdatePolicySigners { 2175 | get { 2176 | return this.updatePolicySignersField; 2177 | } 2178 | set { 2179 | this.updatePolicySignersField = value; 2180 | } 2181 | } 2182 | 2183 | /// 2184 | [System.Xml.Serialization.XmlArrayItemAttribute("CiSigner", IsNullable=false)] 2185 | public CiSigner[] CiSigners { 2186 | get { 2187 | return this.ciSignersField; 2188 | } 2189 | set { 2190 | this.ciSignersField = value; 2191 | } 2192 | } 2193 | 2194 | /// 2195 | public uint HvciOptions { 2196 | get { 2197 | return this.hvciOptionsField; 2198 | } 2199 | set { 2200 | this.hvciOptionsField = value; 2201 | } 2202 | } 2203 | 2204 | /// 2205 | [System.Xml.Serialization.XmlIgnoreAttribute()] 2206 | public bool HvciOptionsSpecified { 2207 | get { 2208 | return this.hvciOptionsFieldSpecified; 2209 | } 2210 | set { 2211 | this.hvciOptionsFieldSpecified = value; 2212 | } 2213 | } 2214 | 2215 | /// 2216 | [System.Xml.Serialization.XmlArrayItemAttribute("Setting", IsNullable=false)] 2217 | public Setting[] Settings { 2218 | get { 2219 | return this.settingsField; 2220 | } 2221 | set { 2222 | this.settingsField = value; 2223 | } 2224 | } 2225 | 2226 | /// 2227 | [System.Xml.Serialization.XmlArrayItemAttribute("Macro", IsNullable=false)] 2228 | public MacrosMacro[] Macros { 2229 | get { 2230 | return this.macrosField; 2231 | } 2232 | set { 2233 | this.macrosField = value; 2234 | } 2235 | } 2236 | 2237 | /// 2238 | [System.Xml.Serialization.XmlArrayItemAttribute("SupplementalPolicySigner", IsNullable=false)] 2239 | public SupplementalPolicySigner[] SupplementalPolicySigners { 2240 | get { 2241 | return this.supplementalPolicySignersField; 2242 | } 2243 | set { 2244 | this.supplementalPolicySignersField = value; 2245 | } 2246 | } 2247 | 2248 | /// 2249 | [System.Xml.Serialization.XmlAttributeAttribute()] 2250 | public string FriendlyName { 2251 | get { 2252 | return this.friendlyNameField; 2253 | } 2254 | set { 2255 | this.friendlyNameField = value; 2256 | } 2257 | } 2258 | 2259 | /// 2260 | [System.Xml.Serialization.XmlAttributeAttribute()] 2261 | public PolicyType PolicyType { 2262 | get { 2263 | return this.policyTypeField; 2264 | } 2265 | set { 2266 | this.policyTypeField = value; 2267 | } 2268 | } 2269 | 2270 | /// 2271 | [System.Xml.Serialization.XmlIgnoreAttribute()] 2272 | public bool PolicyTypeSpecified { 2273 | get { 2274 | return this.policyTypeFieldSpecified; 2275 | } 2276 | set { 2277 | this.policyTypeFieldSpecified = value; 2278 | } 2279 | } 2280 | } 2281 | 2282 | /// 2283 | [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3698.0")] 2284 | [System.SerializableAttribute()] 2285 | [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-microsoft-com:sipolicy")] 2286 | public enum PolicyType { 2287 | 2288 | /// 2289 | [System.Xml.Serialization.XmlEnumAttribute("Base Policy")] 2290 | BasePolicy, 2291 | 2292 | /// 2293 | [System.Xml.Serialization.XmlEnumAttribute("Supplemental Policy")] 2294 | SupplementalPolicy, 2295 | } 2296 | } 2297 | '@ 2298 | 2299 | if (-not ('CodeIntegrity.SIPolicy' -as [Type])) { 2300 | Add-Type -TypeDefinition $TypeDef -ReferencedAssemblies 'System.Xml' 2301 | } 2302 | 2303 | function ConvertTo-Oid { 2304 | <# 2305 | .SYNOPSIS 2306 | 2307 | Decodes a DER encoded ASN.1 object identifier (OID) 2308 | 2309 | .DESCRIPTION 2310 | 2311 | ConvertTo-Oid decodes a DER encoded ASN.1 object identifier (OID). This can be used as a helper function for binary certificate parsers. 2312 | 2313 | .PARAMETER EncodedOIDBytes 2314 | 2315 | Specifies the bytes of an absolute (starts with 6), encoded OID. 2316 | 2317 | .EXAMPLE 2318 | 2319 | ConvertTo-Oid -EncodedOIDBytes @(0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0A, 0x03, 0x05) 2320 | 2321 | .OUTPUTS 2322 | 2323 | System.Security.Cryptography.Oid 2324 | 2325 | ConvertTo-Oid outputs an OID object representing the decoded OID. 2326 | #> 2327 | 2328 | [OutputType([System.Security.Cryptography.Oid])] 2329 | param ( 2330 | [Parameter(Mandatory = $True, Position = 0)] 2331 | [Byte[]] 2332 | [ValidateNotNullOrEmpty()] 2333 | $EncodedOIDBytes 2334 | ) 2335 | 2336 | # This only handles absolute encoded OIDs - those that start with 6. 2337 | # [Security.Cryptography.CryptoConfig]::EncodeOID only handles absolute OIDs. 2338 | 2339 | # This article describes the OID encoding/decoding process: 2340 | # https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809(v=vs.85).aspx 2341 | 2342 | if (($EncodedOIDBytes.Length -lt 2) -or ($EncodedOIDBytes[1] -ne ($EncodedOIDBytes.Length - 2))) { 2343 | throw 'Invalid encoded EKU OID value.' 2344 | } 2345 | 2346 | $OIDComponents = New-Object -TypeName 'System.Collections.Generic.List[Int]' 2347 | 2348 | $SecondComponent = $EncodedOIDBytes[2] % 40 2349 | $FirstComponent = ($EncodedOIDBytes[2] - $SecondComponent) / 40 2350 | 2351 | $OIDComponents.Add($FirstComponent) 2352 | $OIDComponents.Add($SecondComponent) 2353 | 2354 | $i = 3 2355 | 2356 | while ($i -lt $EncodedOIDBytes.Length) { 2357 | if (-not ($EncodedOIDBytes[$i] -band 0x80)) { 2358 | # It is just singlebyte encoded 2359 | $OIDComponents.Add($EncodedOIDBytes[$i]) 2360 | $i++ 2361 | } else { 2362 | # It is either two or three byte encoded 2363 | $Byte1 = ($EncodedOIDBytes[$i] -shl 1) -shr 1 # Strip the high bit 2364 | $Byte2 = $EncodedOIDBytes[$i+1] 2365 | 2366 | if ($Byte2 -band 0x80) { 2367 | # three byte encoded 2368 | $Byte3 = $EncodedOIDBytes[$i+2] 2369 | $i += 3 2370 | 2371 | $Byte2 = $Byte2 -band 0x7F 2372 | if ($Byte2 -band 1) { $Byte3 = $Byte3 -bor 0x80 } 2373 | if ($Byte1 -band 1) { $Byte2 = $Byte2 -bor 0x80 } 2374 | $Byte2 = $Byte2 -shr 1 2375 | $Byte1 = $Byte1 -shr 1 2376 | if ($Byte2 -band 1) { $Byte2 = $Byte2 -bor 0x80 } 2377 | $Byte1 = $Byte1 -shr 1 2378 | 2379 | $OIDComponents.Add([BitConverter]::ToInt32(@($Byte3, $Byte2, $Byte1, 0), 0)) 2380 | } else { 2381 | # two byte encoded 2382 | $i +=2 2383 | 2384 | # "Shift" the low bit from the high byte to the high bit of the low byte 2385 | if ($Byte1 -band 1) { $Byte2 -bor 0x80 } 2386 | $Byte1 = $Byte1 -shr 1 2387 | 2388 | $OIDComponents.Add([BitConverter]::ToInt16(@($Byte2, $Byte1), 0)) 2389 | } 2390 | } 2391 | } 2392 | 2393 | [Security.Cryptography.Oid] ($OIDComponents -join '.') 2394 | } 2395 | 2396 | # Helper function to read strings from the binary 2397 | function Get-BinaryString { 2398 | [OutputType('String')] 2399 | param ( 2400 | [Parameter(Mandatory)] 2401 | [IO.BinaryReader] 2402 | [ValidateNotNullOrEmpty()] 2403 | $BinaryReader 2404 | ) 2405 | 2406 | $StringLength = $BinaryReader.ReadUInt32() 2407 | 2408 | if ($StringLength) { 2409 | $PaddingBytes = 4 - $StringLength % 4 -band 3 2410 | 2411 | $StringBytes = $BinaryReader.ReadBytes($StringLength) 2412 | $null = $BinaryReader.ReadBytes($PaddingBytes) 2413 | 2414 | [Text.Encoding]::Unicode.GetString($StringBytes) 2415 | } 2416 | 2417 | $null = $BinaryReader.ReadInt32() 2418 | } 2419 | 2420 | # Obtain the full path to the policy file if a relative path was provided. 2421 | $BinPath = Resolve-Path $BinaryFilePath 2422 | 2423 | $XmlPathDir = Split-Path -Path $XmlFilePath -Parent 2424 | $XmlPathFile = Split-Path -Path $XmlFilePath -Leaf 2425 | 2426 | if (-not $XmlPathDir) { 2427 | $XmlPathDir = $PWD 2428 | } 2429 | 2430 | $ResolvedDir = Resolve-Path -Path $XmlPathDir 2431 | 2432 | if (-not [System.IO.Directory]::Exists($ResolvedDir.Path)) { 2433 | throw "Cannot find path '$ResolvedDir' because it does not exist." 2434 | return 2435 | } 2436 | 2437 | $FullXmlPath = Join-Path -Path $ResolvedDir -ChildPath $XmlPathFile 2438 | 2439 | try { 2440 | $CIPolicyBytes = [IO.File]::ReadAllBytes($BinPath.Path) 2441 | 2442 | try { 2443 | try { 2444 | $ContentType = [Security.Cryptography.Pkcs.ContentInfo]::GetContentType($CIPolicyBytes) 2445 | } catch { 2446 | $ContentType = $null 2447 | } 2448 | 2449 | # Check for PKCS#7 ASN.1 SignedData type 2450 | if ($ContentType -and $ContentType.Value -eq '1.2.840.113549.1.7.2') { 2451 | $Cms = New-Object System.Security.Cryptography.Pkcs.SignedCms 2452 | $Cms.Decode($CIPolicyBytes) 2453 | $CIPolicyBytes = $Cms.ContentInfo.Content 2454 | if ($CIPolicyBytes[0] -eq 4) { 2455 | # Policy is stored as an OCTET STRING 2456 | $PolicySize = $CIPolicyBytes[1] 2457 | $BaseIndex = 2 2458 | if (($PolicySize -band 0x80) -eq 0x80) { 2459 | $SizeCount = $PolicySize -band 0x7F 2460 | $BaseIndex += $SizeCount 2461 | $PolicySize = 0 2462 | for ($i = 0; $i -lt $SizeCount; $i++) { 2463 | $PolicySize = $PolicySize -shl 8 2464 | $PolicySize = $PolicySize -bor $CIPolicyBytes[2 + $i] 2465 | } 2466 | } 2467 | 2468 | $CIPolicyBytes = $CIPolicyBytes[$BaseIndex..($BaseIndex + $PolicySize - 1)] 2469 | } 2470 | } 2471 | } catch { 2472 | Write-Output $_ 2473 | } 2474 | 2475 | $MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$CIPolicyBytes) 2476 | $BinaryReader = New-Object -TypeName System.IO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode) 2477 | } catch { 2478 | throw $_ 2479 | return 2480 | } 2481 | 2482 | $SIPolicy = New-Object -TypeName CodeIntegrity.SIPolicy 2483 | 2484 | try { 2485 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): CI Policy Format Version" 2486 | 2487 | # Validate binary CI policy header 2488 | # This header value indicates likely indicates the schema version that was used. 2489 | # This script will only support whatever the latest schema version was at the time of last update, in this case, 7. 2490 | $CIPolicyFormatVersion = $BinaryReader.ReadInt32() 2491 | 2492 | # My inference is that the binary format will terminate with a UInt32 value that is $CIPolicyFormatVersion + 1. 2493 | # For example, if $CIPolicyFormatVersion is 7, the binary policy is expected to be terminated with 0x00000008. 2494 | # This way, should the following warning be presented, should a format version of 8 be introduced, I will know that 2495 | # there will be binary data in need of parsing beyond 0x00000008. 2496 | 2497 | if ($CIPolicyFormatVersion -gt 7) { 2498 | Write-Warning "$BinPath has an invalid or unsupported binary CI policy format version value: 0x$($CIPolicyFormatVersion.ToString('X8')). If you are sure that you are dealing with a binary code integrity policy, there is a high liklihood that Microsoft updated the binary file for mat to support new schema elements and that this code will likely need to be updated." 2499 | } 2500 | 2501 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): PolicyTypeID" 2502 | 2503 | $PolicyTypeID = [Guid][Byte[]] $BinaryReader.ReadBytes($GuidLength) 2504 | 2505 | # The policy type ID can be used to determine the intended purpose of the CI policy 2506 | switch ($PolicyTypeID.Guid) { 2507 | 'a244370e-44c9-4c06-b551-f6016e563076' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - Enterprise Code Integrity Policy (SiPolicy.p7b or UpdateSiPolicy.p7b)" } 2508 | '2a5a0136-f09f-498e-99cc-51099011157c' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - Windows Revoke Code Integrity Policy (RvkSiPolicy.p7b or UpdateRvkSiPolicy.p7b)" } 2509 | '976d12c8-cb9f-4730-be52-54600843238e' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - SKU Code Integrity Policy (SkuSiPolicy.p7b or UpdateSkuSiPolicy.p7b)" } 2510 | '5951a96a-e0b5-4d3d-8fb8-3e5b61030784' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - Windows Lockdown (S-Mode) Code Integrity Policy (WinSiPolicy.p7b or UpdateWinSiPolicy.p7b)" } 2511 | '4e61c68c-97f6-430b-9cd7-9b1004706770' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - Advanced Threat Protection Code Integrity Policy (ATPSiPolicy.p7b or UpdateATPSiPolicy.p7b)" } 2512 | 'd2bda982-ccf6-4344-ac5b-0b44427b6816' { Write-Verbose "PolicyTypeID: {$PolicyTypeID} - Driver Code Integrity Policy (DriverSiPolicy.p7b or UpdateDriverSiPolicy.p7b)" } 2513 | } 2514 | 2515 | $SetPolicyTypeID = $True 2516 | 2517 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): PlatformID" 2518 | 2519 | [Byte[]] $PlatformIDBytes = $BinaryReader.ReadBytes($GuidLength) 2520 | $PlatformID = [Guid] $PlatformIDBytes 2521 | 2522 | $SIPolicy.PlatformID = "{$($PlatformID.ToString().ToUpper())}" 2523 | 2524 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Option Flags" 2525 | 2526 | $OptionFlags = $BinaryReader.ReadInt32() 2527 | 2528 | # Validate that the high bit is set - i.e. mask it off with 0x80000000 2529 | if ($OptionFlags -band ([Int32]::MinValue) -ne [Int32]::MinValue) { 2530 | throw "Invalid policy options flag. $CorruptPolicyErr" 2531 | return 2532 | } 2533 | 2534 | if (($OptionFlags -band 0x40000000) -eq 0x40000000) { 2535 | Write-Verbose 'Policy option flags indicate that the code integrity policy was built from supplmental policies.' 2536 | } 2537 | 2538 | # Obtain the policy rules but first remove the upper two high bits - 2539 | # i.e. anding it with 0x3FFFFFFF first 2540 | $PolicyRules = [CodeIntegrity.PolicyRules] ($OptionFlags -band 0x3FFFFFFF) 2541 | 2542 | $PolicyRulesArray = $PolicyRules -split ', ' 2543 | 2544 | $Rules = New-Object -TypeName CodeIntegrity.RuleType[]($PolicyRulesArray.Length) 2545 | 2546 | for ($i = 0; $i -lt $Rules.Length; $i++) { 2547 | $RuleType = New-Object -TypeName CodeIntegrity.RuleType -Property @{ Item = $PolicyRulesArray[$i] } 2548 | $Rules[$i] = $RuleType 2549 | } 2550 | 2551 | $SIPolicy.Rules = $Rules 2552 | 2553 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): EKU Rule Count" 2554 | $EKURuleEntryCount = $BinaryReader.ReadInt32() 2555 | 2556 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): File Rule Count" 2557 | $FileRuleEntryCount = $BinaryReader.ReadInt32() 2558 | 2559 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Signer Rule Count" 2560 | $SignerRuleEntryCount = $BinaryReader.ReadInt32() 2561 | 2562 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Signer Scenario Rule Count" 2563 | $SignerScenarioEntryCount = $BinaryReader.ReadInt32() 2564 | 2565 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): VersionEx" 2566 | $Revis = $BinaryReader.ReadUInt16() 2567 | $Build = $BinaryReader.ReadUInt16() 2568 | $Minor = $BinaryReader.ReadUInt16() 2569 | $Major = $BinaryReader.ReadUInt16() 2570 | 2571 | $PolicyVersion = New-Object -TypeName Version -ArgumentList $Major, $Minor, $Build, $Revis 2572 | 2573 | $SIPolicy.VersionEx = $PolicyVersion 2574 | 2575 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Header Length" 2576 | # Validate that the fixed header length was written to the end of the header 2577 | $HeaderLength = $BinaryReader.ReadInt32() 2578 | 2579 | if ($HeaderLength -ne ($HeaderLengthMax - 4)) { 2580 | Write-Warning "$BinPath has an invalid header footer: 0x$($HeaderLength.ToString('X8')). $CorruptPolicyErr" 2581 | } 2582 | 2583 | if ($EKURuleEntryCount) { 2584 | $EKUArray = New-Object -TypeName CodeIntegrity.EKU[]($EKURuleEntryCount) 2585 | 2586 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): EKU Rules" 2587 | 2588 | for ($i = 0; $i -lt $EKURuleEntryCount; $i++) { 2589 | # Length of the encoded EKU OID value 2590 | $EkuValueLen = $BinaryReader.ReadUInt32() 2591 | 2592 | # Length of the encoded EKU OID value padded out to 4 bytes 2593 | $PaddingBytes = 4 - $EkuValueLen % 4 -band 3 2594 | 2595 | $EKUValueBytes = $BinaryReader.ReadBytes($EkuValueLen) 2596 | $null = $BinaryReader.ReadBytes($PaddingBytes) 2597 | 2598 | $EKUValueBytesCopy = $EKUValueBytes 2599 | #$EKUValueBytesCopy[0] = 6 2600 | 2601 | $OID = ConvertTo-Oid -EncodedOIDBytes $EKUValueBytesCopy 2602 | 2603 | $Properties = @{ 2604 | Value = $EKUValueBytes 2605 | ID = "ID_EKU_E_$(($i + 1).ToString('X4'))" 2606 | } 2607 | 2608 | # Reconstruct the original FriendlyName that would have been lost 2609 | # in the process of converting to binary form. 2610 | if ($OID) { 2611 | if ($OID.FriendlyName) { 2612 | $Properties['FriendlyName'] = $OID.FriendlyName 2613 | } elseif ($OID.Value) { 2614 | $Properties['FriendlyName'] = $OID.Value 2615 | } 2616 | } 2617 | 2618 | $EKUArray[$i] = New-Object -TypeName CodeIntegrity.EKU -Property $Properties 2619 | } 2620 | 2621 | $SIPolicy.EKUs = $EKUArray 2622 | } 2623 | 2624 | if ($FileRuleEntryCount) { 2625 | # The XMl serializer won't validate unless 2626 | # I use a generic collection vs. a System.Object[]. 2627 | $Script:FileRulesArray = New-Object -TypeName 'System.Collections.Generic.List[Object]' 2628 | 2629 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): File Rules" 2630 | 2631 | for ($i = 0; $i -lt $FileRuleEntryCount; $i++) { 2632 | $FileRuleTypeValue = $BinaryReader.ReadInt32() 2633 | 2634 | switch ($FileRuleTypeValue) { 2635 | 0 { 2636 | $TypeName = 'CodeIntegrity.Deny' 2637 | $ID = "ID_DENY_D_$(($i + 1).ToString('X4'))" 2638 | } 2639 | 2640 | 1 { 2641 | $TypeName = 'CodeIntegrity.Allow' 2642 | $ID = "ID_ALLOW_A_$(($i + 1).ToString('X4'))" 2643 | } 2644 | 2645 | 2 { 2646 | $TypeName = 'CodeIntegrity.FileAttrib' 2647 | $ID = "ID_FILEATTRIB_F_$(($i + 1).ToString('X4'))" 2648 | } 2649 | 2650 | default { throw "Invalid file rule type: 0x$($FileRuleTypeValue.ToString('X8'))" } 2651 | } 2652 | 2653 | $FileRule = New-Object -TypeName $TypeName -Property @{ ID = $ID } 2654 | 2655 | $FileName = Get-BinaryString -BinaryReader $BinaryReader 2656 | 2657 | if ($FileName) { 2658 | $FileRule.FileName = $FileName 2659 | } 2660 | 2661 | $Revis = $BinaryReader.ReadUInt16() 2662 | $Build = $BinaryReader.ReadUInt16() 2663 | $Minor = $BinaryReader.ReadUInt16() 2664 | $Major = $BinaryReader.ReadUInt16() 2665 | 2666 | $MinimumVersion = New-Object -TypeName Version -ArgumentList $Major, $Minor, $Build, $Revis 2667 | 2668 | # If it's a deny rule and MaximumFileVersion is null, the version will be set to 65535.65535.65535.65535 2669 | # Otherwise, if MinimumFileVersion is non-zero, then a MinimumFileVersion was specified. 2670 | if (!(($FileRuleTypeValue -eq 0) -and ($MinimumVersion -eq '65535.65535.65535.65535')) -and ($MinimumVersion -ne '0.0.0.0')) { 2671 | $FileRule.MinimumFileVersion = $MinimumVersion 2672 | } 2673 | 2674 | $HashLen = $BinaryReader.ReadUInt32() 2675 | 2676 | if ($HashLen) { 2677 | $PaddingBytes = 4 - $HashLen % 4 -band 3 2678 | 2679 | $HashBytes = $BinaryReader.ReadBytes($HashLen) 2680 | $null = $BinaryReader.ReadBytes($PaddingBytes) 2681 | 2682 | $FileRule.Hash = $HashBytes 2683 | } 2684 | 2685 | $Script:FileRulesArray.Add($FileRule) 2686 | } 2687 | 2688 | $SIPolicy.FileRules = $Script:FileRulesArray 2689 | } 2690 | 2691 | if ($SignerRuleEntryCount) { 2692 | $Script:SignersArray = New-Object -TypeName CodeIntegrity.Signer[]($SignerRuleEntryCount) 2693 | 2694 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Signer Rules" 2695 | 2696 | for ($i = 0; $i -lt $SignerRuleEntryCount; $i++) { 2697 | $CertRootTypeValue = $BinaryReader.ReadInt32() 2698 | 2699 | $Signer = New-Object -TypeName CodeIntegrity.Signer -Property @{ 2700 | ID = "ID_SIGNER_S_$(($i + 1).ToString('X4'))" 2701 | Name = "Signer $($i + 1)" 2702 | } 2703 | 2704 | switch ($CertRootTypeValue) { 2705 | 0 { $CertRootType = [CodeIntegrity.CertEnumType] 'TBS' } # TBS - To Be Signed 2706 | 1 { $CertRootType = [CodeIntegrity.CertEnumType] 'WellKnown' } 2707 | default { throw "Invalid certificate root type: 0x$($CertRooTypeValue.ToString('X8'))" } 2708 | } 2709 | 2710 | if ($CertRootType -eq 'TBS') { 2711 | $CertRootLength = $BinaryReader.ReadUInt32() 2712 | 2713 | if ($CertRootLength) { 2714 | $PaddingBytes = 4 - $CertRootLength % 4 -band 3 2715 | 2716 | # This is a hash of the ToBeSigned data blob. 2717 | # The hashing algorithm used is dictated by the algorithm specified in the certificate. 2718 | [Byte[]] $CertRootBytes = $BinaryReader.ReadBytes($CertRootLength) 2719 | 2720 | $null = $BinaryReader.ReadBytes($PaddingBytes) 2721 | } 2722 | } else { 2723 | # WellKnown type 2724 | 2725 | # I'd like to know what these map to. I assume there's a mapped list of common 2726 | # Microsoft root certificates. 2727 | # It doesn't appear as though the ConfigCI cmdlets can generate a well known root type. 2728 | [Byte[]] $CertRootBytes = @(($BinaryReader.ReadUInt32() -band 0xFF)) 2729 | } 2730 | 2731 | $CertRootObject = New-Object -TypeName CodeIntegrity.CertRoot -Property @{ Type = $CertRootType; Value = $CertRootBytes } 2732 | 2733 | $Signer.CertRoot = $CertRootObject 2734 | 2735 | $CertEKULength = $BinaryReader.ReadUInt32() 2736 | 2737 | if ($CertEKULength) { 2738 | $CertEKUArray = New-Object -TypeName CodeIntegrity.CertEKU[]($CertEKULength) 2739 | 2740 | for ($j = 0; $j -lt $CertEKULength; $j++) { 2741 | $EKUIndex = $BinaryReader.ReadUInt32() 2742 | $CertEKUArray[$j] = New-Object -TypeName CodeIntegrity.CertEKU -Property @{ ID = $SIPolicy.EKUs[$EKUIndex].ID } 2743 | } 2744 | 2745 | $Signer.CertEKU = $CertEKUArray 2746 | } 2747 | 2748 | $CertIssuer = Get-BinaryString -BinaryReader $BinaryReader 2749 | 2750 | if ($CertIssuer) { 2751 | $Signer.CertIssuer = New-Object -TypeName CodeIntegrity.CertIssuer -Property @{ Value = $CertIssuer } 2752 | } 2753 | 2754 | $CertPublisher = Get-BinaryString -BinaryReader $BinaryReader 2755 | 2756 | if ($CertPublisher) { 2757 | $Signer.CertPublisher = New-Object -TypeName CodeIntegrity.CertPublisher -Property @{ Value = $CertPublisher } 2758 | } 2759 | 2760 | $CertOemID = Get-BinaryString -BinaryReader $BinaryReader 2761 | 2762 | if ($CertOemID) { 2763 | $Signer.CertOemID = New-Object -TypeName CodeIntegrity.CertOemID -Property @{ Value = $CertOemID } 2764 | } 2765 | 2766 | $FileAttribRefLength = $BinaryReader.ReadUInt32() 2767 | 2768 | if ($FileAttribRefLength) { 2769 | $FileAttribRefArray = New-Object -TypeName CodeIntegrity.FileAttribRef[]($FileAttribRefLength) 2770 | 2771 | for ($j = 0; $j -lt $FileAttribRefLength; $j++) { 2772 | $FileAttribRefIndex = $BinaryReader.ReadUInt32() 2773 | $FileAttribRefArray[$j] = New-Object -TypeName CodeIntegrity.FileAttribRef -Property @{ RuleID = $SIPolicy.FileRules[$FileAttribRefIndex].ID } 2774 | } 2775 | 2776 | $Signer.FileAttribRef = $FileAttribRefArray 2777 | } 2778 | 2779 | $Script:SignersArray[$i] = $Signer 2780 | } 2781 | 2782 | $SIPolicy.Signers = $Script:SignersArray 2783 | } 2784 | 2785 | $UpdatePolicySignersLength = $BinaryReader.ReadUInt32() 2786 | 2787 | if ($UpdatePolicySignersLength) { 2788 | $UpdatePolicySigners = New-Object -TypeName CodeIntegrity.UpdatePolicySigner[]($UpdatePolicySignersLength) 2789 | 2790 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Update Policy Signers" 2791 | 2792 | for ($i = 0; $i -lt $UpdatePolicySignersLength; $i++) { 2793 | $UpdatePolicySignersIndex = $BinaryReader.ReadUInt32() 2794 | $UpdatePolicySigners[$i] = New-Object -TypeName CodeIntegrity.UpdatePolicySigner -Property @{ SignerId = $SIPolicy.Signers[$UpdatePolicySignersIndex].ID } 2795 | } 2796 | 2797 | $SIPolicy.UpdatePolicySigners = $UpdatePolicySigners 2798 | } 2799 | 2800 | $CISignersLength = $BinaryReader.ReadUInt32() 2801 | 2802 | if ($CISignersLength) { 2803 | $CISigners = New-Object -TypeName CodeIntegrity.CiSigner[]($CISignersLength) 2804 | 2805 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): CI Signers" 2806 | 2807 | for ($i = 0; $i -lt $CISignersLength; $i++) { 2808 | $CISignersIndex = $BinaryReader.ReadUInt32() 2809 | $CISigners[$i] = New-Object -TypeName CodeIntegrity.CiSigner -Property @{ SignerId = $SIPolicy.Signers[$CISignersIndex].ID } 2810 | } 2811 | 2812 | $SIPolicy.CiSigners = $CISigners 2813 | } 2814 | 2815 | if ($SignerScenarioEntryCount) { 2816 | $SignerScenarioArray = New-Object -TypeName CodeIntegrity.SigningScenario[]($SignerScenarioEntryCount) 2817 | 2818 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Signer Scenarios" 2819 | 2820 | for ($i = 0; $i -lt $SignerScenarioEntryCount; $i++) { 2821 | [Byte] $SigningScenarioValue = $BinaryReader.ReadUInt32() -band 0xFF 2822 | 2823 | $DriverSigningScenarioCount = 1 2824 | $WindowsSigningScenarioCount = 0 2825 | 2826 | switch ($SigningScenarioValue) { 2827 | 131 { 2828 | $ID = "ID_SIGNINGSCENARIO_DRIVERS_$($DriverSigningScenarioCount.ToString('X'))" 2829 | $DriverSigningScenarioCount++ 2830 | } 2831 | 2832 | 12 { 2833 | $ID = 'ID_SIGNINGSCENARIO_WINDOWS' 2834 | 2835 | # It is unlikely that there would ever be more than one windows 2836 | # (i.e. user mode) signing scenario but handle it just in case. 2837 | if ($WindowsSigningScenarioCount) { 2838 | $ID += "_$(($WindowsSigningScenarioCount + 1).ToString('X'))" 2839 | } 2840 | 2841 | $WindowsSigningScenarioCount++ 2842 | } 2843 | 2844 | default { 2845 | # It is unlikely that there would ever be a value other than 2846 | # 131 or 12 but account for it anyway. 2847 | $ID = "ID_SIGNINGSCENARIO_S_$(($i + 1).ToString('X4'))" 2848 | } 2849 | } 2850 | 2851 | $SigningScenario = New-Object -TypeName CodeIntegrity.SigningScenario -Property @{ ID = $ID; Value = $SigningScenarioValue } 2852 | 2853 | # The ability to inherit from another signing scenario is not formally documented 2854 | # other than in the SIPolicy schema. 2855 | $InheritedScenarios = $null 2856 | 2857 | $InheritedScenarioLength = $BinaryReader.ReadUInt32() 2858 | 2859 | if ($InheritedScenarioLength) { 2860 | $InheritedScenarios = New-Object UInt32[]($InheritedScenarioLength) 2861 | 2862 | for ($j = 0; $j -lt $InheritedScenarioLength; $j++) { 2863 | $InheritedScenarios[$j] = $BinaryReader.ReadUInt32() 2864 | } 2865 | 2866 | # To-do: Make sure I resolve the indices later on! 2867 | $InheritedScenariosString = $InheritedScenarios -join ',' 2868 | $SigningScenario.InheritedScenarios = $InheritedScenariosString 2869 | } 2870 | 2871 | [UInt16] $MinimumHashValueValue = $BinaryReader.ReadUInt32() -band [UInt16]::MaxValue 2872 | 2873 | # 0x800C refers to the absense of a minimum hash algorithm. 2874 | if ($MinimumHashValueValue -ne 0x800C) { 2875 | $MinimumHashValue = $MinimumHashValueValue 2876 | 2877 | $SigningScenario.MinimumHashAlgorithmSpecified = $True 2878 | $SigningScenario.MinimumHashAlgorithm = $MinimumHashValue 2879 | } else { 2880 | $SigningScenario.MinimumHashAlgorithmSpecified = $False 2881 | } 2882 | 2883 | # Loop over product signers, test signers, and test signing signers 2884 | 1..3 | ForEach-Object { 2885 | $AllowedSignersCount = $BinaryReader.ReadUInt32() 2886 | $AllowSignersObject = $null 2887 | 2888 | if ($AllowedSignersCount) { 2889 | $AllowSignersObject = New-Object -TypeName CodeIntegrity.AllowedSigners 2890 | $AllowSignerArray = New-Object -TypeName CodeIntegrity.AllowedSigner[]($AllowedSignersCount) 2891 | 2892 | for ($j = 0; $j -lt $AllowedSignersCount; $j++) { 2893 | $AllowedSignerIndex = $BinaryReader.ReadUInt32() 2894 | 2895 | $ExceptDenyRuleLength = $BinaryReader.ReadUInt32() 2896 | 2897 | $ExceptDenyRulesArray = $null 2898 | 2899 | if ($ExceptDenyRuleLength) { 2900 | $ExceptDenyRulesArray = New-Object -TypeName CodeIntegrity.ExceptDenyRule[]($ExceptDenyRuleLength) 2901 | 2902 | for ($k = 0; $k -lt $ExceptDenyRuleLength; $k++) { 2903 | $ExceptDenyRuleIndex = $BinaryReader.ReadUInt32() 2904 | $ExceptDenyRulesArray[$k] = New-Object -TypeName CodeIntegrity.ExceptDenyRule -Property @{ DenyRuleID = $SIPolicy.FileRules[$ExceptDenyRuleIndex].ID } 2905 | } 2906 | } 2907 | 2908 | $AllowSignerArray[$j] = New-Object -TypeName CodeIntegrity.AllowedSigner -Property @{ SignerId = $SIPolicy.Signers[$AllowedSignerIndex].ID } 2909 | $AllowSignerArray[$j].ExceptDenyRule = $ExceptDenyRulesArray 2910 | } 2911 | 2912 | $AllowSignersObject.AllowedSigner = $AllowSignerArray 2913 | } 2914 | 2915 | $DeniedSignersCount = $BinaryReader.ReadUInt32() 2916 | $DeniedSignersObject = $null 2917 | 2918 | if ($DeniedSignersCount) { 2919 | $DeniedSignersObject = New-Object -TypeName CodeIntegrity.DeniedSigners 2920 | $DeniedSignerArray = New-Object -TypeName CodeIntegrity.DeniedSigner[]($DeniedSignersCount) 2921 | 2922 | for ($j = 0; $j -lt $DeniedSignersCount; $j++) { 2923 | $DeniedSignerIndex = $BinaryReader.ReadUInt32() 2924 | 2925 | $ExceptAllowRuleLength = $BinaryReader.ReadUInt32() 2926 | 2927 | $ExceptAllowRulesArray = $null 2928 | 2929 | if ($ExceptAllowRuleLength) { 2930 | $ExceptAllowRulesArray = New-Object -TypeName CodeIntegrity.ExceptAllowRule[]($ExceptAllowRuleLength) 2931 | 2932 | for ($k = 0; $k -lt $ExceptAllowRuleLength; $k++) { 2933 | $ExceptAllowRuleIndex = $BinaryReader.ReadUInt32() 2934 | $ExceptAllowRulesArray[$k] = New-Object -TypeName CodeIntegrity.ExceptAllowRule -Property @{ AllowRuleID = $SIPolicy.FileRules[$ExceptAllowRuleIndex].ID } 2935 | } 2936 | } 2937 | 2938 | $DeniedSignerArray[$j] = New-Object -TypeName CodeIntegrity.DeniedSigner -Property @{ SignerId = $SIPolicy.Signers[$DeniedSignerIndex].ID } 2939 | $DeniedSignerArray[$j].ExceptAllowRule = $ExceptAllowRulesArray 2940 | } 2941 | 2942 | $DeniedSignersObject.DeniedSigner = $DeniedSignerArray 2943 | } 2944 | 2945 | $FileRulesRefCount = $BinaryReader.ReadUInt32() 2946 | $FileRulesRefObject = $null 2947 | 2948 | if ($FileRulesRefCount) { 2949 | $FileRulesRefObject = New-Object -TypeName CodeIntegrity.FileRulesRef 2950 | $FileRuleRefArray = New-Object -TypeName CodeIntegrity.FileRuleRef[]($FileRulesRefCount) 2951 | 2952 | for ($j = 0; $j -lt $FileRulesRefCount; $j++) { 2953 | $FileRulesRefIndex = $BinaryReader.ReadUInt32() 2954 | 2955 | $FileRuleRefArray[$j] = New-Object -TypeName CodeIntegrity.FileRuleRef -Property @{ RuleID = $SIPolicy.FileRules[$FileRulesRefIndex].ID } 2956 | } 2957 | 2958 | $FileRulesRefObject.FileRuleRef = $FileRuleRefArray 2959 | } 2960 | 2961 | $NullSigner = $False 2962 | 2963 | # Don't populate the relevant object if it wasn't present in the binary. 2964 | # Even setting a property to null in an object that can be serialized 2965 | # with XML can result in the creation of empty XML element/attributes. 2966 | if (($AllowedSignersCount -eq 0) -and ($DeniedSignersCount -eq 0) -and ($FileRulesRefCount -eq 0)) { 2967 | $NullSigner = $True 2968 | } 2969 | 2970 | switch ($_) { 2971 | 1 { # Product signers 2972 | if (-not $NullSigner) { 2973 | $ProductSigner = New-Object -TypeName CodeIntegrity.ProductSigners 2974 | 2975 | if ($AllowSignersObject) { $ProductSigner.AllowedSigners = $AllowSignersObject } 2976 | if ($DeniedSignersObject) { $ProductSigner.DeniedSigners = $DeniedSignersObject } 2977 | if ($FileRulesRefObject) { $ProductSigner.FileRulesRef = $FileRulesRefObject } 2978 | 2979 | $SigningScenario.ProductSigners = $ProductSigner 2980 | } else { 2981 | $SigningScenario.ProductSigners = New-Object -TypeName CodeIntegrity.ProductSigners 2982 | } 2983 | } 2984 | 2985 | 2 { # Test signers 2986 | if (-not $NullSigner) { 2987 | $TestSigner = New-Object -TypeName CodeIntegrity.TestSigners 2988 | 2989 | if ($AllowSignersObject) { $TestSigner.AllowedSigners = $AllowSignersObject } 2990 | if ($DeniedSignersObject) { $TestSigner.DeniedSigners = $DeniedSignersObject } 2991 | if ($FileRulesRefObject) { $TestSigner.FileRulesRef = $FileRulesRefObject } 2992 | 2993 | $SigningScenario.TestSigners = $TestSigner 2994 | } else { 2995 | $SigningScenario.TestSigners = New-Object -TypeName CodeIntegrity.TestSigners 2996 | } 2997 | } 2998 | 2999 | 3 { # Test signing signers 3000 | if (-not $NullSigner) { 3001 | $TestSigningSigner = New-Object -TypeName CodeIntegrity.TestSigningSigners 3002 | 3003 | if ($AllowSignersObject) { $TestSigningSigner.AllowedSigners = $AllowSignersObject } 3004 | if ($DeniedSignersObject) { $TestSigningSigner.DeniedSigners = $DeniedSignersObject } 3005 | if ($FileRulesRefObject) { $TestSigningSigner.FileRulesRef = $FileRulesRefObject } 3006 | 3007 | $SigningScenario.TestSigningSigners = $TestSigningSigner 3008 | } else { 3009 | $SigningScenario.TestSigningSigners = New-Object -TypeName CodeIntegrity.TestSigningSigners 3010 | } 3011 | } 3012 | } 3013 | } 3014 | 3015 | $SignerScenarioArray[$i] = $SigningScenario 3016 | } 3017 | 3018 | # Resolve inherited scenario IDs now that they've all been parsed. 3019 | for ($i = 0; $i -lt $SignerScenarioEntryCount; $i++) { 3020 | if ($SignerScenarioArray[$i].InheritedScenarios) { 3021 | [Int[]] $ScenarioIndices = $SignerScenarioArray[$i].InheritedScenarios -split ',' 3022 | 3023 | $SignerScenarioArray[$i].InheritedScenarios = ($ScenarioIndices | ForEach-Object { $SignerScenarioArray[$_].ID }) -join ',' 3024 | } 3025 | } 3026 | 3027 | $SIPolicy.SigningScenarios = $SignerScenarioArray 3028 | } 3029 | 3030 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): HVCI Options" 3031 | # Maybe I could parse this out 3032 | $HVCIOptions = $BinaryReader.ReadUInt32() 3033 | 3034 | if ($HVCIOptions) { 3035 | $SIPolicy.HvciOptions = $HVCIOptions 3036 | $SIPolicy.HvciOptionsSpecified = $True 3037 | } else { 3038 | $SIPolicy.HvciOptionsSpecified = $False 3039 | } 3040 | 3041 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Secure Settings" 3042 | $SecureSettingsLength = $BinaryReader.ReadUInt32() 3043 | 3044 | if ($SecureSettingsLength) { 3045 | 3046 | $SecureSettings = New-Object CodeIntegrity.Setting[]($SecureSettingsLength) 3047 | 3048 | for ($i = 0; $i -lt $SecureSettingsLength; $i++) { 3049 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Secure Settings [$i]" 3050 | 3051 | $Provider = Get-BinaryString -BinaryReader $BinaryReader 3052 | $Key = Get-BinaryString -BinaryReader $BinaryReader 3053 | $ValueName = Get-BinaryString -BinaryReader $BinaryReader 3054 | 3055 | $ValueType = $BinaryReader.ReadUInt32() 3056 | 3057 | switch ($ValueType) { 3058 | 0 { # Boolean type 3059 | [Bool] $Value = $BinaryReader.ReadUInt32() 3060 | } 3061 | 3062 | 1 { # Unsigned int type 3063 | [UInt32] $Value = $BinaryReader.ReadUInt32() 3064 | } 3065 | 3066 | 2 { # Byte array type 3067 | # Length of the byte array 3068 | $ByteArrayLen = $BinaryReader.ReadUInt32() 3069 | 3070 | # Length of the byte array padded out to 4 bytes 3071 | $PaddingBytes = 4 - $ByteArrayLen % 4 -band 3 3072 | 3073 | $ValueBytes = $BinaryReader.ReadBytes($ByteArrayLen) 3074 | $null = $BinaryReader.ReadBytes($PaddingBytes) 3075 | 3076 | [Byte[]] $Value = $ValueBytes 3077 | } 3078 | 3079 | 3 { # String type 3080 | [String] $Value = Get-BinaryString -BinaryReader $BinaryReader 3081 | } 3082 | } 3083 | 3084 | $SecureSetting = New-Object CodeIntegrity.Setting 3085 | $SettingValueType = New-Object CodeIntegrity.SettingValueType 3086 | $SettingValueType.Item = $Value 3087 | 3088 | $SecureSetting.Provider = $Provider 3089 | $SecureSetting.Key = $Key 3090 | $SecureSetting.ValueName = $ValueName 3091 | $SecureSetting.Value = $SettingValueType 3092 | 3093 | $SecureSettings[$i] = $SecureSetting 3094 | } 3095 | 3096 | $SIPolicy.Settings = $SecureSettings 3097 | } 3098 | 3099 | $V3RuleSupport = $BinaryReader.ReadUInt32() 3100 | 3101 | if ($V3RuleSupport -eq 3 -and $CIPolicyFormatVersion -ge 3) { 3102 | 3103 | Write-Verbose 'Processing binary format v3 rules: file rule maximum versions and macro rules' 3104 | 3105 | if ($FileRuleEntryCount) { 3106 | 3107 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): File Rules Macros" 3108 | 3109 | for ($i = 0; $i -lt $FileRuleEntryCount; $i++) { 3110 | $Revis = $BinaryReader.ReadUInt16() 3111 | $Build = $BinaryReader.ReadUInt16() 3112 | $Minor = $BinaryReader.ReadUInt16() 3113 | $Major = $BinaryReader.ReadUInt16() 3114 | 3115 | $MaximumVersion = New-Object -TypeName Version -ArgumentList $Major, $Minor, $Build, $Revis 3116 | 3117 | if ($MaximumVersion -ne ([Version] '0.0.0.0')) { 3118 | $Script:FileRulesArray[$i].MaximumFileVersion = $MaximumVersion 3119 | } 3120 | 3121 | $MacroStringCount = $BinaryReader.ReadUInt32() 3122 | 3123 | # Note: macro names are not stored in a binary policy (only values) so no effort will be made to infer macro names. 3124 | if ($MacroStringCount) { 3125 | if ($MacroStringCount -eq 1) { 3126 | $MacroString = Get-BinaryString -BinaryReader $BinaryReader 3127 | 3128 | $Script:FileRulesArray[$i].AppIDs = $MacroString 3129 | } else { 3130 | $MacroStrings = (1..$MacroStringCount | ForEach-Object { Get-BinaryString -BinaryReader $BinaryReader }) -join '' 3131 | 3132 | $Script:FileRulesArray[$i].AppIDs = $MacroStrings 3133 | } 3134 | } 3135 | } 3136 | } 3137 | 3138 | if ($SignerRuleEntryCount) { 3139 | 3140 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Signer Rules Macro" 3141 | 3142 | for ($i = 0; $i -lt $SignerRuleEntryCount; $i++) { 3143 | $SignTimeAfterValue = $BinaryReader.ReadInt64() 3144 | 3145 | if ($SignTimeAfterValue -ne 0) { 3146 | $Script:SignersArray[$i].SignTimeAfter = [DateTime]::FromFileTime($SignTimeAfterValue) 3147 | } 3148 | } 3149 | } 3150 | 3151 | $V4RuleSupport = $BinaryReader.ReadUInt32() 3152 | 3153 | if ($V4RuleSupport -eq 4 -and $CIPolicyFormatVersion -ge 4) { 3154 | Write-Verbose 'Processing binary format v4 rules: file metadata - InternalName, FileDescription, ProductName' 3155 | 3156 | if ($FileRuleEntryCount) { 3157 | 3158 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): File Rules File Metadata" 3159 | 3160 | for ($i = 0; $i -lt $FileRuleEntryCount; $i++) { 3161 | $InternalName = Get-BinaryString -BinaryReader $BinaryReader 3162 | $FileDescription = Get-BinaryString -BinaryReader $BinaryReader 3163 | $ProductName = Get-BinaryString -BinaryReader $BinaryReader 3164 | 3165 | if ($InternalName) { $Script:FileRulesArray[$i].InternalName = $InternalName } 3166 | if ($FileDescription) { $Script:FileRulesArray[$i].FileDescription = $FileDescription } 3167 | if ($ProductName) { $Script:FileRulesArray[$i].ProductName = $ProductName } 3168 | } 3169 | } 3170 | 3171 | $V5RuleSupport = $BinaryReader.ReadUInt32() 3172 | 3173 | if ($V5RuleSupport -eq 5 -and $CIPolicyFormatVersion -ge 5) { 3174 | Write-Verbose 'Processing binary format v5 rules: PackageFamilyName and PackageVersion' 3175 | 3176 | if ($FileRuleEntryCount) { 3177 | 3178 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): File Rules Package Metadata" 3179 | 3180 | for ($i = 0; $i -lt $FileRuleEntryCount; $i++) { 3181 | $PackageFamilyName = Get-BinaryString -BinaryReader $BinaryReader 3182 | 3183 | $Revis = $BinaryReader.ReadUInt16() 3184 | $Build = $BinaryReader.ReadUInt16() 3185 | $Minor = $BinaryReader.ReadUInt16() 3186 | $Major = $BinaryReader.ReadUInt16() 3187 | 3188 | $PackageVersion = New-Object -TypeName Version -ArgumentList $Major, $Minor, $Build, $Revis 3189 | 3190 | if ($PackageFamilyName) { $Script:FileRulesArray[$i].PackageFamilyName = $PackageFamilyName } 3191 | 3192 | if ($PackageVersion -ne ([Version] '0.0.0.0')) { 3193 | $Script:FileRulesArray[$i].PackageVersion = $PackageVersion 3194 | } 3195 | } 3196 | } 3197 | 3198 | $V6RuleSupport = $BinaryReader.ReadUInt32() 3199 | 3200 | if ($V6RuleSupport -eq 6 -and $CIPolicyFormatVersion -ge 6) { 3201 | 3202 | Write-Verbose 'Processing binary format v6 rules: Supplemental policy information - BasePolicyID, PolicyID, and supplemental signers' 3203 | 3204 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): BasePolicyID and PolicyID GUID" 3205 | 3206 | # The CI policy has the new BasePolicyID and PolicyID elements versus the older PolicyTypeID element. 3207 | 3208 | $PolicyID = [Guid][Byte[]] $BinaryReader.ReadBytes($GuidLength) 3209 | 3210 | $SIPolicy.PolicyID = "{$($PolicyID.ToString().ToUpper())}" 3211 | 3212 | $BasePolicyID = [Guid][Byte[]] $BinaryReader.ReadBytes($GuidLength) 3213 | 3214 | $SIPolicy.BasePolicyID = "{$($BasePolicyID.ToString().ToUpper())}" 3215 | 3216 | $SIPolicy.PolicyTypeSpecified = $True 3217 | 3218 | if ($SIPolicy.PolicyID -eq $SIPolicy.BasePolicyID) { 3219 | $SIPolicy.PolicyType = 'BasePolicy' 3220 | } else { 3221 | $SIPolicy.PolicyType = 'SupplementalPolicy' 3222 | } 3223 | 3224 | $SetPolicyTypeID = $False 3225 | 3226 | $SupplementalSignerRuleEntryCount = $BinaryReader.ReadUInt32() 3227 | 3228 | if ($SupplementalSignerRuleEntryCount) { 3229 | $SupplementalSigners = New-Object -TypeName CodeIntegrity.SupplementalPolicySigner[]($SupplementalSignerRuleEntryCount) 3230 | 3231 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): Supplemental Signers" 3232 | 3233 | for ($i = 0; $i -lt $SupplementalSignerRuleEntryCount; $i++) { 3234 | $SupplemetalSignersIndex = $BinaryReader.ReadUInt32() 3235 | $SupplementalSigners[$i] = New-Object -TypeName CodeIntegrity.SupplementalPolicySigner -Property @{ SignerId = $SIPolicy.Signers[$SupplemetalSignersIndex].ID } 3236 | } 3237 | 3238 | $SIPolicy.SupplementalPolicySigners = $SupplementalSigners 3239 | } 3240 | 3241 | $V7RuleSupport = $BinaryReader.ReadUInt32() 3242 | 3243 | if ($V7RuleSupport -eq 7 -and $CIPolicyFormatVersion -ge 7) { 3244 | Write-Verbose 'Processing binary format v7 rules: FilePath rules' 3245 | 3246 | if ($FileRuleEntryCount) { 3247 | 3248 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): FilePath Rules" 3249 | 3250 | for ($i = 0; $i -lt $FileRuleEntryCount; $i++) { 3251 | $FilePath = Get-BinaryString -BinaryReader $BinaryReader 3252 | 3253 | if ($FilePath) { $Script:FileRulesArray[$i].FilePath = $FilePath } 3254 | } 3255 | } 3256 | 3257 | $V8RuleSupport = $BinaryReader.ReadUInt32() 3258 | 3259 | # To-do: What follows will need to be updated when a new CI policy schema is released. 3260 | if ($V8RuleSupport -ne 8) { 3261 | Write-Warning 'A parsing error may have occurred. The CI policy should end with 0x00000008.' 3262 | } 3263 | } 3264 | } 3265 | } 3266 | } 3267 | 3268 | if ($FileRuleEntryCount) { $SIPolicy.FileRules = $Script:FileRulesArray } 3269 | if ($SignerRuleEntryCount) { $SIPolicy.Signers = $Script:SignersArray } 3270 | } 3271 | 3272 | Write-Verbose "Position 0x$($BinaryReader.BaseStream.Position.ToString('X8')): End of Policy" 3273 | 3274 | } catch { 3275 | $BinaryReader.Close() 3276 | $MemoryStream.Close() 3277 | 3278 | throw $_ 3279 | return 3280 | } 3281 | 3282 | if ($SetPolicyTypeID) { $SIPolicy.PolicyTypeID = "{$($PolicyTypeID.ToString().ToUpper())}" } 3283 | 3284 | $BinaryReader.Close() 3285 | $MemoryStream.Close() 3286 | 3287 | $XmlOutputSuccess = $False 3288 | 3289 | try { 3290 | $XmlTextWriter = New-Object -TypeName Xml.XmlTextWriter -ArgumentList $FullXmlPath, $null 3291 | $XmlTextWriter.Formatting = 'Indented' 3292 | 3293 | $XmlSerializer = New-Object -TypeName Xml.Serialization.XmlSerializer -ArgumentList ([CodeIntegrity.SIPolicy]) 3294 | 3295 | $XmlSerializer.Serialize($XmlTextWriter, $SIPolicy) 3296 | $XmlTextWriter.Close() 3297 | $XmlOutputSuccess = $True 3298 | } catch { 3299 | throw $_ 3300 | return 3301 | } 3302 | 3303 | if ($XmlOutputSuccess) { 3304 | Get-Item -Path $FullXmlPath 3305 | } 3306 | } 3307 | 3308 | function Get-WDACCodeIntegrityBinaryPolicyCertificate { 3309 | <# 3310 | .SYNOPSIS 3311 | 3312 | Extracts the signer information from a signed, binary code integrity policy. 3313 | 3314 | Author: Matthew Graeber (@mattifestation) 3315 | Contributors: James Forshaw (@tiraniddo) - thanks for the major bug fixes! 3316 | License: BSD 3-Clause 3317 | 3318 | .DESCRIPTION 3319 | 3320 | 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.113549.1.7.2). 3321 | 3322 | .PARAMETER BinaryFilePath 3323 | 3324 | Specifies the path of a signed, binary code interity policy. Deployed binary policy files are located in %SystemRoot%\System32\CodeIntegrity\SIPolicy.p7b. 3325 | 3326 | .EXAMPLE 3327 | 3328 | Get-WDACCodeIntegrityBinaryPolicyCertificate -BinaryFilePath C:\Windows\System32\CodeIntegrity\SIPolicy.p7b 3329 | 3330 | .OUTPUTS 3331 | 3332 | System.Security.Cryptography.X509Certificates.X509Certificate2 3333 | 3334 | If the binary code integrity is signed, Get-WDACCodeIntegrityBinaryPolicyCertificate will output a list of X509Certificate2 objects. 3335 | #> 3336 | 3337 | [CmdletBinding()] 3338 | [OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])] 3339 | param ( 3340 | [Parameter(Position = 0, Mandatory)] 3341 | [String] 3342 | [ValidateScript({ [IO.File]::Exists((Resolve-Path $_).Path) })] 3343 | $BinaryFilePath 3344 | ) 3345 | 3346 | # Obtain the full path to the policy file if a relative path was provided. 3347 | $BinPath = Resolve-Path $BinaryFilePath 3348 | try { 3349 | $Cms = New-Object System.Security.Cryptography.Pkcs.SignedCms 3350 | $Cms.Decode([IO.File]::ReadAllBytes($BinPath)) 3351 | $Cms.Certificates 3352 | } catch { 3353 | throw "$BinPath is not a signed binary code integrity policy." 3354 | } 3355 | } 3356 | -------------------------------------------------------------------------------- /Examples/ExamplePolicyBuilder.ps1: -------------------------------------------------------------------------------- 1 | # These are the policy rule options that will be applied to all built policies. 2 | $CommonBasePolicyRuleOptions = @( 3 | 'Enabled:Inherit Default Policy', 4 | 'Enabled:Unsigned System Integrity Policy', 5 | 'Enabled:Advanced Boot Options Menu', 6 | 'Enabled:Update Policy No Reboot', 7 | 'Enabled:Allow Supplemental Policies', 8 | 'Disabled:Flight Signing', 9 | 'Required:WHQL', 10 | 'Enabled:Boot Audit On Failure' 11 | ) 12 | 13 | # The following specified policies are expected to reside in the "BasePolicies" directory. 14 | $BasePolicyConfigurations = @( 15 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'BaseDriverPolicy.xml' -PolicyName 'BaseDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode'), 16 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'BaseUserPolicy.xml' -PolicyName 'BaseUserModeRuleset' -PolicyRuleOptions 'Disabled:Script Enforcement', 'Enabled:UMCI', 'Enabled:Audit Mode'), 17 | (New-WDACPolicyConfiguration -BasePolicy -FileName 'MicrosoftRecommendedBlockRules.xml' -PolicyName 'MicrosoftRecommendedBlockRuleset' -PolicyRuleOptions 'Disabled:Script Enforcement', 'Enabled:UMCI', 'Enabled:Audit Mode') 18 | ) 19 | 20 | # The following specified policies are expected to reside in the "SupplementalPolicies" directory. 21 | $SupplementalPolicyConfigurations = @( 22 | (New-WDACPolicyConfiguration -SupplementalPolicy -FileName 'MicrosoftSurfaceDriverPolicy.xml' -PolicyName '3rdPartyDriverRuleset' -PolicyRuleOptions 'Enabled:Audit Mode') 23 | ) 24 | 25 | # The following configuration implies that the "AppSpecificPolicies" directory is populated with policy XML files that are to be merged. 26 | $MergedPolicyConfiguration = New-WDACPolicyConfiguration -MergedPolicy -PolicyName 'Merged3rdPartySoftwareRuleset' -BasePolicyToSupplement 'BaseUserModeRuleset' -PolicyRuleOptions 'Enabled:Audit Mode' 27 | 28 | $CodeIntegrityPoliciesArgs = @{ 29 | CommonBasePolicyRuleOptions = $CommonBasePolicyRuleOptions 30 | BasePolicyConfiguration = $BasePolicyConfigurations 31 | SupplementalPolicyConfiguration = $SupplementalPolicyConfigurations 32 | MergedPolicyConfiguration = $MergedPolicyConfiguration 33 | } 34 | 35 | # Upon running this, all generated policy XML and binary .cip files will be stored in the "BuildArtifacts" directory. 36 | Invoke-WDACCodeIntegrityPolicyBuild @CodeIntegrityPoliciesArgs 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Matt Graeber 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | The `WDACTools` PowerShell module comprises everything that should be needed to build, configure, deploy, and audit [Windows Defender Application Control](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/windows-defender-application-control) (WDAC) policies. 2 | 3 | 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](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/select-types-of-rules-to-create) is specified. 4 | 5 | # Motivations 6 | 7 | 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](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/deploy-multiple-windows-defender-application-control-policies). In particular, this offers the following unique advantages: 8 | 9 | 1. 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. 10 | 2. 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. 11 | 3. When code integrity (CI) events are logged, the corresponding policy that generated the CI event is logged. 12 | 13 | # Problems 14 | 15 | 1. 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](https://posts.specterops.io/adventures-in-extremely-strict-device-guard-policy-configuration-part-1-device-drivers-fd1a281b35a8). 16 | 2. As rich as the logging is, it remains difficult to contextualize what all fields mean across many related events. 17 | 3. The existing WDAC cmdlets available in the [ConfigCI PowerShell module](https://docs.microsoft.com/en-us/powershell/module/configci/?view=win10-ps) 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. 18 | 19 | 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.** 20 | 21 | # Available Module Functions 22 | 23 | ### Usage 24 | 25 | Method 1: Import the module manifest directly 26 | 27 | ```powershell 28 | Import-Module WDACTools.psd1 29 | 30 | # View available exported functions 31 | Get-Command -Module WDACTools 32 | ``` 33 | 34 | 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: 35 | 36 | ```powershell 37 | $Env:PSModulePath -split ';' 38 | ``` 39 | 40 | ## New-WDACPolicyConfiguration 41 | 42 | Supports: `Configuration` 43 | 44 | `New-WDACPolicyConfiguration` is used as a helper function to generate code integrity policy configuration options and to supply them to the `Invoke-WDACCodeIntegrityPolicyBuild` function. 45 | 46 | ## Invoke-WDACCodeIntegrityPolicyBuild 47 | 48 | Supports: `Build`, `Deployment` 49 | 50 | `Invoke-WDACCodeIntegrityPolicyBuild` builds and, optionally, deploys and refreshes code integrity policies locally. 51 | 52 | ## Get-WDACCodeIntegrityEvent 53 | 54 | Supports: `Auditing` 55 | 56 | `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. 57 | 58 | ## Get-WDACApplockerScriptMsiEvent 59 | 60 | Supports: `Auditing` 61 | 62 | `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. 63 | 64 | ## ConvertTo-WDACCodeIntegrityPolicy 65 | 66 | Supports: `Auditing` 67 | 68 | `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`](https://docs.microsoft.com/en-us/powershell/module/configci/convertfrom-cipolicy?view=win10-ps) in reverse. 69 | 70 | ## Get-WDACCodeIntegrityBinaryPolicyCertificate 71 | 72 | Supports: `Auditing` 73 | 74 | `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.113549.1.7.2). 75 | 76 | # Expected CI Policy Locations 77 | 78 | `Invoke-WDACCodeIntegrityPolicyBuild` expects your policies to reside in specific directories included in this repository. 79 | 80 | ## `BasePolicies` Directory 81 | 82 | 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](https://web.archive.org/web/20190904022759/https://www.microsoft.com/security/blog/2019/07/01/delivering-major-enhancements-in-windows-defender-application-control-with-the-windows-10-may-2019-update/). 83 | 84 | ## `SupplementalPolicies` Directory 85 | 86 | This is where optional supplemental policies reside. These policies are intended to be updated more frequently whereas the base policies should rarely change. 87 | 88 | ## `AppSpecificPolicies` Directory 89 | 90 | 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](https://twitter.com/j3ffr3y1974/status/1189235744008802309). 91 | 92 | The policies in this directory will be merged together to form `MergedPolicy.xml` in the `BuildArtifacts` directory. 93 | 94 | # Recommended CI Policy Format 95 | 96 | As the `WDACTools` module was designed to facilitate consistency across all of your policies, it is recommended that your policies have the following characteristics: 97 | 98 | 1. Each policy have an empty policy rule option element. This would take on the following form: 99 | 100 | ```xml 101 | 102 | ``` 103 | 104 | `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. 105 | 106 | 2. Policy settings Name and ID fields should be named `REPLACEME`. Doing so, allows you to specify policy names via code. `Invoke-WDACCodeIntegrityPolicyBuild` populates each policy ID with the build date (format: `MM_DD_YYYY`) as a way to simplify auditing. 107 | 108 | ```xml 109 | 110 | 111 | 112 | REPLACEME 113 | 114 | 115 | 116 | 117 | REPLACEME 118 | 119 | 120 | 121 | ``` 122 | 123 | # Generated Build Artifacts 124 | 125 | When policies are built with `Invoke-WDACCodeIntegrityPolicyBuild`, all generated XML and binary policies are saved to the `BuildArtifacts` directory. `Invoke-WDACCodeIntegrityPolicyBuild` supports an optional `-ArtifactPath` parameter though that allows you to specify an alternate build artifact path. 126 | -------------------------------------------------------------------------------- /SupplementalPolicies/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattifestation/WDACTools/07be9ddfed49b56dd1952f7eb0361f6d540c4bf5/SupplementalPolicies/.empty -------------------------------------------------------------------------------- /WDACAuditing.psm1: -------------------------------------------------------------------------------- 1 | # File paths are often in the format of device path (e.g. \Device\HarddiskVolumeN\). 2 | # Get-Partition is used to map the volume number to a partition so that file paths can be normalized. 3 | $Script:PartitionMapping = @{} 4 | 5 | Get-Partition | Where-Object { $_.DriveLetter } | ForEach-Object { $PartitionMapping[$_.PartitionNumber.ToString()] = $_.DriveLetter } 6 | 7 | # Try again. Get-Partition is flakey for some reason but it seems to work if tried a second time. 8 | if ($PartitionMapping.Count -eq 0) { 9 | Get-Partition | Where-Object { $_.DriveLetter } | ForEach-Object { $PartitionMapping[$_.PartitionNumber.ToString()] = $_.DriveLetter } 10 | } 11 | 12 | # Resolve user names from SIDs 13 | $Script:UserMapping = @{} 14 | 15 | $Script:Providers = @{ 16 | 'Microsoft-Windows-AppLocker' = (Get-WinEvent -ListProvider Microsoft-Windows-AppLocker) 17 | 'Microsoft-Windows-CodeIntegrity' = (Get-WinEvent -ListProvider Microsoft-Windows-CodeIntegrity) 18 | } 19 | 20 | # Hash to cache event templates 21 | $Script:EventTemplates = @{} 22 | 23 | # This hashtable is used to resolve RequestedSigningLevel and ValidatedSigningLevel fields into human-readable properties 24 | # For more context around signing levels, Alex Ionescu (@aionescu) has a great resource on them: 25 | # http://www.alex-ionescu.com/?p=146 26 | # They are also officially documented here: https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/event-tag-explanations#validatedsigninglevel 27 | $Script:SigningLevelMapping = @{ 28 | [Byte] 0x0 = 'Not Checked' 29 | [Byte] 0x1 = 'Unsigned' 30 | [Byte] 0x2 = 'WDAC Code Integrity Policy' 31 | [Byte] 0x3 = 'Developer-Signed' 32 | [Byte] 0x4 = 'Authenticode-Signed' 33 | [Byte] 0x5 = 'Microsoft Store-Signed PPL' 34 | [Byte] 0x6 = 'Microsoft Store-Signed' 35 | [Byte] 0x7 = 'Antimalware PPL' 36 | [Byte] 0x8 = 'Microsoft-Signed' 37 | [Byte] 0x9 = 'Custom4' 38 | [Byte] 0xA = 'Custom5' 39 | [Byte] 0xB = '.NET NGEN Signer' 40 | [Byte] 0xC = 'Windows' 41 | [Byte] 0xD = 'Windows PPL' 42 | [Byte] 0xE = 'Windows TCB' 43 | [Byte] 0xF = 'Custom6' 44 | } 45 | 46 | # These are documented here: https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/event-tag-explanations#signaturetype 47 | $Script:SignatureTypeMapping = @{ 48 | [Byte] 0 = 'Unsigned' 49 | [Byte] 1 = 'Embedded Authenticode Signature' 50 | [Byte] 2 = 'Cached CI Extended Attribute Signature' 51 | [Byte] 3 = 'Cached Catalog Signature' 52 | [Byte] 4 = 'Catalog Signature' 53 | [Byte] 5 = 'Cached CI Extended Attribute Hint' 54 | [Byte] 6 = 'Appx or MSIX Package Catalog Verified' 55 | [Byte] 7 = 'File was Verified' 56 | } 57 | 58 | # These are documented here: https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/event-tag-explanations#verificationerror 59 | $Script:VerificationErrorMapping = @{ 60 | [Byte] 0 = 'Successfully verified signature' 61 | [Byte] 1 = 'File has an invalid hash' 62 | [Byte] 2 = 'File contains shared writable sections' 63 | [Byte] 3 = 'File is not signed' 64 | [Byte] 4 = 'Revoked signature' 65 | [Byte] 5 = 'Expired signature' 66 | [Byte] 6 = 'File is signed using a weak hashing algorithm which does not meet the minimum policy' 67 | [Byte] 7 = 'Invalid root certificate' 68 | [Byte] 8 = 'Signature was unable to be validated; generic error' 69 | [Byte] 9 = 'Signing time not trusted' 70 | [Byte] 10 = 'The file must be signed using page hashes for this scenario' 71 | [Byte] 11 = 'Page hash mismatch' 72 | [Byte] 12 = 'Not valid for a PPL (Protected Process Light)' 73 | [Byte] 13 = 'Not valid for a PP (Protected Process)' 74 | [Byte] 14 = 'The signature is missing the required ARM EKU' 75 | [Byte] 15 = 'Failed WHQL check' 76 | [Byte] 16 = 'Default policy signing level not met' 77 | [Byte] 17 = "Custom policy signing level not met; returned when signature doesn't validate against an SBCP-defined set of certs" 78 | [Byte] 18 = 'Custom signing level not met; returned if signature fails to match CISigners in UMCI' 79 | [Byte] 19 = 'Binary is revoked by file hash' 80 | [Byte] 20 = "SHA1 cert hash's timestamp is missing or after valid cutoff as defined by Weak Crypto Policy" 81 | [Byte] 21 = 'Failed to pass WDAC policy' 82 | [Byte] 22 = 'Not IUM (Isolated User Mode) signed; indicates trying to load a non-trustlet binary into a trustlet' 83 | [Byte] 23 = 'Invalid image hash' 84 | [Byte] 24 = 'Flight root not allowed; indicates trying to run flight-signed code on production OS' 85 | [Byte] 25 = 'Anti-cheat policy violation' 86 | [Byte] 26 = 'Explicitly denied by WDAC policy' 87 | [Byte] 27 = 'The signing chain appears to be tampered/invalid' 88 | [Byte] 28 = 'Resource page hash mismatch' 89 | } 90 | 91 | function Get-UserMapping { 92 | [CmdletBinding()] 93 | param ( 94 | # Security identifier of the account to look up 95 | [Parameter(Mandatory)] 96 | [System.Security.Principal.SecurityIdentifier]$SID 97 | ) 98 | 99 | if (-not ($UserMapping[$SID.Value])) { 100 | $Account = Get-CimInstance Win32_Account -Property SID, Caption -Filter ('SID="{0}"' -f $SID.Value) 101 | # Revert to the SID if a user name cannot be resolved 102 | $UserMapping[$SID.Value] = if ($Account.Caption) {$Account.Caption} else {$SID.Value} 103 | } 104 | $UserMapping[$SID.Value] 105 | } 106 | 107 | function Get-WDACPolicyRefreshEventFilter { 108 | <# 109 | .SYNOPSIS 110 | Returns a filter to use to get only events that occured since last policy refresh 111 | 112 | .DESCRIPTION 113 | Get-WDACPolicyRefreshEventFilter retrieves the latestMicrosoft-Windows-CodeIntegrity/Operational policy refresh event (id 3099) and generates a string to insert in "FilterXPath" filters to only search for events generated after the latest policy refresh 114 | 115 | .EXAMPLE 116 | Get-WDACPolicyRefreshEventFilter 117 | 118 | Looks for the latest policy refresh event and returns a filter string such as " and TimeCreated[@SystemTime >= '2020-10-05T08:11:22.7969367+02:00']" 119 | #> 120 | 121 | [CmdletBinding()] 122 | param() 123 | 124 | # Only consider failed audit events that occured after the last CI policy update (event ID 3099) 125 | $LastPolicyUpdateEvent = Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-CodeIntegrity/Operational'; Id = 3099 } -MaxEvents 1 -ErrorAction Ignore 126 | 127 | # Sometimes this event will not be present - e.g. if the log rolled since the last update. 128 | if ($LastPolicyUpdateEvent) { 129 | $DateTimeAfter = [Xml.XmlConvert]::ToString($LastPolicyUpdateEvent.TimeCreated.ToUniversalTime(), 'O') 130 | 131 | " and TimeCreated[@SystemTime >= '$DateTimeAfter']" 132 | } else { 133 | Write-Verbose "No policy update event was present in the event log. Ignoring the -SinceLastPolicyRefresh switch." 134 | '' 135 | } 136 | } 137 | 138 | function Get-WinEventData { 139 | [CmdletBinding()] 140 | param( 141 | [Parameter(Mandatory)] 142 | [Diagnostics.Eventing.Reader.EventLogRecord] $EventRecord 143 | ) 144 | 145 | process { 146 | $Provider = $Providers[$EventRecord.ProviderName] 147 | 148 | if ($Provider.Events.Id -contains $EventRecord.Id) { 149 | $EventTemplateName = $EventRecord.ProviderName, $EventRecord.Id, $EventRecord.Version -join '_' 150 | 151 | if (-not $EventTemplates[$EventTemplateName]) { 152 | $EventTemplates[$EventTemplateName] = ($Provider.Events | Where-Object { $_.Id -eq $EventRecord.Id -and $_.Version -eq $EventRecord.Version }).Template 153 | } 154 | 155 | [Xml] $XmlTemplate = $EventTemplates[$EventTemplateName] 156 | 157 | $EventData = @{} 158 | 159 | for ($i = 0; $i -lt $EventRecord.Properties.Count; $i++) { 160 | $Name = $XmlTemplate.template.data.name[$i] -replace ' ', '' 161 | $Value = $EventRecord.Properties[$i].Value 162 | 163 | $EventData[$Name] = $Value 164 | } 165 | 166 | $EventData 167 | } 168 | else { 169 | $EventRecord.Properties.Value 170 | } 171 | } 172 | } 173 | 174 | function Get-WDACApplockerScriptMsiEvent { 175 | <# 176 | .SYNOPSIS 177 | 178 | Returns script/MSI event log audit/enforcement events in a more human-readable fashion. 179 | 180 | .DESCRIPTION 181 | 182 | 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. 183 | 184 | Author: Matthew Graeber 185 | License: BSD 3-Clause 186 | 187 | .PARAMETER SignerInformation 188 | 189 | Specifies that correlated signer information should be collected. Note: When there are many CodeIntegrity events present in the event log, collection of signature events can be time consuming. 190 | 191 | .PARAMETER ShowAllowedEvents 192 | 193 | Specifies that Get-WDACApplockerScriptMsiEvent should also return scripts that were allowed to execute (via 8037 events) 194 | 195 | .PARAMETER SinceLastPolicyRefresh 196 | 197 | Specifies that events should only be returned since the last time the code integrity policy was refreshed. This option is useful for baselining purposes. 198 | 199 | .PARAMETER MaxEvents 200 | 201 | Specifies the maximum number of events that Get-WDACCodeIntegrityEvent returns. The default is to return all the events. 202 | 203 | .EXAMPLE 204 | 205 | Get-WDACApplockerScriptMsiEvent 206 | 207 | Return all user-mode code integrity events (audit/enforcement) since the last code intgrity policy refresh. 208 | 209 | .EXAMPLE 210 | 211 | Get-WDACApplockerScriptMsiEvent -MaxEvents 5 212 | 213 | Return the most recent 5 script/MSI code integrity events. 214 | 215 | .EXAMPLE 216 | 217 | Get-WDACApplockerScriptMsiEvent -SinceLastPolicyRefresh 218 | 219 | Return all script/MSI code integrity events since the last code intgrity policy refresh. 220 | 221 | .EXAMPLE 222 | 223 | Get-WDACApplockerScriptMsiEvent -SignerInformation 224 | #> 225 | 226 | [CmdletBinding()] 227 | param ( 228 | [Switch] 229 | $SignerInformation, 230 | 231 | [Switch] 232 | $ShowAllowedEvents, 233 | 234 | [Switch] 235 | $SinceLastPolicyRefresh, 236 | 237 | [Int64] 238 | $MaxEvents 239 | ) 240 | 241 | $MaxEventArg = @{} 242 | 243 | # Pass -MaxEvents through to Get-WinEvent 244 | if ($MaxEvents) { $MaxEventArg = @{ MaxEvents = $MaxEvents } } 245 | 246 | $PolicyRefreshFilter = '' 247 | 248 | if ($SinceLastPolicyRefresh) { 249 | $PolicyRefreshFilter = Get-WDACPolicyRefreshEventFilter -Verbose:$False 250 | } 251 | 252 | if ($ShowAllowedEvents) { 253 | $Filter = "*[System[(EventID = 8028 or EventID = 8029 or EventID = 8037)$($PolicyRefreshFilter)]]" 254 | } else { 255 | $Filter = "*[System[(EventID = 8028 or EventID = 8029)$($PolicyRefreshFilter)]]" 256 | } 257 | 258 | Write-Verbose "XPath Filter: $Filter" 259 | 260 | $EventIdMapping = @{ 261 | 8028 = 'Audit' 262 | 8029 = 'Enforce' 263 | 8037 = 'Allowed' 264 | } 265 | 266 | Get-WinEvent -LogName 'Microsoft-Windows-AppLocker/MSI and Script' -FilterXPath $Filter @MaxEventArg -ErrorAction Ignore | ForEach-Object { 267 | $ResolvedSigners = $null 268 | $SigningStatus = $null 269 | 270 | # 8037 (Allow) events do not populate signer information so don't attempt to retrieve 271 | if ($SignerInformation -and ($_.Id -ne 8037)) { 272 | $SigningStatus = 'Unsigned' 273 | 274 | # Retrieve correlated signer info (event ID 8038) 275 | # Note: there may be more than one correlated signer event in the case of the file having multiple signers. 276 | $Signer = Get-WinEvent -LogName 'Microsoft-Windows-AppLocker/MSI and Script' -FilterXPath "*[System[EventID = 8038 and Correlation[@ActivityID = '$($_.ActivityId.Guid)']]]" -MaxEvents 1 -ErrorAction Ignore 277 | 278 | # Unsigned scripts will often generate bogus 8038 events. Don't process them 279 | if ($Signer.Properties.Count -gt 0) { 280 | 281 | if ($Signer.Properties[0].Value -gt 1) { 282 | $Signer = Get-WinEvent -LogName 'Microsoft-Windows-AppLocker/MSI and Script' -FilterXPath "*[System[EventID = 8038 and Correlation[@ActivityID = '$($_.ActivityId.Guid)']]]" -MaxEvents ($Signer.Properties[0].Value) -ErrorAction Ignore 283 | } 284 | 285 | $ResolvedSigners = $Signer | ForEach-Object { 286 | $SignerData = Get-WinEventData -EventRecord $_ 287 | 288 | if (-not (($SignerData.PublisherNameLength -eq 0) -and ($SignerData.IssuerNameLength -eq 0) -and ($SignerData.PublisherTBSHashSize -eq 0) -and ($SignerData.IssuerTBSHashSize -eq 0))) { 289 | $SigningStatus = 'Signed' 290 | 291 | $PublisherTBSHash = $null 292 | if ($SignerData.PublisherTBSHash) { $PublisherTBSHash = [BitConverter]::ToString($SignerData.PublisherTBSHash).Replace('-','') } 293 | 294 | $IssuerTBSHash = $null 295 | if ($SignerData.IssuerTBSHash) { $IssuerTBSHash = [BitConverter]::ToString($SignerData.IssuerTBSHash).Replace('-','') } 296 | 297 | New-Object -TypeName PSObject -Property ([Ordered] @{ 298 | SignatureIndex = $SignerData.Signature 299 | PublisherName = $SignerData.PublisherName 300 | IssuerName = $SignerData.IssuerName 301 | PublisherTBSHash = $PublisherTBSHash 302 | IssuerTBSHash = $IssuerTBSHash 303 | }) 304 | } 305 | } 306 | } 307 | } 308 | 309 | $EventData = Get-WinEventData -EventRecord $_ 310 | 311 | $UserName = Get-UserMapping $_.UserId.Value 312 | 313 | $SHA1FileHash = $null 314 | if ($EventData.Sha1Hash) { $SHA1FileHash = [BitConverter]::ToString($EventData.Sha1Hash).Replace('-','') } 315 | 316 | $SHA256FileHash = $null 317 | if ($EventData.Sha256CatalogHash) { $SHA256FileHash = [BitConverter]::ToString($EventData.Sha256CatalogHash).Replace('-','') } 318 | 319 | $SHA256AuthenticodeHash = $null 320 | if ($EventData.Sha256Hash) { $SHA256AuthenticodeHash = [BitConverter]::ToString($EventData.Sha256Hash).Replace('-','') } 321 | 322 | $ObjectArgs = [Ordered] @{ 323 | TimeCreated = $_.TimeCreated 324 | ProcessID = $_.ProcessId 325 | User = $UserName 326 | EventType = $EventIdMapping[$_.Id] 327 | FilePath = $EventData.FilePath 328 | SHA1FileHash = $SHA1FileHash 329 | SHA256FileHash = $SHA256FileHash 330 | SHA256AuthenticodeHash = $SHA256AuthenticodeHash 331 | UserWriteable = $EventData.UserWriteable 332 | Signed = $SigningStatus 333 | SignerInfo = ($ResolvedSigners | Sort-Object -Property SignatureIndex) 334 | } 335 | 336 | New-Object -TypeName PSObject -Property $ObjectArgs 337 | } 338 | } 339 | 340 | function Get-WDACCodeIntegrityEvent { 341 | <# 342 | .SYNOPSIS 343 | 344 | Returns code integrity event log audit/enforcement events in a more human-readable fashion. 345 | 346 | .DESCRIPTION 347 | 348 | 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. 349 | 350 | Author: Matthew Graeber 351 | License: BSD 3-Clause 352 | 353 | .PARAMETER User 354 | 355 | Specifies that only user-mode events should be returned. If neither -User nor -Kernel is specified, user and kernel events are returned. 356 | 357 | .PARAMETER Kernel 358 | 359 | Specifies that only kernel-mode events should be returned. If neither -User nor -Kernel is specified, user and kernel events are returned. 360 | 361 | .PARAMETER Audit 362 | 363 | Specifies that only audit events (event ID 3076) should be returned. If neither -Audit nor -Enforce is specified, audit and enforcement events are returned. 364 | 365 | .PARAMETER Enforce 366 | 367 | Specifies that only enforcement events (event ID 3077) should be returned. If neither -Audit nor -Enforce is specified, audit and enforcement events are returned. 368 | 369 | .PARAMETER SinceLastPolicyRefresh 370 | 371 | Specifies that events should only be returned since the last time the code integrity policy was refreshed. This option is useful for baselining purposes. 372 | 373 | .PARAMETER SignerInformation 374 | 375 | Specifies that correlated signer information should be collected. Note: When there are many CodeIntegrity events present in the event log, collection of signature events can be time consuming. 376 | 377 | .PARAMETER CheckWhqlStatus 378 | 379 | Specifies that correlated WHQL events should be collected. Supplying this switch will populate the returned FailedWHQL property. 380 | 381 | .PARAMETER IgnoreNativeImagesDLLs 382 | 383 | Specifies that events where ResolvedFilePath is like "$env:SystemRoot\assembly\NativeImages*.dll" should be skipped. Useful to suppress events caused by auto-generated "NativeImages DLLs" 384 | 385 | .PARAMETER IgnoreDenyEvents 386 | 387 | Specifies that only events will be returned that are not explicitly blocked by policy. This switch only works when -SignerInformation is also specified. This switch is available to help reduce noise and prevent inadvertantly creating allow rules for explicitly denied executables. 388 | 389 | .PARAMETER MaxEvents 390 | 391 | Specifies the maximum number of events that Get-WDACCodeIntegrityEvent returns. The default is to return all the events. 392 | 393 | .EXAMPLE 394 | 395 | Get-WDACCodeIntegrityEvent -SinceLastPolicyRefresh 396 | 397 | Return all code integrity events (user/kernel/audit/enforcement) since the last code intgrity policy refresh. 398 | 399 | .EXAMPLE 400 | 401 | Get-WDACCodeIntegrityEvent -User -SinceLastPolicyRefresh 402 | 403 | Return all user-mode code integrity events (audit/enforcement) since the last code intgrity policy refresh. 404 | 405 | .EXAMPLE 406 | 407 | Get-WDACCodeIntegrityEvent -Kernel -MaxEvents 5 408 | 409 | Return the most recent 5 kernel mode code integrity events. 410 | 411 | .EXAMPLE 412 | 413 | Get-WDACCodeIntegrityEvent -Kernel -Enforce 414 | 415 | Return all kernel mode enforcement events. 416 | #> 417 | 418 | [CmdletBinding(DefaultParameterSetName = 'NoSignerCheck')] 419 | param ( 420 | [Parameter(ParameterSetName = 'NoSignerCheck')] 421 | [Parameter(ParameterSetName = 'SignerCheck')] 422 | [Switch] 423 | $User, 424 | 425 | [Parameter(ParameterSetName = 'NoSignerCheck')] 426 | [Parameter(ParameterSetName = 'SignerCheck')] 427 | [Switch] 428 | $Kernel, 429 | 430 | [Parameter(ParameterSetName = 'NoSignerCheck')] 431 | [Parameter(ParameterSetName = 'SignerCheck')] 432 | [Switch] 433 | $Audit, 434 | 435 | [Parameter(ParameterSetName = 'NoSignerCheck')] 436 | [Parameter(ParameterSetName = 'SignerCheck')] 437 | [Switch] 438 | $Enforce, 439 | 440 | [Parameter(ParameterSetName = 'NoSignerCheck')] 441 | [Parameter(ParameterSetName = 'SignerCheck')] 442 | [Switch] 443 | $SinceLastPolicyRefresh, 444 | 445 | [Parameter(Mandatory, ParameterSetName = 'SignerCheck')] 446 | [Switch] 447 | $SignerInformation, 448 | 449 | [Parameter(ParameterSetName = 'NoSignerCheck')] 450 | [Parameter(ParameterSetName = 'SignerCheck')] 451 | [Switch] 452 | $CheckWhqlStatus, 453 | 454 | [Parameter(ParameterSetName = 'NoSignerCheck')] 455 | [Parameter(ParameterSetName = 'SignerCheck')] 456 | [Switch] 457 | $IgnoreNativeImagesDLLs, 458 | 459 | [Parameter(ParameterSetName = 'SignerCheck')] 460 | [Switch] 461 | $IgnoreDenyEvents, 462 | 463 | [Parameter(ParameterSetName = 'NoSignerCheck')] 464 | [Parameter(ParameterSetName = 'SignerCheck')] 465 | [Int64] 466 | $MaxEvents 467 | ) 468 | 469 | # If neither -User nor -Kernel are supplied, do not filter based on signing scenario 470 | # If -User and -Kernel are supplied, do not filter based on signing scenario 471 | # Only filter in a mutually exclusive scenario. 472 | $ScenarioFilter = '' 473 | 474 | if ($User -and !$Kernel) { 475 | # 1 == A user-mode rule triggered 476 | $ScenarioFilter = " and EventData[Data[@Name='SI Signing Scenario'] = 1]" 477 | } elseif ($Kernel -and !$User) { 478 | # 2 == A kernel-mode rule triggered 479 | $ScenarioFilter = " and EventData[Data[@Name='SI Signing Scenario'] = 0]" 480 | } 481 | 482 | # If neither -Audit nor -Enforce are supplied, do not filter based on event ID 483 | # If -Audit and -Enforce are supplied, do not filter based on event ID 484 | # Only filter in a mutually exclusive scenario. 485 | $ModeFilter = '(EventID = 3076 or EventID = 3077)' 486 | 487 | if ($Audit -and !$Enforce) { 488 | # Event ID 3076 == an audit event 489 | $ModeFilter = "EventID = 3076" 490 | } elseif ($Enforce -and !$Audit) { 491 | # Event ID 3077 == an enforcement event 492 | $ModeFilter = "EventID = 3077" 493 | } 494 | 495 | $PolicyRefreshFilter = '' 496 | 497 | if ($SinceLastPolicyRefresh) { 498 | $PolicyRefreshFilter = Get-WDACPolicyRefreshEventFilter -Verbose:$False 499 | } 500 | 501 | $Filter = "*[System[$($ModeFilter)$($PolicyRefreshFilter)]$ScenarioFilter]" 502 | 503 | Write-Verbose "XPath Filter: $Filter" 504 | 505 | $EventIdMapping = @{ 506 | 3076 = 'Audit' 507 | 3077 = 'Enforce' 508 | } 509 | 510 | $SigningScenarioMapping = @{ 511 | [UInt32] 0 = 'Driver' 512 | [UInt32] 1 = 'UserMode' 513 | } 514 | 515 | $MaxEventArg = @{} 516 | 517 | # Pass -MaxEvents through to Get-WinEvent 518 | if ($MaxEvents) { $MaxEventArg = @{ MaxEvents = $MaxEvents } } 519 | 520 | Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -FilterXPath $Filter @MaxEventArg -ErrorAction Ignore | ForEach-Object { 521 | $EventData = Get-WinEventData -EventRecord $_ 522 | 523 | $WHQLFailed = $null 524 | 525 | if ($CheckWhqlStatus) { 526 | $WHQLFailed = $False 527 | 528 | # A correlated 3082 event indicates that WHQL verification failed 529 | $WHQLEvent = Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -FilterXPath "*[System[EventID = 3082 and Correlation[@ActivityID = '$($_.ActivityId.Guid)']]]" -MaxEvents 1 -ErrorAction Ignore 530 | 531 | if ($WHQLEvent) { $WHQLFailed = $True } 532 | } 533 | 534 | $ResolvedSigners = $null 535 | $ExplicitlyDeniedSigner = $False 536 | 537 | if ($SignerInformation) { 538 | # Retrieve correlated signer info (event ID 3089) 539 | # Note: there may be more than one correlated signer event in the case of the file having multiple signers. 540 | $Signer = Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -FilterXPath "*[System[EventID = 3089 and Correlation[@ActivityID = '$($_.ActivityId.Guid)']]]" -MaxEvents 1 -ErrorAction Ignore 541 | 542 | if ($Signer -and $Signer.Properties -and ($Signer.Properties[0].Value -gt 1)) { 543 | $Signer = Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -FilterXPath "*[System[EventID = 3089 and Correlation[@ActivityID = '$($_.ActivityId.Guid)']]]" -MaxEvents ($Signer.Properties[0].Value) -ErrorAction Ignore 544 | } 545 | 546 | $ResolvedSigners = $Signer | ForEach-Object { 547 | $SignerData = Get-WinEventData -EventRecord $_ 548 | 549 | $SignatureType = $SignatureTypeMapping[$SignerData.SignatureType] 550 | 551 | $VerificationError = $VerificationErrorMapping[$SignerData.VerificationError] 552 | 553 | if ($IgnoreDenyEvents -and ($VerificationError -eq 'Explicitly denied by WDAC policy')) { $ExplicitlyDeniedSigner = $True } 554 | 555 | $Hash = $null 556 | if ($SignerData.Hash) { $Hash = [BitConverter]::ToString($SignerData.Hash).Replace('-','') } 557 | 558 | $PublisherTBSHash = $null 559 | if ($SignerData.PublisherTBSHash) { $PublisherTBSHash = [BitConverter]::ToString($SignerData.PublisherTBSHash).Replace('-','') } 560 | 561 | $IssuerTBSHash = $null 562 | if ($SignerData.IssuerTBSHash) { $IssuerTBSHash = [BitConverter]::ToString($SignerData.IssuerTBSHash).Replace('-','') } 563 | 564 | New-Object -TypeName PSObject -Property ([Ordered] @{ 565 | SignatureIndex = $SignerData.Signature 566 | Hash = $Hash 567 | PageHash = $SignerData.PageHash 568 | SignatureType = $SignatureType 569 | ValidatedSigningLevel = $SigningLevelMapping[$SignerData.ValidatedSigningLevel] 570 | VerificationError = $VerificationError 571 | Flags = $SignerData.Flags 572 | PolicyBits = $SignerData.PolicyBits 573 | NotValidBefore = $SignerData.NotValidBefore 574 | NotValidAfter = $SignerData.NotValidAfter 575 | PublisherName = $SignerData.PublisherName 576 | IssuerName = $SignerData.IssuerName 577 | PublisherTBSHash = $PublisherTBSHash 578 | IssuerTBSHash = $IssuerTBSHash 579 | }) 580 | } 581 | } 582 | 583 | if (-not $ExplicitlyDeniedSigner) { 584 | $UnresolvedFilePath = $EventData.FileName 585 | 586 | $ResolvedFilePath = $null 587 | # Make a best effort to resolve the device path to a normal path. 588 | if ($UnresolvedFilePath -match '(?^\\Device\\HarddiskVolume(?\d)\\)') { 589 | $ResolvedFilePath = $UnresolvedFilePath.Replace($Matches['Prefix'], "$($PartitionMapping[$Matches['VolumeNumber']]):\") 590 | } elseif ($UnresolvedFilePath.ToLower().StartsWith('system32')) { 591 | $ResolvedFilePath = "$($Env:windir)\System32$($UnresolvedFilePath.Substring(8))" 592 | } 593 | 594 | # If all else fails regarding path resolution, show a warning. 595 | if ($ResolvedFilePath -and !(Test-Path -Path $ResolvedFilePath)) { 596 | Write-Warning "The following file path was either not resolved properly or was not present on disk: $ResolvedFilePath" 597 | } 598 | 599 | $ResolvedProcessName = $null 600 | $ProcessName = $EventData.ProcessName 601 | # Make a best effort to resolve the process path to a normal path. 602 | if ($ProcessName -match '(?^\\Device\\HarddiskVolume(?\d)\\)') { 603 | $ResolvedProcessName = $ProcessName.Replace($Matches['Prefix'], "$($PartitionMapping[$Matches['VolumeNumber']]):\") 604 | } elseif ($ProcessName.ToLower().StartsWith('system32')) { 605 | $ResolvedProcessName = "$($Env:windir)\System32$($ProcessName.Substring(8))" 606 | } 607 | 608 | # If all else fails regarding path resolution, show a warning. 609 | if ($ResolvedProcessName -and !(Test-Path -Path $ResolvedProcessName)) { 610 | Write-Warning "The following process file path was either not resolved properly or was not present on disk: $ResolvedProcessName" 611 | } 612 | 613 | $UserName = Get-UserMapping $_.UserId.Value 614 | 615 | $SHA1FileHash = $null 616 | if ($EventData.SHA1FlatHash) { $SHA1FileHash = [BitConverter]::ToString($EventData.SHA1FlatHash[0..19]).Replace('-','') } 617 | 618 | $SHA1AuthenticodeHash = $null 619 | if ($EventData.SHA1Hash) { $SHA1AuthenticodeHash = [BitConverter]::ToString($EventData.SHA1Hash).Replace('-','') } 620 | 621 | $SHA256FileHash = $null 622 | if ($EventData.SHA256FlatHash) { $SHA256FileHash = [BitConverter]::ToString($EventData.SHA256FlatHash[0..31]).Replace('-','') } 623 | 624 | $SHA256AuthenticodeHash = $null 625 | if ($EventData.SHA256Hash) { $SHA256AuthenticodeHash = [BitConverter]::ToString($EventData.SHA256Hash).Replace('-','') } 626 | 627 | $PolicyGuid = $null 628 | if ($EventData.PolicyGUID) { $PolicyGuid = $EventData.PolicyGUID.Guid.ToUpper() } 629 | 630 | $PolicyHash = $null 631 | if ($EventData.PolicyHash) { $PolicyHash = [BitConverter]::ToString($EventData.PolicyHash).Replace('-','') } 632 | 633 | $CIEventProperties = [Ordered] @{ 634 | TimeCreated = $_.TimeCreated 635 | ProcessID = $_.ProcessId 636 | User = $UserName 637 | EventType = $EventIdMapping[$_.Id] 638 | SigningScenario = $SigningScenarioMapping[$EventData.SISigningScenario] 639 | UnresolvedFilePath = $UnresolvedFilePath 640 | FilePath = $ResolvedFilePath 641 | SHA1FileHash = $SHA1FileHash 642 | SHA1AuthenticodeHash = $SHA1AuthenticodeHash 643 | SHA256FileHash = $SHA256FileHash 644 | SHA256AuthenticodeHash = $SHA256AuthenticodeHash 645 | UnresolvedProcessName = $EventData.ProcessName 646 | ProcessName = $ResolvedProcessName 647 | RequestedSigningLevel = $SigningLevelMapping[$EventData.RequestedSigningLevel] 648 | ValidatedSigningLevel = $SigningLevelMapping[$EventData.ValidatedSigningLevel] 649 | PolicyName = $EventData.PolicyName 650 | PolicyID = $EventData.PolicyId 651 | PolicyGUID = $PolicyGuid 652 | PolicyHash = $PolicyHash 653 | OriginalFileName = $EventData.OriginalFileName 654 | InternalName = $EventData.InternalName 655 | FileDescription = $EventData.FileDescription 656 | ProductName = $EventData.ProductName 657 | FileVersion = $EventData.FileVersion 658 | PackageFamilyName = $EventData.PackageFamilyName 659 | UserWriteable = $EventData.UserWriteable 660 | FailedWHQL = $WHQLFailed 661 | SignerInfo = ($ResolvedSigners | Sort-Object -Property SignatureIndex) 662 | } 663 | 664 | if (-not $IgnoreNativeImagesDLLs -or ($IgnoreNativeImagesDLLs -and $CIEventProperties.ResolvedFilePath -notlike "$env:SystemRoot\assembly\NativeImages*.dll")) { 665 | New-Object -TypeName PSObject -Property $CIEventProperties 666 | } 667 | } 668 | } 669 | } 670 | 671 | function Copy-WDACEventFile { 672 | <# 673 | .SYNOPSIS 674 | 675 | Copies files returned by the Get-WDACApplockerScriptMsiEvent or Get-WDACCodeIntegrityEvent functions to a destination directory. 676 | 677 | .DESCRIPTION 678 | 679 | Copy-WDACEventFile copies files returned by the Get-WDACApplockerScriptMsiEvent or Get-WDACCodeIntegrityEvent functions to a destination directory. When developing targeted code integrity policies, it is ideal to consolidate all the relevant files in a dedicated directory that are not intermingled with files not to be added per policy. Copy-WDACEventFile copies files in a targeted fashion such that Get-SystemDriver will scan a specific path containing only the relevant file. 680 | 681 | Author: Matthew Graeber 682 | License: BSD 3-Clause 683 | 684 | .PARAMETER FilePath 685 | 686 | Specifies the filepath of the executable or script to be copied. 687 | 688 | .PARAMETER Destination 689 | 690 | Specifies the destination directory where all files will be copied. 691 | 692 | .EXAMPLE 693 | 694 | Get-WDACCodeIntegrityEvent | Copy-WDACEventFile -Destination .\FilesToAllow 695 | 696 | .EXAMPLE 697 | 698 | Get-WDACApplockerScriptMsiEvent | Copy-WDACEventFile -Destination .\FilesToAllow 699 | 700 | .INPUTS 701 | 702 | PSObject 703 | 704 | Copy-WDACEventFile accepts the output of Get-WDACApplockerScriptMsiEvent and Get-WDACCodeIntegrityEvent. 705 | 706 | .OUTPUTS 707 | 708 | System.IO.FileInfo 709 | 710 | Copy-WDACEventFile outputs a FileInfo object representing the new file that was copied to its destination. 711 | #> 712 | 713 | [CmdletBinding()] 714 | param ( 715 | [Parameter(Mandatory, Position = 1)] 716 | [String] 717 | [ValidateScript({ Test-Path -Path $_ -PathType Container })] 718 | $Destination, 719 | 720 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0)] 721 | [String[]] 722 | [ValidateNotNullOrEmpty()] 723 | $FilePath 724 | ) 725 | 726 | BEGIN { 727 | $ResolvedDestination = Resolve-Path $Destination 728 | } 729 | 730 | PROCESS { 731 | foreach ($Path in $FilePath) { 732 | $FileName = Split-Path -Path $Path -Leaf 733 | $ChildDestinationDirectory = (Split-Path -Path $Path -Parent).Substring(2) 734 | 735 | $DestinationDirectory = Join-Path -Path $ResolvedDestination -ChildPath $ChildDestinationDirectory 736 | $DestinationFilePath = Join-Path -Path $DestinationDirectory -ChildPath $FileName 737 | 738 | # If the destination directory doesn't exist, create it 739 | if (-not (Test-Path -Path $DestinationDirectory -PathType Container)) { 740 | $null = mkdir -Path $DestinationDirectory -Force 741 | } 742 | 743 | Copy-Item -Path $Path -Destination $DestinationFilePath -PassThru 744 | } 745 | } 746 | } -------------------------------------------------------------------------------- /WDACTools.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # Script module or binary module file associated with this manifest. 4 | # RootModule = '' 5 | 6 | # Version number of this module. 7 | ModuleVersion = '2.0.1.0' 8 | 9 | # Supported PSEditions 10 | # CompatiblePSEditions = @() 11 | 12 | # ID used to uniquely identify this module 13 | GUID = '2aa9f041-3cbf-4904-9c1f-c19fe6675789' 14 | 15 | # Author of this module 16 | Author = 'Matthew Graeber' 17 | 18 | # Copyright statement for this module 19 | Copyright = 'BSD 3-Clause' 20 | 21 | # Description of the functionality provided by this module 22 | Description = 'A module to facilitate building, deploying, and auditing WDAC policies.' 23 | 24 | # Minimum version of the Windows PowerShell engine required by this module 25 | PowerShellVersion = '5.0' 26 | 27 | # Name of the Windows PowerShell host required by this module 28 | # PowerShellHostName = '' 29 | 30 | # Minimum version of the Windows PowerShell host required by this module 31 | # PowerShellHostVersion = '' 32 | 33 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 34 | # DotNetFrameworkVersion = '' 35 | 36 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 37 | # CLRVersion = '' 38 | 39 | # Processor architecture (None, X86, Amd64) required by this module 40 | # ProcessorArchitecture = '' 41 | 42 | # Modules that must be imported into the global environment prior to importing this module 43 | # RequiredModules = @() 44 | 45 | # Assemblies that must be loaded prior to importing this module 46 | RequiredAssemblies = 'System.Security' 47 | 48 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 49 | # ScriptsToProcess = @() 50 | 51 | # Type files (.ps1xml) to be loaded when importing this module 52 | # TypesToProcess = @() 53 | 54 | # Format files (.ps1xml) to be loaded when importing this module 55 | # FormatsToProcess = @() 56 | 57 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 58 | NestedModules = @('BuildAndDeployPolicies.psm1', 59 | 'CIPolicyParser.psm1', 60 | 'WDACAuditing.psm1') 61 | 62 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 63 | FunctionsToExport = 'New-WDACPolicyConfiguration', 64 | 'Invoke-WDACCodeIntegrityPolicyBuild', 65 | 'Get-WDACCodeIntegrityEvent', 66 | 'Get-WDACApplockerScriptMsiEvent', 67 | 'ConvertTo-WDACCodeIntegrityPolicy', 68 | 'Get-WDACCodeIntegrityBinaryPolicyCertificate', 69 | 'Update-WDACBinaryCodeIntegrityPolicy', 70 | 'Copy-WDACEventFile', 71 | 'Disable-WDACDeployedPolicy' 72 | 73 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 74 | # CmdletsToExport = '*' 75 | 76 | # Variables to export from this module 77 | # VariablesToExport = '*' 78 | 79 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 80 | # AliasesToExport = '*' 81 | 82 | # DSC resources to export from this module 83 | # DscResourcesToExport = @() 84 | 85 | # List of all modules packaged with this module 86 | # ModuleList = @() 87 | 88 | # List of all files packaged with this module 89 | # FileList = @() 90 | 91 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 92 | PrivateData = @{ 93 | 94 | PSData = @{ 95 | 96 | # Tags applied to this module. These help with module discovery in online galleries. 97 | # Tags = @() 98 | 99 | # A URL to the license for this module. 100 | # LicenseUri = '' 101 | 102 | # A URL to the main website for this project. 103 | # ProjectUri = '' 104 | 105 | # A URL to an icon representing this module. 106 | # IconUri = '' 107 | 108 | # ReleaseNotes of this module 109 | # ReleaseNotes = '' 110 | 111 | } # End of PSData hashtable 112 | 113 | } # End of PrivateData hashtable 114 | 115 | # HelpInfo URI of this module 116 | # HelpInfoURI = '' 117 | 118 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 119 | # DefaultCommandPrefix = '' 120 | 121 | } 122 | 123 | --------------------------------------------------------------------------------