Showing preview only (854K chars total). Download the full file or copy to clipboard to get everything.
Repository: darkoperator/Posh-Sysmon
Branch: master
Commit: f89a27fd1897
Files: 65
Total size: 822.3 KB
Directory structure:
gitextract_jqcvzr7i/
├── .gitattributes
├── Config.ps1
├── Filters.ps1
├── Format/
│ ├── Sysmon.ConfigOption.ps1xml
│ ├── Sysmon.Rule.Filter.ps1xml
│ └── Sysmon.Rule.ps1xml
├── Functions/
│ ├── ConvertFrom-SysmonBinaryConfiguration.ps1
│ ├── ConvertTo-SysmonXMLConfiguration.ps1
│ ├── Get-SysmonConfiguration.ps1
│ ├── Get-SysmonEventData.ps1
│ ├── Get-SysmonHashingAlgorithm.ps1
│ ├── Get-SysmonRule.ps1
│ ├── Get-SysmonRuleFilter.ps1
│ ├── New-SysmonConfiguration.ps1
│ ├── New-SysmonCreateRemoteThreadFilter.ps1
│ ├── New-SysmonDriverLoadFilter.ps1
│ ├── New-SysmonFileCreateFilter.ps1
│ ├── New-SysmonFileCreateStreamHashFilter.ps1
│ ├── New-SysmonImageLoadFilter.ps1
│ ├── New-SysmonNetworkConnectFilter.ps1
│ ├── New-SysmonPipeFilter.ps1
│ ├── New-SysmonProcessAccessFilter.ps1
│ ├── New-SysmonProcessCreateFilter.ps1
│ ├── New-SysmonProcessTerminateFilter.ps1
│ ├── New-SysmonRawAccessReadFilter.ps1
│ ├── New-SysmonRegistryFilter.ps1
│ ├── New-SysmonWmiFilter.ps1
│ ├── Remove-SysmonRule.ps1
│ ├── Remove-SysmonRuleFilter.ps1
│ ├── Schemas/
│ │ ├── SysmonConfigurationSchema_3_40.xsd
│ │ └── SysmonConfigurationSchema_4_00.xsd
│ ├── Set-SysmonHashingAlgorithm.ps1
│ └── Set-SysmonRule.ps1
├── LICENSE
├── Posh-SysMon.psm1
├── Posh-Sysmon.psd1
├── README.md
├── build.ps1
├── docs/
│ ├── Get-SysmonEventData.md
│ ├── Get-SysmonHashingAlgorithm.md
│ ├── Get-SysmonRule.md
│ ├── Get-SysmonRuleFilter.md
│ ├── New-SysmonConfiguration.md
│ ├── New-SysmonDriverLoadFilter.md
│ ├── New-SysmonFileCreateFilter.md
│ ├── New-SysmonFileCreateStreamHash.md
│ ├── New-SysmonFileCreateStreamHashFilter.md
│ ├── New-SysmonImageLoadFilter.md
│ ├── New-SysmonNetworkConnectFilter.md
│ ├── New-SysmonPipeEvent.md
│ ├── New-SysmonPipeFilter.md
│ ├── New-SysmonProcessAccessFilter.md
│ ├── New-SysmonProcessCreateFilter.md
│ ├── New-SysmonProcessTerminateFilter.md
│ ├── New-SysmonRegistryEvent.md
│ ├── New-SysmonRegistryFilter.md
│ ├── Remove-SysmonRule.md
│ ├── Remove-SysmonRuleFilter.md
│ ├── Set-SysmonHashingAlgorithm.md
│ └── Set-SysmonRule.md
├── en-US/
│ ├── Posh-SysMon-help.xml
│ └── Posh-SysMon.psm1-Help.xml
└── lib/
├── sysmon3_1.dtd
├── sysmon3_2.dtd
└── sysmon3_3.dtd
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
# Custom for PowerShell*.psm1 text
*.psd1 text
*.psm1 text
*.ps1xml text
================================================
FILE: Config.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonConfiguration
{
[CmdletBinding(HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonConfiguration.md')]
Param
(
# Path to write XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String]
$Path,
# Specify one or more hash algorithms used for image identification
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
[string[]]
$HashingAlgorithm,
# Log Network Connections
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[Switch]
$NetworkConnect,
# Log process loading of modules.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[Switch]
$DriverLoad,
# Log process loading of modules.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[Switch]
$ImageLoad,
# Log create remote thread actions.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=5)]
[Switch]
$CreateRemoteThread,
# Log file creation time modifications.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=6)]
[Switch]
$FileCreateTime,
# Log process creation.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=7)]
[Switch]
$ProcessCreate,
# Log process termination.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=8)]
[Switch]
$ProcessTerminate,
# Log when a running process opens another process.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=9)]
[Switch]
$ProcessAccess,
# Log raw access reads of files.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=10)]
[Switch]
$RawAccessRead,
# Check for signature certificate revocation.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=11 )]
[Switch]
$CheckRevocation,
# Log Registry events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=12 )]
[Switch]
$RegistryEvent,
# Log File Creation events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=13 )]
[Switch]
$FileCreate,
# Log File Stream creations events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=14 )]
[Switch]
$FileCreateStreamHash,
# Log NamedPipes connection and creations events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=15 )]
[Switch]
$PipeEvent,
# WMI Permanent Event component events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=16 )]
[Switch]
$WmiEvent,
# Comment for purpose of the configuration file.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true)]
[String]
$Comment,
# Schema Vesion for the configuration file, default is 3.3.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true)]
[ValidateSet('2.0','3.0', '3.1', '3.2','3.3', '3.4')]
[String]
$SchemaVersion = '3.4'
)
Begin{}
Process
{
if ($HashingAlgorithm -contains 'ALL')
{
$Hash = '*'
}
else
{
$Hash = $HashingAlgorithm -join ','
}
$Config = ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path))
# get an XMLTextWriter to create the XML
$XmlWriter = New-Object System.XMl.XmlTextWriter($Config,$Null)
# choose a pretty formatting:
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = 1
# write the header
if ($Comment)
{
$xmlWriter.WriteComment($Comment)
}
$xmlWriter.WriteStartElement('Sysmon')
$XmlWriter.WriteAttributeString('schemaversion', $SchemaVersion)
Write-Verbose -Message "Enabling hashing algorithms : $($Hash)"
$xmlWriter.WriteElementString('HashAlgorithms',$Hash)
# Enable checking revocation.
if ($CheckRevocation)
{
if ($SchemaVersion -in @('3.1','3.2','3.3','3.4'))
{
Write-Verbose -message 'Enabling CheckRevocation.'
$xmlWriter.WriteElementString('CheckRevocation','')
}
else
{
Write-Warning -Message 'CheckRevocation was not enabled because it is not supported in this SchemaVersion.'
}
}
# Create empty EventFiltering section.
$xmlWriter.WriteStartElement('EventFiltering')
if ($NetworkConnect)
{
Write-Verbose -Message 'Enabling network connection logging for all connections by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('NetworkConnect')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($DriverLoad)
{
Write-Verbose -Message 'Enabling logging all driver loading by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('DriverLoad ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ImageLoad)
{
Write-Verbose -Message 'Enabling logging all image loading by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ImageLoad ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($CreateRemoteThread)
{
Write-Verbose -Message 'Enabling logging all CreateRemoteThread API actions by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('CreateRemoteThread ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessCreate)
{
Write-Verbose -Message 'Enabling logging all process creation by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessCreate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessTerminate)
{
Write-Verbose -Message 'Enabling logging all process termination by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessTerminate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($FileCreateTime)
{
Write-Verbose -Message 'Enabling logging all process creation by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('FileCreateTime ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessAccess)
{
Write-Verbose -Message 'Enabling logging all process access by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessAccess ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($RawAccessRead)
{
Write-Verbose -Message 'Enabling logging all process access by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('RawAccessRead ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# Log registry events.
if ($RegistryEvent)
{
if ($SchemaVersion -gt 3.2)
{
Write-Verbose -message 'Enabling RegistryEvent.'
$xmlWriter.WriteStartElement('RegistryEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
else
{
Write-Warning -Message 'RegistryEvent was not enabled because it is not supported in this SchemaVersion.'
}
}
# Log file create events.
if ($FileCreate)
{
if ($SchemaVersion -gt 3.2)
{
Write-Verbose -message 'Enabling FileCreate.'
$xmlWriter.WriteStartElement('FileCreate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
else
{
Write-Warning -Message 'FileCreate was not enabled because it is not supported in this SchemaVersion.'
}
}
# Log file create events.
if ($FileCreateStreamHash)
{
if ($SchemaVersion -gt 3.2)
{
Write-Verbose -message 'Enabling FileCreateStreamHash.'
$xmlWriter.WriteStartElement('FileCreateStreamHash ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
else
{
Write-Warning -Message 'FileCreateStreamHash was not enabled because it is not supported in this SchemaVersion.'
}
}
# NamedPipes create and connect events.
if ($PipeEvent)
{
if ($SchemaVersion -gt 3.2)
{
Write-Verbose -message 'Enabling PipeEvent.'
$xmlWriter.WriteStartElement('PipeEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
else
{
Write-Warning -Message 'PipeEvent was not enabled because it is not supported in this SchemaVersion.'
}
}
# NamedPipes create and connect events.
if ($WmiEvent)
{
if ($SchemaVersion -gt 3.4)
{
Write-Verbose -message 'Enabling WmiEvent.'
$xmlWriter.WriteStartElement('WmiEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
els
{
Write-Warning -Message 'WmiEvent was not enabled because it is not supported in this SchemaVersion.'
}
}
# End Element of EventFiltering
$xmlWriter.WriteFullEndElement()
# Sysmon
$xmlWriter.WriteEndElement()
# finalize the document:
#$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()
Write-Verbose -Message "Config file created as $($Config)"
write-verbose -Message "Configuration is for Sysmon $($sysmonVerMap[$SchemaVersion])"
}
End
{
}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonHashingAlgorithm
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonHashingAlgorithm.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[string]$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
[string]$LiteralPath
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path' {[xml]$Config = Get-Content -Path $Path}
'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
}
}
catch [System.Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
$ObjOptions = @{}
if ($Config.Sysmon.SelectSingleNode('//HashAlgorithms'))
{
$ObjOptions['Hashing'] = $config.Sysmon.HashAlgorithms
}
else
{
$ObjOptions['Hashing'] = ''
}
#$ObjOptions['Comment'] = $Config.'#comment'
$ConfigObj = [pscustomobject]$ObjOptions
$ConfigObj.pstypenames.insert(0,'Sysmon.HashingAlgorithm')
$ConfigObj
}
End{}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonRule
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRule.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[string]$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
[string]$LiteralPath,
# Event type to parse rules for.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('ALL', 'NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'ProcessAccess',
'RawAccessRead','ProcessAccess', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
[string[]]
$EventType = @('ALL')
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path' {[xml]$Config = Get-Content -Path $Path}
'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
}
}
catch [System.Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
# Collect all individual rules if they exist.
$Rules = $Config.Sysmon.EventFiltering
if ($EventType -contains 'ALL')
{
$TypesToParse = @('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad','CreateRemoteThread',
'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')
}
else
{
$TypesToParse = $EventType
}
foreach($Type in $TypesToParse)
{
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
$RuleData = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
if($RuleData -ne $null)
{
Write-Verbose -Message "$($EvtType) Rule Found."
Get-RuleWithFilter($RuleData)
}
}
}
End{}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Set-SysmonHashingAlgorithm
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Set-SysmonHashingAlgorithm.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Specify one or more hash algorithms used for image identification
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
[string[]]
$HashingAlgorithm
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path'
{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath'
{
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [System.Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
Write-Verbose -Message 'Updating Hashing option.'
if ($HashingAlgorithm -contains 'ALL')
{
$Hash = '*'
}
else
{
$Hash = $HashingAlgorithm -join ','
}
# Check if Hashing Alorithm node exists.
if($Config.SelectSingleNode('//Sysmon/HashAlgorithms') -ne $null)
{
$Config.Sysmon.HashAlgorithms = $Hash
}
else
{
$HashElement = $Config.CreateElement('HashAlgorithms')
[void]$Config.Sysmon.Configuration.AppendChild($HashElement)
$Config.Sysmon.Configuration.Hashing = $Hash
}
Write-Verbose -Message 'Hashing option has been updated.'
Write-Verbose -Message "Option have been set on $($FileLocation)"
$Config.Save($FileLocation)
}
End{}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Set-SysmonRule
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Set-SysmonRule.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type to update.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
[string[]]
$EventType,
# Action for event type rule and filters.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Include', 'Exclude')]
[String]
$OnMatch = 'Exclude',
# Action to take for Schema 3.0 files.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[ValidateSet('Modify', 'Add')]
[String]
$Action = 'Modify'
)
Begin{}
Process
{
# if no elemrnt create one either if it is schema 2.0 or 3.0.
# If one is present we modify that one if Schema 2.0 and if Schema 3.0 and action modify.
# If Schema 3.0 and action add we check if only is present and that it is not the same OnMatch
# as being specified if it is we do nothing if not we add.
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path'
{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath'
{
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
$Rules = $config.SelectSingleNode('//Sysmon/EventFiltering')
foreach($Type in $EventType)
{
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
$RuleData = $Rules.SelectSingleNode("//EventFiltering/$($EvtType)")
$elements = $Rules."$($EvtType)" | Select-Object -property onmatch -Unique
if($RuleData -ne $null)
{
if ($Rules."$($EvtType)".count -eq $null)
{
if (($Config.Sysmon.schemaversion -eq '2.0') -or ($Config.Sysmon.schemaversion -in @('3.0', '3.1', '3.2','3.3', '3.4') -and $Action -eq 'Modify'))
{
Write-Verbose -Message "Setting as default action for $($EvtType) the rule on match of $($OnMatch)."
$RuleData.SetAttribute('onmatch',($OnMatch.ToLower()))
Write-Verbose -Message 'Action has been set.'
}
elseif ($Config.Sysmon.schemaversion -in @('3.0', '3.1', '3.2','3.3', '3.4') -and $Action -eq 'Add')
{
if ($RuleData.onmatch -ne $OnMatch)
{
Write-Verbose -Message "Creating rule for event type with action of $($OnMatch)"
$TypeElement = $config.CreateElement($EvtType)
$TypeElement.SetAttribute('onmatch',($OnMatch.ToLower()))
$RuleData = $Rules.AppendChild($TypeElement)
Write-Verbose -Message 'Action has been set.'
}
else
{
Write-Verbose -Message 'A rule with the specified onmatch action already exists.'
}
}
}
elseif ($Config.Sysmon.schemaversion -in ('3.0', '3.1', '3.2','3.3', '3.4') -and $elements.count -eq 2)
{
Write-Verbose -Message 'A rule with the specified onmatch action already exists.'
}
else
{
Write-Error -Message 'This XML file does not conform to the schema.'
return
}
}
else
{
Write-Verbose -Message "No rule for $($EvtType) was found."
Write-Verbose -Message "Creating rule for event type with action of $($OnMatch)"
$TypeElement = $config.CreateElement($EvtType)
$TypeElement.SetAttribute('onmatch',($OnMatch.ToLower()))
$RuleData = $Rules.AppendChild($TypeElement)
Write-Verbose -Message 'Action has been set.'
}
Get-RuleWithFilter($RuleData)
}
$config.Save($FileLocation)
}
End{}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRule
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRule.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type to remove. It is case sensitive.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
[string[]]
$EventType,
# Action for event type rule and filters.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Include', 'Exclude')]
[String]
$OnMatch = 'Exclude'
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path'
{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath'
{
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
$Rules = $config.SelectSingleNode('//Sysmon/EventFiltering')
foreach ($rule in $rules.ChildNodes)
{
if ($rule.name -in $EventType -and $rule.onmatch -eq $OnMatch)
{
[void]$rule.ParentNode.RemoveChild($rule)
Write-Verbose -Message "Removed rule for $($EventType)."
}
}
$config.Save($FileLocation)
}
End{}
}
================================================
FILE: Filters.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonImageLoadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonImageLoadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'ImageLoaded', 'Hashes', 'Signed',
'Signature')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process
{
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ImageLoad'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath'
{
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End { }
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonDriverLoadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonDriverLoadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ImageLoaded',
'Hashes', 'Signed', 'Signature')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'DriverLoad'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonNetworkConnectFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonNetworkConnectFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'User', 'Protocol', 'Initiated', 'SourceIsIpv6',
'SourceIp', 'SourceHostname', 'SourcePort',
'SourcePortName', 'DestinationIsIpv6',
'DestinationIp', 'DestinationHostname',
'DestinationPort', 'DestinationPortName')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'NetworkConnect'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonFileCreateFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'TargetFilename', 'CreationUtcTime',
'PreviousCreationUtcTime')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
switch($psCmdlet.ParameterSetName) {
'Path' {
New-RuleFilter -Path $Path -EventType FileCreateTime -Condition $Condition -EventField $FieldString -Value $Value -OnMatch $OnMatch
}
'LiteralPath' {
New-RuleFilter -LiteralPath $LiteralPath -EventType FileCreateTime -Condition $Condition -EventField $FieldString -Value $Value -OnMatch $OnMatch
}
}
}
End {}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessCreateFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessCreateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'CommandLine', 'User', 'LogonGuid', 'LogonId',
'TerminalSessionId', 'IntegrityLevel',
'Hashes', 'ParentProcessGuid', 'ParentProcessId',
'ParentImage', 'ParentCommandLine')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessCreate'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End { }
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessTerminateFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessTerminateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process
{
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessTerminate'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath'
{
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonCreateRemoteThreadFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonCreateRemoteThreadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('SourceImage', 'TargetImage')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin { }
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'CreateRemoteThread'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for the logging of when a running process opens another.
.DESCRIPTION
Create a new filter for the logging of when a running process opens another.
.EXAMPLE
C:\PS> New-SysmonProcessAccessFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField TargetImage lsass.exe
Log any process trying to open lsass.exe.
#>
function New-SysmonProcessAccessFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessAccessFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'SourceProcessGUID',
'SourceProcessId', 'SourceThreadId', 'SourceImage',
'TargetProcessGUID', 'TargetProcessId', 'TargetImage',
'GrantedAccess','CallTrace')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessAccess'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for the logging of file raw access read actions.
.DESCRIPTION
Create a new filter for the logging of file raw access read actions.
.EXAMPLE
C:\PS> New-SysmonRawAccessReadFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField Image NTDS.dit
Log any raw access read of the file NTDS.dit.
#>
function New-SysmonRawAccessReadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRawAccessReadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId',
'Image', 'Device')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'RawAccessRead'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for the logging file creation.
.DESCRIPTION
Create a new filter for the logging file creation.
.EXAMPLE
#>
function New-SysmonFileCreateFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
'Image')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'FileCreate'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for the logging of the saving of data on a file stream.
.DESCRIPTION
Create a new filter for the logging of the saving of data on a file stream.
#>
function New-SysmonFileCreateStreamHashFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateStreamHashFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
'Image')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'FileCreateStreamHash'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for the actions against the registry.
.DESCRIPTION
Create a new filter for actions against the registry. Supports filtering
by aby of the following event types:
* CreateKey
* DeleteKey
* RenameKey
* CreateValue
* DeleteValue
* RenameValue
* SetValue
Hives on Schema 3.2 in TargetObject are referenced as:
* \REGISTRY\MACHINE\HARDWARE
* \REGISTRY\USER\Security ID number
* \REGISTRY\MACHINE\SECURITY
* \REGISTRY\USER\.DEFAULT
* \REGISTRY\MACHINE\SYSTEM
* \REGISTRY\MACHINE\SOFTWARE
* \REGISTRY\MACHINE\SAM
Hives on Schema 3.3 and above in TargetObject are referenced as:
* HKLM
* HKCR
* HKEY_USER
.EXAMPLE
C:\PS> New-SysmonRegistryFilter -Path .\32config.xml -OnMatch include -Condition Contains -EventField TargetObject 'RunOnce'
Capture persistance attemp by creating a registry entry in the RunOnce keys.
#>
function New-SysmonRegistryFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRegistryFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({ Test-Path -Path $_ })]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('TargetObject', 'ProcessGuid', 'ProcessId',
'Image', 'EventType')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {
# Event types used to validate right type and string case
$EventTypeMap = @{
CreateKey = 'CreateKey'
DeleteKey = 'DeleteKey'
RenameKey = 'RenameKey'
CreateValue = 'CreateValue'
DeleteValue = 'DeleteValue'
RenameValue = 'RenameValue'
SetValue = 'SetValue'
}
$Etypes = $EventTypeMap.Keys
}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
if ($EventField -in 'EventType') {
if ($Value -in $Etypes) {
$Value = $EventTypeMap[$Value]
} else {
Write-Error -Message "Not a supported EventType. Supported Event types $($Etypes -join ', ')"
return
}
}
$cmdoptions = @{
'EventType' = 'RegistryEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for when a Named Pipe is created or connected.
.DESCRIPTION
Create a new filter for when a Named Pipe is created or connected.
Useful for watching malware inter process communication.
#>
function New-SysmonPipeFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonPipeFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('Pipe', 'ProcessGuid', 'ProcessId',
'Image')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'PipeEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
<#
.SYNOPSIS
Create a new filter for WMI Permamanent Event Classes.
.DESCRIPTION
Create a new filter for WMI permamanent event classes are created or connected.
Useful for monitoring for persistence actions.
#>
function New-SysmonWmiFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonWmiFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('Name', 'EventNamespace', 'Destination',
'Type', 'Query', 'Operation', 'Consumer', 'Filter')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'WmiEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRuleFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRuleFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type to update.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad',
'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess',
'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
'PipeEvent', 'WmiEvent')]
[string]
$EventType,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=5)]
[string[]]
$Value
)
Begin{}
Process {
$EvtType = $null
# Check if the file is a valid XML file and if not raise and error.
try {
switch($psCmdlet.ParameterSetName) {
'Path' {
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath' {
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [Management.Automation.PSInvalidCastException] {
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null) {
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
$Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')
# Select the proper condition string.
switch ($Condition) {
'Is' {$ConditionString = 'is'}
'IsNot' {$ConditionString = 'is not'}
'Contains' {$ConditionString = 'contains'}
'Excludes' {$ConditionString = 'excludes'}
'Image' {$ConditionString = 'image'}
'BeginWith' {$ConditionString = 'begin with'}
'EndWith' {$ConditionString = 'end with'}
'LessThan' {$ConditionString = 'less than'}
'MoreThan' {$ConditionString = 'more than'}
Default {$ConditionString = 'is'}
}
# Check if the event type exists if not create it.
if ($Rules -eq '') {
Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
return
} else {
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]
$EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
}
if($EventRule -eq $null) {
Write-Warning -Message "No rule for $($EvtType) was found."
return
}
if($EventRule -eq $null) {
Write-Error -Message "No rule for $($EvtType) was found."
return
} else {
if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
if ($EventRule.onmatch -eq $OnMatch) {
$Filters = $EventRule.SelectNodes('*')
if ($Filters.count -gt 0) {
foreach($val in $Value) {
foreach($Filter in $Filters) {
if ($Filter.Name -eq $EventField) {
if (($Filter.condition -eq $null) -and ($Condition -eq 'is') -and ($Filter.'#text' -eq $val)) {
[void]$Filter.ParentNode.RemoveChild($Filter)
Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
} elseif (($Filter.condition -eq $Condition) -and ($Filter.'#text' -eq $val)) {
[void]$Filter.ParentNode.RemoveChild($Filter)
Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
}
}
}
}
Get-RuleWithFilter($EventRule)
}
}
} else {
Write-Verbose -Message 'Mutiple nodes.'
foreach ($rule in $EventRule) {
if ($rule.onmatch -eq $OnMatch) {
$Filters = $rule.SelectNodes('*')
if ($Filters.count -gt 0) {
foreach($val in $Value) {
foreach($Filter in $Filters) {
if ($Filter.Name -eq $EventField) {
if (($Filter.condition -eq $null) -and ($Condition -eq 'is') -and ($Filter.'#text' -eq $val)) {
[void]$Filter.ParentNode.RemoveChild($Filter)
Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
} elseif (($Filter.condition -eq $Condition) -and ($Filter.'#text' -eq $val)) {
[void]$Filter.ParentNode.RemoveChild($Filter)
Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
}
}
}
}
Get-RuleWithFilter($rule)
}
}
}
}
}
$config.Save($FileLocation)
}
End{}
}
<#
.SYNOPSIS
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.DESCRIPTION
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.EXAMPLE
C:\PS> Get-SysmonRuleFilter -Path C:\sysmon.xml -EventType ProcessCreate
Get the filter under the ProcessCreate Rule.
#>
function Get-SysmonRuleFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRuleFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type rule to get filter for.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad',
'CreateRemoteThread','RawAccessRead', 'ProcessAccess',
'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
'PipeEvent', 'WmiEvent')]
[string]
$EventType,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch
)
Begin{}
Process {
$EvtType = $null
# Check if the file is a valid XML file and if not raise and error.
try {
switch($psCmdlet.ParameterSetName){
'Path'{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath' {
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [System.Management.Automation.PSInvalidCastException] {
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null){
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
$Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')
if ($Rules -eq '') {
Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
return
} else {
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]
$EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
}
if($EventRule -eq $null) {
Write-Error -Message "No rule for $($EvtType) was found."
return
} else {
if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
Write-Verbose -Message 'Single Node'
if ($EventRule.onmatch -eq $OnMatch) {
$Filters = $EventRule.SelectNodes('*')
if ($Filters.ChildNodes.Count -gt 0) {
foreach($Filter in $Filters) {
$FilterObjProps = @{}
$FilterObjProps['EventField'] = $Filter.Name
$FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
$FilterObjProps['Value'] = $Filter.'#text'
$FilterObjProps['EventType'] = $EvtType
$FilterObjProps['OnMatch'] = $OnMatch
$FilterObj = [pscustomobject]$FilterObjProps
$FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
$FilterObj
}
}
}
}
else
{
Write-Verbose -Message 'Mutiple nodes.'
foreach ($rule in $EventRule)
{
if ($rule.onmatch -eq $OnMatch)
{
$Filters = $rule.SelectNodes('*')
if ($Filters.ChildNodes.Count -gt 0)
{
foreach($Filter in $Filters)
{
$FilterObjProps = @{}
$FilterObjProps['EventField'] = $Filter.Name
$FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
$FilterObjProps['Value'] = $Filter.'#text'
$FilterObjProps['EventType'] = $EvtType
$FilterObjProps['OnMatch'] = $OnMatch
$FilterObj = [pscustomobject]$FilterObjProps
$FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
$FilterObj
}
}
}
}
}
}
}
End{}
}
<#
.Synopsis
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.DESCRIPTION
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.EXAMPLE
Get-SysMonEventData -EventId 1 -MaxEvents 10 -EndTime (Get-Date) -StartTime (Get-Date).AddDays(-1)
All process creation events in the last 24hr
.EXAMPLE
Get-SysMonEventData -EventId 3 -MaxEvents 20 -Path .\export.evtx
last 20 network connection events from a exported SysMon log.
#>
function Get-SysmonEventData {
[CmdletBinding(DefaultParameterSetName='ID',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonEventData.md')]
Param (
# Sysmon Event ID of records to show
[Parameter(Mandatory=$true,
ParameterSetName='ID',
ValueFromPipelineByPropertyName=$true,
Position=0)]
[ValidateSet(1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,255)]
[Int32[]]
$EventId,
# EventType that a Rule can be written against.
[Parameter(Mandatory=$false,
ParameterSetName='Type',
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string[]]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad',
'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess', 'Error',
'FileCreateStreamHash', 'RegistryValueSet', 'RegistryRename',
'RegistryAddOrDelete', 'FileCreate','ConfigChange','PipeCreated',
'PipeConnected', 'WmiFilter', 'WmiConsumer', 'WmiBinding')]
$EventType,
# Specifies the maximum number of events that Get-WinEvent returns. Enter an integer. The default is to return all the events in the logs or files.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[int]
$MaxEvents,
# Specifies a path to one or more exported SysMon events in evtx format.
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
HelpMessage='Path to one or more locations.')]
[Alias('PSPath')]
[ValidateNotNullOrEmpty()]
[string[]]
$Path,
# Start Date to get all event going forward.
[Parameter(Mandatory=$false)]
[datetime]
$StartTime,
# End data for searching events.
[Parameter(Mandatory=$false)]
[datetime]
$EndTime
)
Begin
{
$EventTypeMap = @{
ProcessCreate = 1
FileCreateTime = 2
NetworkConnect = 3
ProcessTerminate = 5
DriverLoad = 6
ImageLoad = 7
CreateRemoteThread = 8
RawAccessRead = 9
ProcessAccess = 10
FileCreate = 11
RegistryAddOrDelete = 12
RegistryValueSet = 13
RegistryRename = 14
FileCreateStreamHash = 15
ConfigChange = 16
PipeCreated = 17
PipeConnected = 18
WmiFilter = 19
WmiConsumer = 20
WmiBinding = 21
Error = 255
}
$EventIdtoType = @{
'1' = 'ProcessCreate'
'2' = 'FileCreateTime'
'3' = 'NetworkConnect'
'5' = 'ProcessTerminate'
'6' = 'DriverLoad'
'7' = 'ImageLoad'
'8' = 'CreateRemoteThread'
'9' = 'RawAccessRead'
'10' = 'ProcessAccess'
'11' = 'FileCreate'
'12' = 'RegistryAddOrDelete'
'13' = 'RegistryValueSet'
'14' = 'RegistryRename'
'15' = 'FileCreateStreamHash'
'16' = 'ConfigChange'
'17' = 'PipeCreated'
'18' = 'PipeConnected'
'19' = 'WmiFilter'
'20' = 'WmiConsumer'
'21' = 'WmiBinding'
'255' = 'Error'
}
}
Process
{
# Hash for filtering
$HashFilter = @{LogName='Microsoft-Windows-Sysmon/Operational'}
# Hash for command paramteters
$ParamHash = @{}
if ($MaxEvents -gt 0)
{
$ParamHash.Add('MaxEvents', $MaxEvents)
}
if ($Path -gt 0)
{
$ParamHash.Add('Path', $Path)
}
switch ($PSCmdlet.ParameterSetName) {
'ID' { $HashFilter.Add('Id', $EventId) }
'Type' {
$EventIds = @()
foreach ($etype in $EventType)
{
$EventIds += $EventTypeMap[$etype]
}
$HashFilter.Add('Id', $EventIds)
}
}
if ($StartTime)
{
$HashFilter.Add('StartTime', $StartTime)
}
if ($EndTime)
{
$HashFilter.Add('EndTime', $EndTime)
}
$ParamHash.Add('FilterHashTable',$HashFilter)
Get-WinEvent @ParamHash | ForEach-Object {
[xml]$evtxml = $_.toxml()
$ProcInfo = [ordered]@{}
$ProcInfo['EventId'] = $evtxml.Event.System.EventID
$ProcInfo['EventType'] = $EventIdtoType[$evtxml.Event.System.EventID]
$ProcInfo['Computer'] = $evtxml.Event.System.Computer
$evtxml.Event.EventData.Data | ForEach-Object {
$ProcInfo[$_.name] = $_.'#text'
}
New-Object psobject -Property $ProcInfo
}
}
End {}
}
================================================
FILE: Format/Sysmon.ConfigOption.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Sysmon.ConfigOption</Name>
<ViewSelectedBy>
<TypeName>Sysmon.ConfigOption</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<Label>Hashing</Label>
<PropertyName>Hashing</PropertyName>
</ListItem>
<ListItem>
<Label>Network</Label>
<PropertyName>Network</PropertyName>
</ListItem>
<ListItem>
<Label>ImageLoading</Label>
<PropertyName>ImageLoading</PropertyName>
</ListItem>
<ListItem>
<Label>Comment</Label>
<PropertyName>Comment</PropertyName>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
</ViewDefinitions>
</Configuration>
================================================
FILE: Format/Sysmon.Rule.Filter.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Sysmon.Rule.Filter</Name>
<ViewSelectedBy>
<TypeName>Sysmon.Rule.Filter</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>12</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>12</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>50</Width>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>EventField</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Condition</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Value</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
================================================
FILE: Format/Sysmon.Rule.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Sysmon.Rule</Name>
<ViewSelectedBy>
<TypeName>Sysmon.Rule</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<Label>EventType</Label>
<PropertyName>EventType</PropertyName>
</ListItem>
<ListItem>
<Label>Scope</Label>
<PropertyName>Scope</PropertyName>
</ListItem>
<ListItem>
<Label>DefaultAction</Label>
<PropertyName>DefaultAction</PropertyName>
</ListItem>
<ListItem>
<Label>Filters</Label>
<PropertyName>Filters</PropertyName>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
</ViewDefinitions>
</Configuration>
================================================
FILE: Functions/ConvertFrom-SysmonBinaryConfiguration.ps1
================================================
<#
.SYNOPSIS
Parses a binary Sysmon configuration.
.DESCRIPTION
ConvertFrom-SysmonBinaryConfiguration parses a binary Sysmon configuration. The configuration is typically stored in the registry at the following path: HKLM\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters\Rules
ConvertFrom-SysmonBinaryConfiguration currently only supports the following schema versions: 3.30, 3.40 and 4.0
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
.PARAMETER RuleBytes
Specifies the raw bytes of a Sysmon configuration from the registry.
.EXAMPLE
[Byte[]] $RuleBytes = Get-ItemPropertyValue -Path HKLM:\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters -Name Rules
ConvertFrom-SysmonBinaryConfiguration -RuleBytes $RuleBytes
.OUTPUTS
Sysmon.EventCollection
Output a fully-parsed rule object including the hash of the rules blob.
.NOTES
ConvertFrom-SysmonBinaryConfiguration is designed to serve as a helper function for Get-SysmonConfiguration.
#>
function ConvertFrom-SysmonBinaryConfiguration {
[OutputType('Sysmon.EventCollection')]
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[Byte[]]
[ValidateNotNullOrEmpty()]
$RuleBytes
)
#region Define byte to string mappings. This may change across verions.
$SupportedSchemaVersions = @(
[Version] '3.30.0.0',
[Version] '3.40.0.0',
[Version] '4.00.0.0'
)
$EventConditionMapping = @{
0 = 'Is'
1 = 'IsNot'
2 = 'Contains'
3 = 'Excludes'
4 = 'BeginWith'
5 = 'EndWith'
6 = 'LessThan'
7 = 'MoreThan'
8 = 'Image'
}
# The following value to string mappings were all pulled from
# IDA and will require manual validation with with each new
# Sysmon and schema version. Here's hoping they don't change often!
$ProcessCreateMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'CommandLine'
5 = 'CurrentDirectory'
6 = 'User'
7 = 'LogonGuid'
8 = 'LogonId'
9 = 'TerminalSessionId'
10 = 'IntegrityLevel'
11 = 'Hashes'
12 = 'ParentProcessGuid'
13 = 'ParentProcessId'
14 = 'ParentImage'
15 = 'ParentCommandLine'
}
$ProcessCreateMapping_4_00 = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'FileVersion'
5 = 'Description'
6 = 'Product'
7 = 'Company'
8 = 'CommandLine'
9 = 'CurrentDirectory'
10 = 'User'
11 = 'LogonGuid'
12 = 'LogonId'
13 = 'TerminalSessionId'
14 = 'IntegrityLevel'
15 = 'Hashes'
16 = 'ParentProcessGuid'
17 = 'ParentProcessId'
18 = 'ParentImage'
19 = 'ParentCommandLine'
}
$FileCreateTimeMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'TargetFilename'
5 = 'CreationUtcTime'
6 = 'PreviousCreationUtcTime'
}
$NetworkConnectMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'User'
5 = 'Protocol'
6 = 'Initiated'
7 = 'SourceIsIpv6'
8 = 'SourceIp'
9 = 'SourceHostname'
10 = 'SourcePort'
11 = 'SourcePortName'
12 = 'DestinationIsIpv6'
13 = 'DestinationIp'
14 = 'DestinationHostname'
15 = 'DestinationPort'
16 = 'DestinationPortName'
}
$SysmonServiceStateChangeMapping = @{
0 = 'UtcTime'
1 = 'State'
2 = 'Version'
3 = 'SchemaVersion'
}
$ProcessTerminateMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
}
$DriverLoadMapping = @{
0 = 'UtcTime'
1 = 'ImageLoaded'
2 = 'Hashes'
3 = 'Signed'
4 = 'Signature'
5 = 'SignatureStatus'
}
$ImageLoadMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'ImageLoaded'
5 = 'Hashes'
6 = 'Signed'
7 = 'Signature'
8 = 'SignatureStatus'
}
$ImageLoadMapping_4_00 = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'ImageLoaded'
5 = 'FileVersion'
6 = 'Description'
7 = 'Product'
8 = 'Company'
9 = 'Hashes'
10 = 'Signed'
11 = 'Signature'
12 = 'SignatureStatus'
}
$CreateRemoteThreadMapping = @{
0 = 'UtcTime'
1 = 'SourceProcessGuid'
2 = 'SourceProcessId'
3 = 'SourceImage'
4 = 'TargetProcessGuid'
5 = 'TargetProcessId'
6 = 'TargetImage'
7 = 'NewThreadId'
8 = 'StartAddress'
9 = 'StartModule'
10 = 'StartFunction'
}
$RawAccessReadMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'Device'
}
$ProcessAccessMapping = @{
0 = 'UtcTime'
1 = 'SourceProcessGUID'
2 = 'SourceProcessId'
3 = 'SourceThreadId'
4 = 'SourceImage'
5 = 'TargetProcessGUID'
6 = 'TargetProcessId'
7 = 'TargetImage'
8 = 'GrantedAccess'
9 = 'CallTrace'
}
$FileCreateMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'TargetFilename'
5 = 'CreationUtcTime'
}
$RegistryEventCreateKeyMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'ProcessGuid'
3 = 'ProcessId'
4 = 'Image'
5 = 'TargetObject'
}
$RegistryEventSetValueMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'ProcessGuid'
3 = 'ProcessId'
4 = 'Image'
5 = 'TargetObject'
6 = 'Details'
}
$RegistryEventDeleteKeyMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'ProcessGuid'
3 = 'ProcessId'
4 = 'Image'
5 = 'TargetObject'
6 = 'NewName'
}
$FileCreateStreamHashMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'Image'
4 = 'TargetFilename'
5 = 'CreationUtcTime'
6 = 'Hash'
}
$SysmonConfigurationChangeMapping = @{
0 = 'UtcTime'
1 = 'Configuration'
2 = 'ConfigurationFileHash'
}
$PipeEventCreatedMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'PipeName'
4 = 'Image'
}
$PipeEventConnectedMapping = @{
0 = 'UtcTime'
1 = 'ProcessGuid'
2 = 'ProcessId'
3 = 'PipeName'
4 = 'Image'
}
$WmiEventFilterMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'Operation'
3 = 'User'
4 = 'EventNamespace'
5 = 'Name'
6 = 'Query'
}
$WmiEventConsumerMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'Operation'
3 = 'User'
4 = 'Name'
5 = 'Type'
6 = 'Destination'
}
$WmiEventConsumerToFilterMapping = @{
0 = 'EventType'
1 = 'UtcTime'
2 = 'Operation'
3 = 'User'
4 = 'Consumer'
5 = 'Filter'
}
$EventTypeMapping = @{
1 = @('ProcessCreate', $ProcessCreateMapping)
2 = @('FileCreateTime', $FileCreateTimeMapping)
3 = @('NetworkConnect', $NetworkConnectMapping)
# SysmonServiceStateChange is not actually present in the schema. It is here for the sake of completeness.
4 = @('SysmonServiceStateChange', $SysmonServiceStateChangeMapping)
5 = @('ProcessTerminate', $ProcessTerminateMapping)
6 = @('DriverLoad', $DriverLoadMapping)
7 = @('ImageLoad', $ImageLoadMapping)
8 = @('CreateRemoteThread', $CreateRemoteThreadMapping)
9 = @('RawAccessRead', $RawAccessReadMapping)
10 = @('ProcessAccess', $ProcessAccessMapping)
11 = @('FileCreate', $FileCreateMapping)
12 = @('RegistryEventCreateKey', $RegistryEventCreateKeyMapping)
13 = @('RegistryEventSetValue', $RegistryEventSetValueMapping)
14 = @('RegistryEventDeleteKey', $RegistryEventDeleteKeyMapping)
15 = @('FileCreateStreamHash', $FileCreateStreamHashMapping)
# SysmonConfigurationChange is not actually present in the schema. It is here for the sake of completeness.
16 = @('SysmonConfigurationChange', $SysmonConfigurationChangeMapping)
17 = @('PipeEventCreated', $PipeEventCreatedMapping)
18 = @('PipeEventConnected', $PipeEventConnectedMapping)
19 = @('WmiEventFilter', $WmiEventFilterMapping)
20 = @('WmiEventConsumer', $WmiEventConsumerMapping)
21 = @('WmiEventConsumerToFilter', $WmiEventConsumerToFilterMapping)
}
#endregion
$RuleMemoryStream = New-Object -TypeName System.IO.MemoryStream -ArgumentList @(,$RuleBytes)
$RuleReader = New-Object -TypeName System.IO.BinaryReader -ArgumentList $RuleMemoryStream
# I'm noting here for the record that parsing could be slightly more robust to account for malformed
# rule blobs. I'm writing this in my spare time so I likely won't put too much work into increased
# parsing robustness.
if ($RuleBytes.Count -lt 16) {
$RuleReader.Dispose()
$RuleMemoryStream.Dispose()
throw 'Insufficient length to contain a Sysmon rule header.'
}
# This value should be either 0 or 1. 1 should be expected for a current Sysmon config.
# A value of 1 indicates that offset 8 will contain the file offset to the first rule grouping.
# A value of 0 should indicate that offset 8 will be the start of the first rule grouping.
# Currently, I am just going to check that the value is 1 and throw an exception if it's not.
$HeaderValue0 = $RuleReader.ReadUInt16()
if ($HeaderValue0 -ne 1) {
$RuleReader.Dispose()
$RuleMemoryStream.Dispose()
throw "Incorrect header value at offset 0x00. Expected: 1. Actual: $HeaderValue0"
}
# This value is expected to be 1. Any other value will indicate the presence of a "registry rule version"
# that is incompatible with the current Sysmon schema version. A value other than 1 likely indicates the
# presence of an old version of Sysmon. Any value besides 1 will not be supported in this script.
$HeaderValue1 = $RuleReader.ReadUInt16()
if ($HeaderValue1 -ne 1) {
$RuleReader.Dispose()
$RuleMemoryStream.Dispose()
throw "Incorrect header value at offset 0x02. Expected: 1. Actual: $HeaderValue1"
}
$RuleGroupCount = $RuleReader.ReadUInt32()
$RuleGroupBeginOffset = $RuleReader.ReadUInt32()
$SchemaVersionMinor = $RuleReader.ReadUInt16()
$SchemaVersionMajor = $RuleReader.ReadUInt16()
$SchemaVersion = New-Object -TypeName System.Version -ArgumentList $SchemaVersionMajor, $SchemaVersionMinor, 0, 0
Write-Verbose "Obtained the following schema version: $($SchemaVersion.ToString(2))"
if (-not ($SupportedSchemaVersions -contains $SchemaVersion)) {
$RuleReader.Dispose()
$RuleMemoryStream.Dispose()
throw "Unsupported schema version: $($SchemaVersion.ToString(2)). Schema version must be at least $($MinimumSupportedSchemaVersion.ToString(2))"
}
#region Perform offset updates depending upon the schema version here
# This logic should be the first candidate for refactoring should the schema change drastically in the future.
switch ($SchemaVersion.ToString(2)) {
'4.0' {
Write-Verbose 'Using schema version 4.00 updated offsets.'
# ProcessCreate and ImageLoad values changed
$EventTypeMapping[1][1] = $ProcessCreateMapping_4_00
$EventTypeMapping[7][1] = $ImageLoadMapping_4_00
}
}
#endregion
$null = $RuleReader.BaseStream.Seek($RuleGroupBeginOffset, 'Begin')
$EventCollection = for ($i = 0; $i -lt $RuleGroupCount; $i++) {
$EventTypeValue = $RuleReader.ReadInt32()
$EventType = $EventTypeMapping[$EventTypeValue][0]
$EventTypeRuleTypes = $EventTypeMapping[$EventTypeValue][1]
$OnMatchValue = $RuleReader.ReadInt32()
$OnMatch = $null
switch ($OnMatchValue) {
0 { $OnMatch = 'Exclude' }
1 { $OnMatch = 'Include' }
default { $OnMatch = '?' }
}
$NextEventTypeOffset = $RuleReader.ReadInt32()
$RuleCount = $RuleReader.ReadInt32()
[PSObject[]] $Rules = New-Object -TypeName PSObject[]($RuleCount)
# Parse individual rules here
for ($j = 0; $j -lt $RuleCount; $j++) {
$RuleType = $EventTypeRuleTypes[$RuleReader.ReadInt32()]
$Filter = $EventConditionMapping[$RuleReader.ReadInt32()]
$NextRuleOffset = $RuleReader.ReadInt32()
$RuleTextLength = $RuleReader.ReadInt32()
$RuleTextBytes = $RuleReader.ReadBytes($RuleTextLength)
$RuleText = [Text.Encoding]::Unicode.GetString($RuleTextBytes).TrimEnd("`0")
$Rules[$j] = [PSCustomObject] @{
PSTypeName = 'Sysmon.Rule'
RuleType = $RuleType
Filter = $Filter
RuleText = $RuleText
}
$null = $RuleReader.BaseStream.Seek($NextRuleOffset, 'Begin')
}
[PSCustomObject] @{
PSTypeName = 'Sysmon.EventGroup'
EventType = $EventType
OnMatch = $OnMatch
Rules = $Rules
}
$null = $RuleReader.BaseStream.Seek($NextEventTypeOffset, 'Begin')
}
$RuleReader.Dispose()
$RuleMemoryStream.Dispose()
# Calculate the hash of the binary rule blob
$SHA256Hasher = New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider
$ConfigBlobSHA256Hash = ($SHA256Hasher.ComputeHash($RuleBytes) | ForEach-Object { $_.ToString('X2') }) -join ''
[PSCustomObject] @{
PSTypeName = 'Sysmon.EventCollection'
SchemaVersion = $SchemaVersion
ConfigBlobSHA256Hash = $ConfigBlobSHA256Hash
Events = $EventCollection
}
}
================================================
FILE: Functions/ConvertTo-SysmonXMLConfiguration.ps1
================================================
<#
.SYNOPSIS
Recovers a Sysmon XML configuration from a binary configuration.
.DESCRIPTION
ConvertTo-SysmonXMLConfiguration takes the parsed output from Get-SysmonConfiguration and converts it to an XML configuration. This function is useful for recovering lost Sysmon configurations or for performing reconnaisance.
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: Get-SysmonConfiguration
GeneratedCode.ps1
.PARAMETER Configuration
Specifies the parsed Sysmon configuration output from Get-SysmonConfiguration.
.EXAMPLE
Get-SysmonConfiguration | ConvertTo-SysmonXMLConfiguration
.EXAMPLE
$Configuration = Get-SysmonConfiguration
ConvertTo-SysmonXMLConfiguration -Configuration $Configuration
.INPUTS
Sysmon.Configuration
ConvertTo-SysmonXMLConfiguration accepts a single result from Get-SysmonConfiguration over the pipeline. Note: it will not accept input from Get-SysmonConfiguration when "-MatchExeOutput" is specified.
.OUTPUTS
System.String
Outputs a Sysmon XML configuration document.
#>
function ConvertTo-SysmonXMLConfiguration {
[OutputType([String])]
[CmdletBinding()]
param (
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[PSTypeName('Sysmon.Configuration')]
$Configuration
)
$SchemaVersion = $Configuration.SchemaVersion
# Get the parsing code for the respective schema.
# Code injection note: an attacker would be able to influence the schema version used. That would only influence what
# non-injectible source code was supplied to Add-Type, however. $ConfigurationSchemaSource variables should always be
# constant variables with script (i.e. module) scope.
$SchemaSource = Get-Variable -Name "SysmonConfigSchemaSource_$($SchemaVersion.Replace('.', '_'))" -Scope Script -ValueOnly
# Compile the parsing code
Add-Type -TypeDefinition $SchemaSource -ReferencedAssemblies 'System.Xml' -ErrorAction Stop
$NamespaceName = "Sysmon_$($SchemaVersion.Replace('.', '_'))"
# Create a base "Sysmon" object. This serves as the root node that will eventually be serialized to XML.
$Sysmon = New-Object -TypeName "$NamespaceName.Sysmon"
$Sysmon.schemaversion = $Configuration.SchemaVersion
if ($Configuration.CRLCheckingEnabled) { $Sysmon.CheckRevocation = New-Object -TypeName "$NamespaceName.SysmonCheckRevocation" }
# The hashing algorithms need to be lower case in the XML config.
$Sysmon.HashAlgorithms = ($Configuration.HashingAlgorithms | ForEach-Object { $_.ToLower() }) -join ','
$ProcessAccessString = ($Configuration.ProcessAccess | ForEach-Object { "$($_.ProcessName):0x$($_.AccessMask.ToString('x'))" }) -join ','
if ($ProcessAccessString) { $Sysmon.ProcessAccessConfig = $ProcessAccessString }
# Do not consider redundant event types. A well-formed binary Sysmon rule blob will have
# identical RegistryEvent, PipeEvent, and WmiEvent rule entries as of config schema version 3.4[0]
$EventTypesToExclude = @(
'RegistryEventSetValue',
'RegistryEventDeleteKey',
'PipeEventConnected',
'WmiEventConsumer',
'WmiEventConsumerToFilter'
)
# Group rules by their respective event types - a requirement for
# setting properties properly in the SysmonEventFiltering instance.
$EventGrouping = $Configuration.Rules |
Where-Object { -not ($EventTypesToExclude -contains $_.EventType) } |
Group-Object -Property EventType
# A configuration can technically not have any EventFiltering rules.
if ($EventGrouping) {
$Sysmon.EventFiltering = New-Object -TypeName "$NamespaceName.SysmonEventFiltering"
foreach ($Event in $EventGrouping) {
# The name of the event - e.g. ProcessCreate, FileCreate, etc.
$EventName = $Event.Name
# Normalize these event names.
# Have a mentioned that I hate that these aren't unique names in Sysmon?
switch ($EventName) {
'RegistryEventCreateKey' { $EventName = 'RegistryEvent' }
'PipeEventCreated' { $EventName = 'PipeEvent' }
'WmiEventFilter' { $EventName = 'WmiEvent' }
}
if ($Event.Count -gt 2) {
Write-Error "There is more than two $EventName entries. This should not be possible."
return
}
if (($Event.Count -eq 2) -and ($Event.Group[0].OnMatch -eq $Event.Group[1].OnMatch)) {
Write-Error "The `"onmatch`" attribute values for the $EventName rules are not `"include`" and `"exclude`". This should not be possible."
return
}
$Events = foreach ($RuleSet in $Event.Group) {
# The dynamic typing that follows relies upon naming consistency in the schema serialization source code.
$EventInstance = New-Object -TypeName "$NamespaceName.SysmonEventFiltering$EventName" -Property @{
onmatch = $RuleSet.OnMatch.ToLower()
}
$RuleDefs = @{}
foreach ($Rule in $RuleSet.Rules) {
$PropertyName = $Rule.RuleType
# Since each property can be of a unique type, resolve it accordingly.
$PropertyTypeName = ("$NamespaceName.SysmonEventFiltering$EventName" -as [Type]).GetProperty($PropertyName).PropertyType.FullName.TrimEnd('[]')
if (-not $RuleDefs.ContainsKey($PropertyName)) {
$RuleDefs[$PropertyName] = New-Object -TypeName "Collections.ObjectModel.Collection``1[$PropertyTypeName]"
}
$RuleInstance = New-Object -TypeName $PropertyTypeName
# This needs to be lower case in the XML config.
$RuleInstance.condition = $Rule.Filter.ToLower()
# An exception is thrown here if the value has a space and it is being cast to an enum type.
# Currently, "Protected Process" is the only instance. I'll need to refactor this if more instances arise.
if ($Rule.RuleText -eq 'Protected Process') { $RuleInstance.Value = 'ProtectedProcess' } else { $RuleInstance.Value = $Rule.RuleText }
$RuleDefs[$PropertyName].Add($RuleInstance)
}
# Set the collected rule properties accordingly.
foreach ($PropertyName in $RuleDefs.Keys) {
$EventInstance."$PropertyName" = $RuleDefs[$PropertyName]
}
$EventInstance
}
$EventPropertyName = $Events[0].GetType().Name.Substring('SysmonEventFiltering'.Length)
$Sysmon.EventFiltering."$EventPropertyName" = $Events
}
}
$XmlWriter = $null
try {
$XmlWriterSetting = New-Object -TypeName Xml.XmlWriterSettings
# A Sysmon XML config is not expected to have an XML declaration line.
$XmlWriterSetting.OmitXmlDeclaration = $True
$XmlWriterSetting.Indent = $True
# Use two spaces in place of a tab character.
$XmlWriterSetting.IndentChars = ' '
# Normalize newlines to CRLF.
$XmlWriterSetting.NewLineHandling = [Xml.NewLineHandling]::Replace
$XMlStringBuilder = New-Object -TypeName Text.StringBuilder
$XmlWriter = [Xml.XmlWriter]::Create($XMlStringBuilder, $XmlWriterSetting)
$XmlSerializer = New-Object -TypeName Xml.Serialization.XmlSerializer -ArgumentList ("$NamespaceName.Sysmon" -as [Type]), ''
# This will strip any additional "xmlns" attributes from the root Sysmon element.
$EmptyNamespaces = New-Object -TypeName Xml.Serialization.XmlSerializerNamespaces
$EmptyNamespaces.Add('', '')
$XmlSerializer.Serialize($XmlWriter, $Sysmon, $EmptyNamespaces)
} catch {
Write-Error $_
} finally {
if ($XmlWriter) { $XmlWriter.Close() }
}
$XMlStringBuilder.ToString()
}
================================================
FILE: Functions/Get-SysmonConfiguration.ps1
================================================
<#
.SYNOPSIS
Parses a Sysmon driver configuration from the registry. Output is nearly identical to that of "sysmon.exe -c" but without the requirement to run sysmon.exe.
.DESCRIPTION
Get-SysmonConfiguration parses a Sysmon configuration from the registry without the need to run "sysmon.exe -c". This function is designed to enable Sysmon configuration auditing at scale as well as reconnaissance for red teamers.
Get-SysmonConfiguration has been tested with the following Sysmon versions: 6.20
Due to the admin-only ACL set on the Sysmon driver registry key, Get-SysmonConfiguration will typically need to run in an elevated context. Because the user-mode service and driver names can be changed, Get-SysmonConfiguration will locate the service and driver regardless of their names.
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: ConvertFrom-SysmonBinaryConfiguration
.PARAMETER MatchExeOutput
Mirrors the text output of "sysmon.exe -c". This parameter was implemented primarily to enable testing scenarios - i.e. to ensure that the output matches that of the version of Sysmon (or schema) being tested against.
.EXAMPLE
Get-SysmonConfiguration
.EXAMPLE
Get-SysmonConfiguration -MatchExeOutput
.OUTPUTS
Sysmon.Configuration
Outputs a fully parsed Sysmon configuration including the hash of the registry rule blob for auditing purposes.
System.String
Outputs mirrored output from "sysmon.exe -c".
.NOTES
Get-SysmonConfiguration will have to be manually validated for each new Sysmon and configuration schema version. Please report all bugs and indiscrepencies with new versions by supplying the following information:
1) The Sysmon config XML that's generating the error (only schema versions 3.30 and later).
2) The version of Sysmon being used (only 6.20 and later).
#>
function Get-SysmonConfiguration {
[OutputType('Sysmon.Configuration', ParameterSetName = 'PSOutput')]
[OutputType([String], ParameterSetName = 'ExeOutput')]
[CmdletBinding(DefaultParameterSetName = 'PSOutput')]
param (
[Parameter(ParameterSetName = 'ExeOutput')]
[Switch]
$MatchExeOutput
)
# Find the Sysmon driver based solely off the presence of the "Rules" value.
# This is being done because the user can optionally specify a driver name other than the default: SysmonDrv
$ServiceParameters = Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\Services -Recurse -Include 'Parameters' -ErrorAction SilentlyContinue
$DriverParameters = $ServiceParameters | Where-Object { $_.Property -contains 'Rules' }
if (-not $DriverParameters) {
Write-Error 'Unable to locate a Sysmon driver. Either it is not installed or you do not have permissions to read the driver configuration in the registry.'
return
}
$FoundSysmonMatch = $False
$SysmonDriverName = $null
$SysmonServiceName = $null
$SysmonDriverParams = $null
# Just in case there is more than one instance where there is a "Rules" value, correlate it with the user-mode service to confirm.
$DriverParameters | ForEach-Object {
$CandidateDriverName = $_.PSParentPath.Split('\')[-1]
$CandidateDriverParams = $_
$CandidateUserModeServices = $ServiceParameters | Where-Object { $_.Property -contains 'DriverName' }
if (-not $CandidateUserModeServices) {
Write-Error 'Unable to locate a user-mode Sysmon service.'
return
}
$CandidateUserModeServices | ForEach-Object {
$CandidateServiceName = $_.PSParentPath.Split('\')[-1]
$DriverName = ($_ | Get-ItemProperty).DriverName
# We have a matching user-mode Sysmon service and Sysmon driver.
if ($DriverName -eq $CandidateDriverName) {
$FoundSysmonMatch = $True
$SysmonDriverName = $CandidateDriverName
$SysmonServiceName = $CandidateServiceName
$SysmonDriverParams = $CandidateDriverParams | Get-ItemProperty
}
}
}
if ($FoundSysmonMatch) {
# HKLM\SYSTEM\CurrentControlSet\Services\<SYSMON_DRIVER_NAME>\Parameters
$RuleBytes = $SysmonDriverParams.Rules # REG_BINARY
$Options = $SysmonDriverParams.Options # REG_DWORD
$HashingAlgorithmValue = $SysmonDriverParams.HashingAlgorithm # REG_DWORD
$ProcessAccessMasks = $SysmonDriverParams.ProcessAccessMasks # REG_BINARY - No larger than size: 0x28 (0x28 / 4 == 10: unique masks to interpret alongside ProcessAccessNames)
$ProcessAccessNames = $SysmonDriverParams.ProcessAccessNames # REG_MULTI_SZ - Can have no more than 10 entries
$CheckRevocation = $SysmonDriverParams.CheckRevocation # REG_BINARY of size: 1 byte
# The high-order bit of HashingAlgorithm must be set to 1 (i.e. 0x80000000)
$HashingAlgorithms = if ($HashingAlgorithmValue) {
if ($HashingAlgorithmValue -band 1) { 'SHA1' }
if ($HashingAlgorithmValue -band 2) { 'MD5' }
if ($HashingAlgorithmValue -band 4) { 'SHA256' }
if ($HashingAlgorithmValue -band 8) { 'IMPHASH' }
}
$NetworkConnection = $False
if ($Options -band 1) { $NetworkConnection = $True }
$ImageLoading = $False
if ($Options -band 2) { $ImageLoading = $True }
$CRLChecking = $False
if (($CheckRevocation.Count -gt 0) -and ($CheckRevocation[0] -eq 1)) { $CRLChecking = $True }
# Parse the binary rules blob.
$Rules = ConvertFrom-SysmonBinaryConfiguration -RuleBytes $RuleBytes
$ProcessAccess = $False
if ($Rules.Events.EventType -contains 'ProcessAccess') { $ProcessAccess = $True }
# Process ProcessAccessNames and ProcessAccessMasks.
# The code path to actually use these appears to be a dead one now.
# I'm only parsing this to mirror Sysmon 6.20 supporting parsing.
$ProcessAccessList = New-Object -TypeName PSObject[]($ProcessAccessNames.Count)
for ($i = 0; $i -lt $ProcessAccessNames.Count; $i++) {
$ProcessAccessList[$i] = [PSCustomObject] @{
ProcessName = $ProcessAccessNames[$i]
AccessMask = [BitConverter]::ToInt32($ProcessAccessMasks, $i * 4)
}
}
$Properties = [Ordered] @{
PSTypeName = 'Sysmon.Configuration'
ServiceName = $SysmonServiceName
DriverName = $SysmonDriverName
HashingAlgorithms = $HashingAlgorithms
NetworkConnectionEnabled = $NetworkConnection
ImageLoadingEnabled = $ImageLoading
CRLCheckingEnabled = $CRLChecking
ProcessAccessEnabled = $ProcessAccess
ProcessAccess = $ProcessAccessList
SchemaVersion = $Rules.SchemaVersion.ToString(2)
ConfigBlobSHA256Hash = $Rules.ConfigBlobSHA256Hash
Rules = $Rules.Events
}
# Don't print the ProcessAccess property if it's not populated. With Sysmon 6.20, this
# should never be present anyway unless there's a stale artifact from an older version.
if ($ProcessAccessList.Count -eq 0) { $Properties.Remove('ProcessAccess') }
if ($MatchExeOutput) {
$NetworkConnectionString = if ($NetworkConnection) { 'enabled' } else { 'disabled' }
$ImageLoadingString = if ($ImageLoading) { 'enabled' } else { 'disabled' }
$CRLCheckingString = if ($CRLChecking) { 'enabled' } else { 'disabled' }
$ProcessAccessString = if ($ProcessAccess) { 'enabled' } else { 'disabled' }
if ($ProcessAccessList) {
$ProcessAccessString = ($ProcessAccessList | ForEach-Object { "`"$($_.ProcessName)`":0x$($_.AccessMask.ToString('x'))" }) -join ','
}
$AllRuleText = $Rules.Events | ForEach-Object {
# Dumb hacks to format output to the original "sysmon.exe -c" output
$EventType = $_.EventType
if ($EventType.StartsWith('RegistryEvent')) { $EventType = 'RegistryEvent' }
if ($EventType.StartsWith('WmiEvent')) { $EventType = 'WmiEvent' }
if ($EventType.StartsWith('PipeEvent')) { $EventType = 'PipeEvent' }
$RuleText = $_.Rules | ForEach-Object {
$FilterText = switch ($_.Filter) {
'Is' { 'is' }
'IsNot' { 'is not' }
'Contains' { 'contains' }
'Excludes' { 'excludes' }
'BeginWith' { 'begin with' }
'EndWith' { 'end with' }
'LessThan' { 'less than' }
'MoreThan' { 'more than' }
'Image' { 'image' }
}
"`t{0,-30} filter: {1,-12} value: '{2}'" -f $_.RuleType, $FilterText, $_.RuleText
}
$RuleSet = @"
- {0,-34} onmatch: {1}
{2}
"@ -f $EventType,
$_.OnMatch.ToLower(),
($RuleText | Out-String).TrimEnd("`r`n")
$RuleSet.TrimEnd("`r`n")
}
$ConfigOutput = @"
Current configuration:
{0,-34}{1}
{2,-34}{3}
{4,-34}{5}
{6,-34}{7}
{8,-34}{9}
{10,-34}{11}
{12,-34}{13}
Rule configuration (version {14}):
{15}
"@ -f ' - Service name:',
$SysmonServiceName,
' - Driver name:',
$SysmonDriverName,
' - HashingAlgorithms:',
($HashingAlgorithms -join ','),
' - Network connection:',
$NetworkConnectionString,
' - Image loading:',
$ImageLoadingString,
' - CRL checking:',
$CRLCheckingString,
' - Process Access:',
$ProcessAccessString,
"$($Rules.SchemaVersion.Major).$($Rules.SchemaVersion.Minor.ToString().PadRight(2, '0'))",
($AllRuleText | Out-String).TrimEnd("`r`n")
$ConfigOutput
} else {
[PSCustomObject] $Properties
}
} else {
Write-Error 'Unable to locate a Sysmon driver and user-mode service.'
}
}
================================================
FILE: Functions/Get-SysmonEventData.ps1
================================================
<#
.Synopsis
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.DESCRIPTION
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.EXAMPLE
Get-SysMonEventData -EventId 1 -MaxEvents 10 -EndTime (Get-Date) -StartTime (Get-Date).AddDays(-1)
All process creation events in the last 24hr
.EXAMPLE
Get-SysMonEventData -EventId 3 -MaxEvents 20 -Path .\export.evtx
last 20 network connection events from a exported SysMon log.
#>
function Get-SysmonEventData {
[CmdletBinding(DefaultParameterSetName='ID',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonEventData.md')]
Param (
# Sysmon Event ID of records to show
[Parameter(Mandatory=$true,
ParameterSetName='ID',
ValueFromPipelineByPropertyName=$true,
Position=0)]
[ValidateSet(1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255)]
[Int32[]]
$EventId,
# EventType that a Rule can be written against.
[Parameter(Mandatory=$false,
ParameterSetName='Type',
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string[]]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad',
'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess', 'Error',
'FileCreateStreamHash', 'RegistryValueSet', 'RegistryRename',
'RegistryAddOrDelete', 'FileCreate','ConfigChange','PipeCreated',
'PipeConnected', 'WmiFilter', 'WmiConsumer', 'WmiBinding',
'DnsEvent', 'FileDelete', 'ClipboardChange', 'ProcessTampering')]
$EventType,
# Specifies the maximum number of events that Get-WinEvent returns. Enter an integer. The default is to return all the events in the logs or files.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[int]
$MaxEvents,
# Specifies a path to one or more exported SysMon events in evtx format.
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
HelpMessage='Path to one or more locations.')]
[Alias('PSPath')]
[ValidateNotNullOrEmpty()]
[string[]]
$Path,
# Start Date to get all event going forward.
[Parameter(Mandatory=$false)]
[datetime]
$StartTime,
# End data for searching events.
[Parameter(Mandatory=$false)]
[datetime]
$EndTime
)
Begin
{
$EventTypeMap = @{
ProcessCreate = 1
FileCreateTime = 2
NetworkConnect = 3
ProcessTerminate = 5
DriverLoad = 6
ImageLoad = 7
CreateRemoteThread = 8
RawAccessRead = 9
ProcessAccess = 10
FileCreate = 11
RegistryAddOrDelete = 12
RegistryValueSet = 13
RegistryRename = 14
FileCreateStreamHash = 15
ConfigChange = 16
PipeCreated = 17
PipeConnected = 18
WmiFilter = 19
WmiConsumer = 20
WmiBinding = 21
DnsEvent = 22
FileDelete = 23
ClipboardChange = 24
ProcessTampering = 25
Error = 255
}
$EventIdtoType = @{
'1' = 'ProcessCreate'
'2' = 'FileCreateTime'
'3' = 'NetworkConnect'
'5' = 'ProcessTerminate'
'6' = 'DriverLoad'
'7' = 'ImageLoad'
'8' = 'CreateRemoteThread'
'9' = 'RawAccessRead'
'10' = 'ProcessAccess'
'11' = 'FileCreate'
'12' = 'RegistryAddOrDelete'
'13' = 'RegistryValueSet'
'14' = 'RegistryRename'
'15' = 'FileCreateStreamHash'
'16' = 'ConfigChange'
'17' = 'PipeCreated'
'18' = 'PipeConnected'
'19' = 'WmiFilter'
'20' = 'WmiConsumer'
'21' = 'WmiBinding'
'22' = 'DnsEvent'
'23' = 'FileDelete'
'24' = 'ClipboardChange'
'25' = 'ProcessTampering'
'255' = 'Error'
}
}
Process
{
# Hash for filtering
$HashFilter = @{LogName='Microsoft-Windows-Sysmon/Operational'}
# Hash for command paramteters
$ParamHash = @{}
if ($MaxEvents -gt 0)
{
$ParamHash.Add('MaxEvents', $MaxEvents)
}
if ($Path -gt 0)
{
$ParamHash.Add('Path', $Path)
}
switch ($PSCmdlet.ParameterSetName) {
'ID' { $HashFilter.Add('Id', $EventId) }
'Type' {
$EventIds = @()
foreach ($etype in $EventType)
{
$EventIds += $EventTypeMap[$etype]
}
$HashFilter.Add('Id', $EventIds)
}
}
if ($StartTime)
{
$HashFilter.Add('StartTime', $StartTime)
}
if ($EndTime)
{
$HashFilter.Add('EndTime', $EndTime)
}
$ParamHash.Add('FilterHashTable',$HashFilter)
Get-WinEvent @ParamHash | ForEach-Object {
[xml]$evtxml = $_.toxml()
$ProcInfo = [ordered]@{}
$ProcInfo['EventId'] = $evtxml.Event.System.EventID
$ProcInfo['EventType'] = $EventIdtoType[$evtxml.Event.System.EventID]
$ProcInfo['Computer'] = $evtxml.Event.System.Computer
$evtxml.Event.EventData.Data | ForEach-Object {
$ProcInfo[$_.name] = $_.'#text'
}
New-Object psobject -Property $ProcInfo
}
}
End {}
}
================================================
FILE: Functions/Get-SysmonHashingAlgorithm.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonHashingAlgorithm
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonHashingAlgorithm.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[string]$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
[string]$LiteralPath
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path' {[xml]$Config = Get-Content -Path $Path}
'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
}
}
catch [System.Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
$ObjOptions = @{}
if ($Config.Sysmon.SelectSingleNode('//HashAlgorithms'))
{
$ObjOptions['Hashing'] = $config.Sysmon.HashAlgorithms
}
else
{
$ObjOptions['Hashing'] = ''
}
#$ObjOptions['Comment'] = $Config.'#comment'
$ConfigObj = [pscustomobject]$ObjOptions
$ConfigObj.pstypenames.insert(0,'Sysmon.HashingAlgorithm')
$ConfigObj
}
End{}
}
================================================
FILE: Functions/Get-SysmonRule.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonRule
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRule.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[string]$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
[string]$LiteralPath,
# Event type to parse rules for.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('ALL', 'NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'ProcessAccess',
'RawAccessRead','ProcessAccess', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
[string[]]
$EventType = @('ALL')
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path' {[xml]$Config = Get-Content -Path $Path}
'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
}
}
catch [System.Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
{
Write-Error -Message 'This version of Sysmon Rule file is not supported.'
return
}
# Collect all individual rules if they exist.
$Rules = $Config.Sysmon.EventFiltering
if ($EventType -contains 'ALL')
{
$TypesToParse = @('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad','CreateRemoteThread',
'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')
}
else
{
$TypesToParse = $EventType
}
foreach($Type in $TypesToParse)
{
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
$RuleData = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
if($RuleData -ne $null)
{
Write-Verbose -Message "$($EvtType) Rule Found."
Get-RuleWithFilter($RuleData)
}
}
}
End{}
}
================================================
FILE: Functions/Get-SysmonRuleFilter.ps1
================================================
<#
.SYNOPSIS
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.DESCRIPTION
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.EXAMPLE
C:\PS> Get-SysmonRuleFilter -Path C:\sysmon.xml -EventType ProcessCreate
Get the filter under the ProcessCreate Rule.
#>
function Get-SysmonRuleFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRuleFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type rule to get filter for.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad',
'CreateRemoteThread','RawAccessRead', 'ProcessAccess',
'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
'PipeEvent', 'WmiEvent','RuleName')]
[string]
$EventType,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch
)
Begin{}
Process {
$EvtType = $null
# Check if the file is a valid XML file and if not raise and error.
try {
switch($psCmdlet.ParameterSetName){
'Path'{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath' {
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [System.Management.Automation.PSInvalidCastException] {
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null){
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
$Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')
if ($Rules -eq '') {
Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
return
} else {
$EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]
$EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
}
if($EventRule -eq $null) {
Write-Error -Message "No rule for $($EvtType) was found."
return
} else {
if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
Write-Verbose -Message 'Single Node'
if ($EventRule.onmatch -eq $OnMatch) {
$Filters = $EventRule.SelectNodes('*')
if ($Filters.ChildNodes.Count -gt 0) {
foreach($Filter in $Filters) {
$FilterObjProps = @{}
$FilterObjProps['EventField'] = $Filter.Name
$FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
$FilterObjProps['Value'] = $Filter.'#text'
$FilterObjProps['EventType'] = $EvtType
$FilterObjProps['OnMatch'] = $OnMatch
$FilterObj = [pscustomobject]$FilterObjProps
$FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
$FilterObj
}
}
}
}
else
{
Write-Verbose -Message 'Mutiple nodes.'
foreach ($rule in $EventRule)
{
if ($rule.onmatch -eq $OnMatch)
{
$Filters = $rule.SelectNodes('*')
if ($Filters.ChildNodes.Count -gt 0)
{
foreach($Filter in $Filters)
{
$FilterObjProps = @{}
$FilterObjProps['EventField'] = $Filter.Name
$FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
$FilterObjProps['Value'] = $Filter.'#text'
$FilterObjProps['EventType'] = $EvtType
$FilterObjProps['OnMatch'] = $OnMatch
$FilterObj = [pscustomobject]$FilterObjProps
$FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
$FilterObj
}
}
}
}
}
}
}
End{}
}
================================================
FILE: Functions/New-SysmonConfiguration.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonConfiguration
{
[CmdletBinding(HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonConfiguration.md')]
Param
(
# Path to write XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String]
$Path,
# Specify one or more hash algorithms used for image identification
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
[string[]]
$HashingAlgorithm,
# Log Network Connections
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[Switch]
$NetworkConnect,
# Log process loading of modules.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[Switch]
$DriverLoad,
# Log process loading of modules.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[Switch]
$ImageLoad,
# Log create remote thread actions.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=5)]
[Switch]
$CreateRemoteThread,
# Log file creation time modifications.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=6)]
[Switch]
$FileCreateTime,
# Log process creation.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=7)]
[Switch]
$ProcessCreate,
# Log process termination.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=8)]
[Switch]
$ProcessTerminate,
# Log when a running process opens another process.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=9)]
[Switch]
$ProcessAccess,
# Log raw access reads of files.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=10)]
[Switch]
$RawAccessRead,
# Check for signature certificate revocation.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=11 )]
[Switch]
$CheckRevocation,
# Log Registry events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=12 )]
[Switch]
$RegistryEvent,
# Log File Creation events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=13 )]
[Switch]
$FileCreate,
# Log File Stream creations events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=14 )]
[Switch]
$FileCreateStreamHash,
# Log NamedPipes connection and creations events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=15 )]
[Switch]
$PipeEvent,
# WMI Permanent Event component events.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true,
Position=16 )]
[Switch]
$WmiEvent,
# Comment for purpose of the configuration file.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true)]
[String]
$Comment,
# Schema Vesion for the configuration file, default is 4.1.
[Parameter(Mandatory=$False,
ValueFromPipelineByPropertyName=$true)]
[ValidateSet('4.0','4.1')]
[string]
$SchemaVersion = '4.1'
)
Begin{}
Process {
if ($HashingAlgorithm -contains 'ALL') {
$Hash = '*'
} else {
$Hash = $HashingAlgorithm -join ','
}
$Config = ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path))
# get an XMLTextWriter to create the XML
$XmlWriter = New-Object System.XMl.XmlTextWriter($Config,$Null)
# choose a pretty formatting:
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = 1
# write the header
if ($Comment)
{
$xmlWriter.WriteComment($Comment)
}
$xmlWriter.WriteStartElement('Sysmon')
$XmlWriter.WriteAttributeString('schemaversion', $SchemaVersion)
Write-Verbose -Message "Enabling hashing algorithms : $($Hash)"
$xmlWriter.WriteElementString('HashAlgorithms',$Hash)
# Enable checking revocation.
if ($CheckRevocation) {
Write-Verbose -message 'Enabling CheckRevocation.'
$xmlWriter.WriteElementString('CheckRevocation','')
}
# Create empty EventFiltering section.
$xmlWriter.WriteStartElement('EventFiltering')
if ($NetworkConnect) {
Write-Verbose -Message 'Enabling network connection logging for all connections by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('NetworkConnect')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($DriverLoad) {
Write-Verbose -Message 'Enabling logging all driver loading by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('DriverLoad ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ImageLoad) {
Write-Verbose -Message 'Enabling logging all image loading by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ImageLoad ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($CreateRemoteThread) {
Write-Verbose -Message 'Enabling logging all CreateRemoteThread API actions by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('CreateRemoteThread ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessCreate) {
Write-Verbose -Message 'Enabling logging all process creation by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessCreate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessTerminate) {
Write-Verbose -Message 'Enabling logging all process termination by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessTerminate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($FileCreateTime) {
Write-Verbose -Message 'Enabling logging all process creation by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('FileCreateTime ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($ProcessAccess) {
Write-Verbose -Message 'Enabling logging all process access by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('ProcessAccess ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
if ($RawAccessRead) {
Write-Verbose -Message 'Enabling logging all process access by setting no filter and onmatch to exclude.'
$xmlWriter.WriteStartElement('RawAccessRead ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# Log registry events.
if ($RegistryEvent) {
Write-Verbose -message 'Enabling RegistryEvent.'
$xmlWriter.WriteStartElement('RegistryEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# Log file create events.
if ($FileCreate) {
Write-Verbose -message 'Enabling FileCreate.'
$xmlWriter.WriteStartElement('FileCreate ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# Log file create events.
if ($FileCreateStreamHash) {
Write-Verbose -message 'Enabling FileCreateStreamHash.'
$xmlWriter.WriteStartElement('FileCreateStreamHash ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# NamedPipes create and connect events.
if ($PipeEvent) {
Write-Verbose -message 'Enabling PipeEvent.'
$xmlWriter.WriteStartElement('PipeEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# NamedPipes create and connect events.
if ($WmiEvent) {
Write-Verbose -message 'Enabling WmiEvent.'
$xmlWriter.WriteStartElement('WmiEvent ')
$XmlWriter.WriteAttributeString('onmatch', 'exclude')
$xmlWriter.WriteFullEndElement()
}
# End Element of EventFiltering
$xmlWriter.WriteFullEndElement()
# Sysmon
$xmlWriter.WriteEndElement()
# finalize the document:
#$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()
Write-Verbose -Message "Config file created as $($Config)"
write-verbose -Message "Configuration is for Sysmon $($sysmonVerMap[$SchemaVersion])"
}
End {}
}
================================================
FILE: Functions/New-SysmonCreateRemoteThreadFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonCreateRemoteThreadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonCreateRemoteThreadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('SourceImage', 'TargetImage')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin { }
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'CreateRemoteThread'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonDriverLoadFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonDriverLoadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonDriverLoadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ImageLoaded',
'Hashes', 'Signed', 'Signature')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'DriverLoad'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonFileCreateFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonFileCreateFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'TargetFilename', 'CreationUtcTime',
'PreviousCreationUtcTime')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'FileCreateStreamHash'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonFileCreateStreamHashFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of the saving of data on a file stream.
.DESCRIPTION
Create a new filter for the logging of the saving of data on a file stream.
#>
function New-SysmonFileCreateStreamHashFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateStreamHashFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
'Image')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'FileCreateStreamHash'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonImageLoadFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonImageLoadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonImageLoadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'ImageLoaded', 'Hashes', 'Signed',
'Signature', 'FileVersion',
'Description', 'Product', 'Company')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process
{
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$ConfigVer = Select-Xml -Path $Path -XPath '//Sysmon/@schemaversion'
}
'LiteralPath'
{
$ConfigVer = Select-Xml -LiteralPath $LiteralPath -XPath '//Sysmon/@schemaversion'
}
}
if ($ConfigVer.Node."#text" -lt 4.0 -and ($EventField -in @('FileVersion','Description', 'Product', 'Company'))) {
Write-Error -Message "The event field $($EventField) is not supported under this schema."
Return
}
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ImageLoad'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath'
{
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End { }
}
================================================
FILE: Functions/New-SysmonNetworkConnectFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonNetworkConnectFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonNetworkConnectFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'User', 'Protocol', 'Initiated', 'SourceIsIpv6',
'SourceIp', 'SourceHostname', 'SourcePort',
'SourcePortName', 'DestinationIsIpv6',
'DestinationIp', 'DestinationHostname',
'DestinationPort', 'DestinationPortName')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'NetworkConnect'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonPipeFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for when a Named Pipe is created or connected.
.DESCRIPTION
Create a new filter for when a Named Pipe is created or connected.
Useful for watching malware inter process communication.
#>
function New-SysmonPipeFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonPipeFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('Pipe', 'ProcessGuid', 'ProcessId',
'Image')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'PipeEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonProcessAccessFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of when a running process opens another.
.DESCRIPTION
Create a new filter for the logging of when a running process opens another.
.EXAMPLE
C:\PS> New-SysmonProcessAccessFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField TargetImage lsass.exe
Log any process trying to open lsass.exe.
#>
function New-SysmonProcessAccessFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessAccessFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'SourceProcessGUID',
'SourceProcessId', 'SourceThreadId', 'SourceImage',
'TargetProcessGUID', 'TargetProcessId', 'TargetImage',
'GrantedAccess','CallTrace')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessAccess'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonProcessCreateFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessCreateFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessCreateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
'CommandLine', 'User', 'LogonGuid', 'LogonId',
'TerminalSessionId', 'IntegrityLevel',
'Hashes', 'ParentProcessGuid', 'ParentProcessId',
'ParentImage', 'ParentCommandLine', 'FileVersion',
'Description', 'Product', 'Company')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$ConfigVer = Select-Xml -Path $Path -XPath '//Sysmon/@schemaversion'
}
'LiteralPath'
{
$ConfigVer = Select-Xml -LiteralPath $LiteralPath -XPath '//Sysmon/@schemaversion'
}
}
if ($ConfigVer.Node."#text" -lt 4.0 -and ($EventField -in @('FileVersion','Description', 'Product', 'Company'))) {
Write-Error -Message "The event field $($EventField) is not supported under this schema."
Return
}
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessCreate'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End { }
}
================================================
FILE: Functions/New-SysmonProcessTerminateFilter.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessTerminateFilter
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessTerminateFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process
{
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'ProcessTerminate'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch($psCmdlet.ParameterSetName)
{
'Path'
{
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath'
{
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonRawAccessReadFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of file raw access read actions.
.DESCRIPTION
Create a new filter for the logging of file raw access read actions.
.EXAMPLE
C:\PS> New-SysmonRawAccessReadFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField Image NTDS.dit
Log any raw access read of the file NTDS.dit.
#>
function New-SysmonRawAccessReadFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRawAccessReadFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId',
'Image', 'Device')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'RawAccessRead'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonRegistryFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the actions against the registry.
.DESCRIPTION
Create a new filter for actions against the registry. Supports filtering
by aby of the following event types:
* CreateKey
* DeleteKey
* RenameKey
* CreateValue
* DeleteValue
* RenameValue
* SetValue
Hives on Schema 3.2 in TargetObject are referenced as:
* \REGISTRY\MACHINE\HARDWARE
* \REGISTRY\USER\Security ID number
* \REGISTRY\MACHINE\SECURITY
* \REGISTRY\USER\.DEFAULT
* \REGISTRY\MACHINE\SYSTEM
* \REGISTRY\MACHINE\SOFTWARE
* \REGISTRY\MACHINE\SAM
Hives on Schema 3.3 and above in TargetObject are referenced as:
* HKLM
* HKCR
* HKEY_USER
.EXAMPLE
C:\PS> New-SysmonRegistryFilter -Path .\32config.xml -OnMatch include -Condition Contains -EventField TargetObject 'RunOnce'
Capture persistance attemp by creating a registry entry in the RunOnce keys.
#>
function New-SysmonRegistryFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRegistryFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({ Test-Path -Path $_ })]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('TargetObject', 'ProcessGuid', 'ProcessId',
'Image', 'EventType')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {
# Event types used to validate right type and string case
$EventTypeMap = @{
CreateKey = 'CreateKey'
DeleteKey = 'DeleteKey'
RenameKey = 'RenameKey'
CreateValue = 'CreateValue'
DeleteValue = 'DeleteValue'
RenameValue = 'RenameValue'
SetValue = 'SetValue'
}
$Etypes = $EventTypeMap.Keys
}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
if ($EventField -in 'EventType') {
if ($Value -in $Etypes) {
$Value = $EventTypeMap[$Value]
} else {
Write-Error -Message "Not a supported EventType. Supported Event types $($Etypes -join ', ')"
return
}
}
$cmdoptions = @{
'EventType' = 'RegistryEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/New-SysmonWmiFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for WMI Permamanent Event Classes.
.DESCRIPTION
Create a new filter for WMI permamanent event classes are created or connected.
Useful for monitoring for persistence actions.
#>
function New-SysmonWmiFilter {
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonWmiFilter.md')]
Param (
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type on match action.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('include', 'exclude')]
[string]
$OnMatch,
# Condition for filtering against and event field.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
[string]
$Condition,
# Event field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=3)]
[ValidateSet('Name', 'EventNamespace', 'Destination',
'Type', 'Query', 'Operation', 'Consumer', 'Filter')]
[string]
$EventField,
# Value of Event Field to filter on.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=4)]
[string[]]
$Value,
# Rule Name for the filter.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true)]
[string]
$RuleName
)
Begin {}
Process {
$FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
$cmdoptions = @{
'EventType' = 'WmiEvent'
'Condition' = $Condition
'EventField' = $FieldString
'Value' = $Value
'OnMatch' = $OnMatch
}
if($RuleName) {
$cmdoptions.Add('RuleName',$RuleName)
}
switch ($PSCmdlet.ParameterSetName) {
'Path' {
$cmdOptions.Add('Path',$Path)
New-RuleFilter @cmdOptions
}
'LiteralPath' {
$cmdOptions.Add('LiteralPath',$LiteralPath)
New-RuleFilter @cmdOptions
}
}
}
End {}
}
================================================
FILE: Functions/Remove-SysmonRule.ps1
================================================
# .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRule
{
[CmdletBinding(DefaultParameterSetName = 'Path',
HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRule.md')]
Param
(
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='Path',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
$Path,
# Path to XML config file.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
ParameterSetName='LiteralPath',
Position=0)]
[ValidateScript({Test-Path -Path $_})]
[Alias('PSPath')]
$LiteralPath,
# Event type to remove. It is case sensitive.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent','RuleName')]
[string[]]
$EventType,
# Action for event type rule and filters.
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=2)]
[ValidateSet('Include', 'Exclude')]
[String]
$OnMatch = 'Exclude'
)
Begin{}
Process
{
# Check if the file is a valid XML file and if not raise and error.
try
{
switch($psCmdlet.ParameterSetName)
{
'Path'
{
[xml]$Config = Get-Content -Path $Path
$FileLocation = (Resolve-Path -Path $Path).Path
}
'LiteralPath'
{
[xml]$Config = Get-Content -LiteralPath $LiteralPath
$FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
}
}
}
catch [Management.Automation.PSInvalidCastException]
{
Write-Error -Message 'Specified file does not appear to be a XML file.'
return
}
# Validate the XML file is a valid Sysmon file.
if ($Config.SelectSingleNode('//Sysmon') -eq $null)
{
Write-Error -Message 'XML file is not a valid Sysmon config file.'
return
}
if (
gitextract_jqcvzr7i/
├── .gitattributes
├── Config.ps1
├── Filters.ps1
├── Format/
│ ├── Sysmon.ConfigOption.ps1xml
│ ├── Sysmon.Rule.Filter.ps1xml
│ └── Sysmon.Rule.ps1xml
├── Functions/
│ ├── ConvertFrom-SysmonBinaryConfiguration.ps1
│ ├── ConvertTo-SysmonXMLConfiguration.ps1
│ ├── Get-SysmonConfiguration.ps1
│ ├── Get-SysmonEventData.ps1
│ ├── Get-SysmonHashingAlgorithm.ps1
│ ├── Get-SysmonRule.ps1
│ ├── Get-SysmonRuleFilter.ps1
│ ├── New-SysmonConfiguration.ps1
│ ├── New-SysmonCreateRemoteThreadFilter.ps1
│ ├── New-SysmonDriverLoadFilter.ps1
│ ├── New-SysmonFileCreateFilter.ps1
│ ├── New-SysmonFileCreateStreamHashFilter.ps1
│ ├── New-SysmonImageLoadFilter.ps1
│ ├── New-SysmonNetworkConnectFilter.ps1
│ ├── New-SysmonPipeFilter.ps1
│ ├── New-SysmonProcessAccessFilter.ps1
│ ├── New-SysmonProcessCreateFilter.ps1
│ ├── New-SysmonProcessTerminateFilter.ps1
│ ├── New-SysmonRawAccessReadFilter.ps1
│ ├── New-SysmonRegistryFilter.ps1
│ ├── New-SysmonWmiFilter.ps1
│ ├── Remove-SysmonRule.ps1
│ ├── Remove-SysmonRuleFilter.ps1
│ ├── Schemas/
│ │ ├── SysmonConfigurationSchema_3_40.xsd
│ │ └── SysmonConfigurationSchema_4_00.xsd
│ ├── Set-SysmonHashingAlgorithm.ps1
│ └── Set-SysmonRule.ps1
├── LICENSE
├── Posh-SysMon.psm1
├── Posh-Sysmon.psd1
├── README.md
├── build.ps1
├── docs/
│ ├── Get-SysmonEventData.md
│ ├── Get-SysmonHashingAlgorithm.md
│ ├── Get-SysmonRule.md
│ ├── Get-SysmonRuleFilter.md
│ ├── New-SysmonConfiguration.md
│ ├── New-SysmonDriverLoadFilter.md
│ ├── New-SysmonFileCreateFilter.md
│ ├── New-SysmonFileCreateStreamHash.md
│ ├── New-SysmonFileCreateStreamHashFilter.md
│ ├── New-SysmonImageLoadFilter.md
│ ├── New-SysmonNetworkConnectFilter.md
│ ├── New-SysmonPipeEvent.md
│ ├── New-SysmonPipeFilter.md
│ ├── New-SysmonProcessAccessFilter.md
│ ├── New-SysmonProcessCreateFilter.md
│ ├── New-SysmonProcessTerminateFilter.md
│ ├── New-SysmonRegistryEvent.md
│ ├── New-SysmonRegistryFilter.md
│ ├── Remove-SysmonRule.md
│ ├── Remove-SysmonRuleFilter.md
│ ├── Set-SysmonHashingAlgorithm.md
│ └── Set-SysmonRule.md
├── en-US/
│ ├── Posh-SysMon-help.xml
│ └── Posh-SysMon.psm1-Help.xml
└── lib/
├── sysmon3_1.dtd
├── sysmon3_2.dtd
└── sysmon3_3.dtd
Condensed preview — 65 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (881K chars).
[
{
"path": ".gitattributes",
"chars": 556,
"preview": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs diff=csharp\n*.sln"
},
{
"path": "Config.ps1",
"chars": 30907,
"preview": "\n# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonConfiguration\n{\n [CmdletBinding(HelpUri = 'https://gi"
},
{
"path": "Filters.ps1",
"chars": 57322,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonImageLoadFilter {\n [CmdletBinding(DefaultParameterSetN"
},
{
"path": "Format/Sysmon.ConfigOption.ps1xml",
"chars": 1141,
"preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n <Name>Sysmon.ConfigOption</Name>\n "
},
{
"path": "Format/Sysmon.Rule.Filter.ps1xml",
"chars": 1137,
"preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n <Name>Sysmon.Rule.Filter</Name>\n "
},
{
"path": "Format/Sysmon.Rule.ps1xml",
"chars": 1127,
"preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n <Name>Sysmon.Rule</Name>\n <View"
},
{
"path": "Functions/ConvertFrom-SysmonBinaryConfiguration.ps1",
"chars": 14443,
"preview": "<#\n.SYNOPSIS\n\nParses a binary Sysmon configuration.\n\n.DESCRIPTION\n\nConvertFrom-SysmonBinaryConfiguration parses a binary"
},
{
"path": "Functions/ConvertTo-SysmonXMLConfiguration.ps1",
"chars": 8060,
"preview": "<#\n.SYNOPSIS\n\nRecovers a Sysmon XML configuration from a binary configuration.\n\n.DESCRIPTION\n\nConvertTo-SysmonXMLConfigu"
},
{
"path": "Functions/Get-SysmonConfiguration.ps1",
"chars": 10129,
"preview": "<#\n.SYNOPSIS\n\nParses a Sysmon driver configuration from the registry. Output is nearly identical to that of \"sysmon.exe "
},
{
"path": "Functions/Get-SysmonEventData.ps1",
"chars": 5924,
"preview": "<#\n.Synopsis\nSearches for specified SysMon Events and retunrs the Event Data as a custom object.\n.DESCRIPTION\nSearches f"
},
{
"path": "Functions/Get-SysmonHashingAlgorithm.ps1",
"chars": 2326,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Get-SysmonHashingAlgorithm\n{\n [CmdletBinding(DefaultParameterSetN"
},
{
"path": "Functions/Get-SysmonRule.ps1",
"chars": 3376,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Get-SysmonRule\n{\n [CmdletBinding(DefaultParameterSetName = 'Path'"
},
{
"path": "Functions/Get-SysmonRuleFilter.ps1",
"chars": 5764,
"preview": "<#\n.SYNOPSIS\nGet the configured filters for a specified Event Type Rule in a Sysmon configuration file.\n.DESCRIPTION\nGet"
},
{
"path": "Functions/New-SysmonConfiguration.ps1",
"chars": 10576,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonConfiguration\n{\n [CmdletBinding(HelpUri = 'https://gith"
},
{
"path": "Functions/New-SysmonCreateRemoteThreadFilter.ps1",
"chars": 2732,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonCreateRemoteThreadFilter {\n [CmdletBinding(DefaultParam"
},
{
"path": "Functions/New-SysmonDriverLoadFilter.ps1",
"chars": 2749,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonDriverLoadFilter {\n [CmdletBinding(DefaultParameterSetN"
},
{
"path": "Functions/New-SysmonFileCreateFilter.ps1",
"chars": 2819,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonFileCreateFilter {\n [CmdletBinding(DefaultParameterSetN"
},
{
"path": "Functions/New-SysmonFileCreateStreamHashFilter.ps1",
"chars": 2912,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of the saving of data on a file stream.\n.DESCRIPTION\nCreate a new filte"
},
{
"path": "Functions/New-SysmonImageLoadFilter.ps1",
"chars": 3501,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonImageLoadFilter {\n [CmdletBinding(DefaultParameterSetNa"
},
{
"path": "Functions/New-SysmonNetworkConnectFilter.ps1",
"chars": 3011,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonNetworkConnectFilter\n{\n [CmdletBinding(DefaultParameter"
},
{
"path": "Functions/New-SysmonPipeFilter.ps1",
"chars": 2899,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for when a Named Pipe is created or connected.\n.DESCRIPTION\nCreate a new filter for whe"
},
{
"path": "Functions/New-SysmonProcessAccessFilter.ps1",
"chars": 3216,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of when a running process opens another.\n.DESCRIPTION\nCreate a new filt"
},
{
"path": "Functions/New-SysmonProcessCreateFilter.ps1",
"chars": 3625,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonProcessCreateFilter\n{\n [CmdletBinding(DefaultParameterS"
},
{
"path": "Functions/New-SysmonProcessTerminateFilter.ps1",
"chars": 2770,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonProcessTerminateFilter\n{\n [CmdletBinding(DefaultParamet"
},
{
"path": "Functions/New-SysmonRawAccessReadFilter.ps1",
"chars": 3060,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of file raw access read actions.\n.DESCRIPTION\nCreate a new filter for t"
},
{
"path": "Functions/New-SysmonRegistryFilter.ps1",
"chars": 4275,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for the actions against the registry.\n.DESCRIPTION\nCreate a new filter for actions agai"
},
{
"path": "Functions/New-SysmonWmiFilter.ps1",
"chars": 2935,
"preview": "<#\n.SYNOPSIS\nCreate a new filter for WMI Permamanent Event Classes.\n.DESCRIPTION\nCreate a new filter for WMI permamanent"
},
{
"path": "Functions/Remove-SysmonRule.ps1",
"chars": 3321,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Remove-SysmonRule\n{\n [CmdletBinding(DefaultParameterSetName = 'Pa"
},
{
"path": "Functions/Remove-SysmonRuleFilter.ps1",
"chars": 7516,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Remove-SysmonRuleFilter {\n [CmdletBinding(DefaultParameterSetName"
},
{
"path": "Functions/Schemas/SysmonConfigurationSchema_3_40.xsd",
"chars": 35603,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xs:schema targetNamespace=\"urn:schemas-specterops.io:SysmonConfiguration\"\n e"
},
{
"path": "Functions/Schemas/SysmonConfigurationSchema_4_00.xsd",
"chars": 36579,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xs:schema targetNamespace=\"urn:schemas-specterops.io:SysmonConfiguration\"\n e"
},
{
"path": "Functions/Set-SysmonHashingAlgorithm.ps1",
"chars": 3267,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Set-SysmonHashingAlgorithm\n{\n [CmdletBinding(DefaultParameterSetN"
},
{
"path": "Functions/Set-SysmonRule.ps1",
"chars": 6236,
"preview": "# .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Set-SysmonRule\n{\n [CmdletBinding(DefaultParameterSetName = 'Path'"
},
{
"path": "LICENSE",
"chars": 1482,
"preview": "Copyright (c) 2016, Carlos Perez\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or withou"
},
{
"path": "Posh-SysMon.psm1",
"chars": 11789,
"preview": "\n# Load functions\n . \"$($PSScriptRoot)\\Functions\\Get-SysmonEventData.ps1\"\n . \"$($PSScriptRoot)\\Functions\\Get-SysmonHash"
},
{
"path": "Posh-Sysmon.psd1",
"chars": 9566,
"preview": "#\n# Module manifest for module 'PSGet_Posh-Sysmon'\n#\n# Generated by: Carlos Perez carlos_Perez@darkoperator.com\n#\n# Gene"
},
{
"path": "README.md",
"chars": 9478,
"preview": "# Posh-Sysmon\nPowerShell 3.0 or above module for creating and managing Sysinternals Sysmon v2.0 config files. System Mon"
},
{
"path": "build.ps1",
"chars": 1097,
"preview": "[CmdletBinding()]\nparam(\n [ValidateSet(\"Release\",\"Debug\")]\n $Configuration = \"Release\"\n)\n\nPush-Location $PSScriptR"
},
{
"path": "docs/Get-SysmonEventData.md",
"chars": 2986,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version:\nschema: 2.0.0\n---\n\n# Get-SysmonEve"
},
{
"path": "docs/Get-SysmonHashingAlgorithm.md",
"chars": 1721,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Get-SysmonRule.md",
"chars": 2180,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Get-SysmonRuleFilter.md",
"chars": 2139,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonConfiguration.md",
"chars": 6289,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonDriverLoadFilter.md",
"chars": 3318,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonFileCreateFilter.md",
"chars": 2839,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonFileCreateStreamHash.md",
"chars": 2385,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonFileCreateStreamHash\n\n## SY"
},
{
"path": "docs/New-SysmonFileCreateStreamHashFilter.md",
"chars": 2996,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonImageLoadFilter.md",
"chars": 3387,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonNetworkConnectFilter.md",
"chars": 3521,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonPipeEvent.md",
"chars": 2214,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonPipeEvent\n\n## SYNOPSIS\nCrea"
},
{
"path": "docs/New-SysmonPipeFilter.md",
"chars": 2991,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonProcessAccessFilter.md",
"chars": 3065,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonProcessCreateFilter.md",
"chars": 3521,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonProcessTerminateFilter.md",
"chars": 3338,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/New-SysmonRegistryEvent.md",
"chars": 2517,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonRegistryEvent\n\n## SYNOPSIS\n"
},
{
"path": "docs/New-SysmonRegistryFilter.md",
"chars": 3533,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Remove-SysmonRule.md",
"chars": 2523,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Remove-SysmonRuleFilter.md",
"chars": 3458,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Set-SysmonHashingAlgorithm.md",
"chars": 2100,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "docs/Set-SysmonRule.md",
"chars": 2799,
"preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
},
{
"path": "en-US/Posh-SysMon-help.xml",
"chars": 322468,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<helpItems schema=\"maml\" xmlns=\"http://msh\">\n <command:command xmlns:maml=\"http"
},
{
"path": "en-US/Posh-SysMon.psm1-Help.xml",
"chars": 111095,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<helpItems xmlns=\"http://msh\" schema=\"maml\">\n\n<command:command xmlns:maml=\"http:"
},
{
"path": "lib/sysmon3_1.dtd",
"chars": 6764,
"preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation)*>\n<!ATTLIST Sysmon schemaversion CD"
},
{
"path": "lib/sysmon3_2.dtd",
"chars": 8158,
"preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation)*>\n<!ATTLIST Sysmon schemaversion CD"
},
{
"path": "lib/sysmon3_3.dtd",
"chars": 8494,
"preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation|PipeMonitoringConfig)*>\n<!ATTLIST Sy"
}
]
About this extraction
This page contains the full source code of the darkoperator/Posh-Sysmon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 65 files (822.3 KB), approximately 210.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.