While doing incident response, if AppLocker is being used but the computer still got infected by a malicious executable, it is useful to know exactly what AppLocker policy is currently applied.
Leveraging PowerShell is the right choice to achieve this. The following cmdlet will dump the current AppLocker policy to a XML file. It will do that by reading the registry without the need for special permissions (i.e. administrator).
1AppLocker-Dump -PolicyFile policy.xml
The resulting XML file will contain all the rules and conditions making it easy to audit them. Follows the source code.
1<#
2.SYNOPSIS
3 Dump the AppLocker policy to a XML file.
4.DESCRIPTION
5 This cmdlet allows a normal user, without any special permissions, to
6 dump the AppLocker policy from the registry to a XML file.
7.PARAMETER PolicyFile
8 Where to write the AppLocker policy
9.LINK
10 https://www.serializing.me/2015/11/01/inspecting-applocker-policy/
11.NOTE
12 Function: AppLocker-Dump
13 Author: Duarte Silva (@serializingme)
14 License: GPLv3
15 Required Dependencies: None
16 Optional Dependencies: None
17 Version: 1.0.0
18#>
19function AppLocker-Dump {
20 [CmdletBinding()]
21 param(
22 [Parameter(Mandatory = $True, HelpMessage = 'To what file will the AppLocker policy be written?')]
23 [String]$PolicyFile
24 )
25
26 function Write-PolicyRule {
27 param(
28 [System.Xml.XmlWriter]$XmlWriter,
29 [String]$Rule
30 )
31
32 [System.IO.StringReader]$StringReader = $Null
33 [System.Xml.XmlReader]$XmlReader = $Null
34
35 try {
36 $Property = Get-ItemProperty -Path ('Registry::{0}' -f $Rule) -Name 'Value' `
37 -ErrorAction SilentlyContinue
38
39 $StringReader = New-Object -TypeName 'System.IO.StringReader' -ArgumentList @(
40 $Property.Value )
41
42 $XmlReader = [System.Xml.XmlReader]::Create($StringReader)
43 $XmlWriter.WriteNode($XmlReader, $False)
44 }
45 finally {
46 if ($XmlReader -ne $Null) {
47 $XmlReader.Close()
48 }
49
50 if ($StringReader -ne $Null) {
51 $StringReader.Close()
52 }
53 }
54 }
55
56 function Write-PolicyRules {
57 param(
58 [System.Xml.XmlWriter]$XmlWriter,
59 [String]$Group
60 )
61
62 Get-ChildItem -Path ('Registry::{0}' -f $Group) | ForEach-Object {
63 Write-PolicyRule -XmlWriter $XmlWriter -Rule $_.Name
64 }
65 }
66
67 function Write-PolicyGroups {
68 param(
69 [System.Xml.XmlWriter]$XmlWriter
70 )
71
72 # Get AppLocker policy groups and process the rules.
73 Get-ChildItem -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\SrpV2' | ForEach-Object {
74 $XmlWriter.WriteStartElement('Group')
75 $XmlWriter.WriteAttributeString('Name', $_.PSChildName)
76
77 Write-PolicyRules -XmlWriter $XmlWriter -Group $_.Name
78
79 $XmlWriter.WriteEndElement()
80 }
81 }
82
83 [System.IO.FileStream]$PolicyFileStrean = $Null
84 [System.Xml.XmlWriter]$PolicyXmlWriter = $Null
85
86 try {
87 [System.IO.FileInfo]$PolicyFileInfo = New-Object -TypeName 'System.IO.FileInfo' `
88 -ArgumentList @( $PolicyFile )
89
90 if ($PolicyFileInfo.Exists) {
91 $PSCmdlet.WriteWarning('The selected file for the policy exists and it will be overwritten')
92 }
93
94 # Instantiate the streams.
95 $PolicyFileStrean = New-Object -TypeName 'System.IO.FileStream' -ArgumentList @(
96 $PolicyFileInfo.FullName, [system.IO.FileMode]::Create, [System.IO.FileAccess]::Write )
97
98 # Instantiate the XML writer.
99 $PolicyXmlWriter = [System.Xml.XmlWriter]::Create($PolicyFileStrean)
100 $PolicyXmlWriter.WriteStartElement('AppLocker')
101 $PolicyXmlWriter.WriteAttributeString('Date', (Get-Date -Format 'O'))
102 $PolicyXmlWriter.WriteAttributeString('Host', (Hostname))
103
104 Write-PolicyGroups -XmlWriter $PolicyXmlWriter
105
106 $PolicyXmlWriter.WriteEndElement()
107 }
108 finally {
109 if ($PolicyXmlWriter -ne $Null) {
110 $PolicyXmlWriter.Close()
111 }
112
113 if ($PolicyFileStrean -ne $Null) {
114 $PolicyFileStrean.Dispose()
115 }
116 }
117}
Hope it’s useful :D