At this year’s Security BSides in Austin, Michael Gough of MI2 Security gave a great workshop on Windows Logging. One of the points he made was that auditing file and registry creation events on high value folders and keys can provide information critical to the detection and remediation of breaches. PowerShell should be used to automate and standardize the process of file and registry auditing. I had some trouble finding information on using PowerShell in this way. So I created this post to collect what I found.
File auditing has to be configured in 2 steps.
STEP 1: File and Registry auditing should be turned on in the Audit Policy.
If you use the standard Windows Audit Policy, you would enable at least Success for Audit Object Access.
If you are using Advanced Audit Policy Configuration, you would enable at least Success for Audit File System, Audit Registry, and Audit Kernel Object auditing under the Object Access subcategory.
STEP 2: Modify the SACLs on the folders and registry keys you want to audit.
Normally, this would be done manually. This involves navigating to the key or folder you want to audit, right-clicking, going to Properties, going to the Security tab, opening Advanced, going to the Auditing tab, and then configuring your auditing. But why do that when you can use PowerShell?
I have created 2 PowerShell functions that can greatly speed up the process of configuring the SACLs on folders and registry keys. The first function is called AddAuditToFile and it adds auditing to a File or Folder object.
function AddAuditToFile { param ( [Parameter(Mandatory=$true)] [string]$path ) Get-Acl $path -Audit | Format-List Path,AuditToString | Out-File -FilePath 'file_before.txt' -Width 200 -Append $File_ACL = Get-Acl $path $AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule("Everyone","CreateFiles”,"none","none",”Success") $File_ACL.AddAuditRule($AccessRule) $File_ACL | Set-Acl $path Get-Acl $path -Audit | Format-List Path,AuditToString | Out-File -FilePath 'file_after.txt' -Width 200 -Append }
The second function is called AddAuditToRegKey.
function AddAuditToRegKey { param ( [Parameter(Mandatory=$true)] [string]$key ) Get-Acl $key -Audit | Format-List Path,AuditToString | Out-File -FilePath 'reg_before.txt' -Width 200 -Append $RegKey_ACL = Get-Acl $key $AccessRule = New-Object System.Security.AccessControl.RegistryAuditRule("Everyone","SetValue,CreateSubKey,Delete”,"none","none",”Success") $RegKey_ACL.AddAuditRule($AccessRule) $RegKey_ACL | Set-Acl $key Get-Acl $key -Audit | Format-List Path,AuditToString | Out-File -FilePath 'reg_after.txt' -Width 200 -Append }
The functions only require a path to the file or registry key. When used within a PS1 file, it looks like this:
AddAuditToFile “C:\Windows” <– UPDATE: This doesn’t work.
AddAuditToFile “C:\test_dir”
AddAuditToRegKey “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”
NOTE: The registry hive must be followed with a colon. So HKLM: as in the example above.
The functions output a TXT file with a before and after picture of the audit settings for each object.
I have the functions set up to audit Everyone on specific Successful actions. Create Files for file auditing and Set Value, Create Subkey, and Delete for registry auditing. This is done when configuring the class ‘System.Security.AccessControl.RegistryAuditRule’ and ‘System.Security.AccessControl.FileSystemAuditRule’. Let’s spend some time talking about these classes as they are key to modifying auditing with PowerShell.
FileSystemAuditRule and RegistryAuditRule Classes
Even though there are separate classes for files and registry, they accept (mostly) the same values.
FileSystem/RegistryAuditRule("IdentityReference","RightsToAudit”,"InheritanceFlags","PropagationFlags",”AuditFlags")
Microsoft has some documentation on FileSystemAuditRule and RegistryAuditRule if you want to dig into that.
But let’s discuss the acceptable values for each constructor.
AuditFlags can have a value of Success, Failure, or none. Multiple values like “Success,Failure” would be comma separated.
IdentityReference is just the name or object reference of the user or group that will be audited.
InheritanceFlags and PropagationFlags determine if the audit settings will be inherited from parent folders or if the audit settings will be propagated to child folders. I highly recommend that this be left at the default, which is none for both values. Accidentally propagating auditing settings to sub folders could create an excessive amount of traffic in your logs. When both values are set to “none”, it shows up under Properties/Security/Advanced/Auditing on the file or registry object as This Folder Only.
RightsToAudit has different values depending upon if FileSystemAuditRule or RegistryAuditRule is being used.
RightsToAudit can have the following values when using RegistryAuditRule.
- FullControl
- QueryValues
- SetValue
- CreateSubKey
- EnumerateSubKeys
- Notify
- CreateLink
- Delete
- WriteKey
- ChangePermissions
- TakeOwnership
- ReadPermissions
RightsToAudit can have the following values when using FileSystemAuditRule
- FullControl
- DeleteSubdirectoriesAndFiles
- Modify
- ChangePermissions
- TakeOwnership
- ExecuteFile
- ReadData
- ReadAttributes
- ReadExtendedAttributes
- CreateFiles
- AppendData
- WriteAttributes
- WriteExtendedAttributes
- Delete
- ReadPermissions
A comma separated list is used to add auditing for more than one property.
So, if we wanted to audit all Successful and Failed Take Ownership and File Creation events for Everyone with no propagation or inheritance, it would look like this.
New-Object System.Security.AccessControl.FileSystemAuditRule("Everyone","CreateFiles,TakeOwnership”,"none","none",”Success,Failure")
Monitoring high value keys and folders with object auditing can help us catch malicious behavior that otherwise might have gone unnoticed. PowerShell can help us by quickly and consistently configuring audit setting across a large number of machines. Hopefully the information in this post will be helpful. Please give me your feedback in the comments.
Response to Configure File and Registry Auditing with PowerShell