Inspecting AppLocker Policy

Inspecting AppLocker Policy

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