├── .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 |
--------------------------------------------------------------------------------