Sysmon for Linux PowerShell Module

Sysmon has been a great tool to enhance logging in Windows for many year allowing well organized teams to cover many gaps in their log and even improve their capabilities at detecting all kinds of attacks. Microsoft released a version of Sysmon for Linux to provide the same type of value to those defending Linux systems. Logs are saved in to Syslog as single line XML blobs that can be ingested and parsed by SIEM products. To aid with extracting the Sysmon specific events from syslog I wrote the SysmonLinux.Util module. The module can parse one or more Syslog files even GZip files archived by LogRotate from a Linux system and allow for the search of specific events that meet a given criteria. The module can be use also for aiding in the generation of filter rules based on the resulting objects of queries performed against the logs, greatly speeding the creation and tunning of Sysmon configuration files.

Install

The recommended method for installing the module is to install the module from the PowerShell Gallery, https://www.powershellgallery.com/packages/SysmonLinux.Util The command to install the module is

Install-Module -Name SysmonLinux.Util -Force

The module source code can also be downloaded from GitHub https://github.com/darkoperator/SysmonLinux.Util/

Exploring the Module

Once the module is installed we can take a look at the functions made available for working with tge Get-Command cmdlet in PowerShell.

PS /home/carlos> Get-Command -Module sysmonlinux.util                                                                                              
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        ConvertTo-SysmonRule                               0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxConfigChange                        0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxEvent                               0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxFileCreate                          0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxFileDelete                          0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxNetworkConnect                      0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxProcessCreate                       0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxProcessTerminate                    0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxRawAccess                           0.0.3      SysmonLinux.Util
Function        Get-SysmonLinuxState                               0.0.3      SysmonLinux.Util

The functions available at the moment of this is written are described bellow in the table.

Function Description
ConvertTo-SysmonRule Takes resulting objects from the other module function and turns them in to Sysmon Rules
Get-SysmonLinuxConfigChange Gets Sysmon configuration change events from one or more syslog files.
Get-SysmonLinuxEvent Gets any Syslon event allowing filtering either by Image and ProcessGUID from one or more syslog files.
Get-SysmonLinuxFileCreate Gets Sysmon File Create events from one or more syslog files.
Get-SysmonLinuxFileDelete Gets Sysmon File Delete events from one or more syslog files.
Get-SysmonLinuxNetworkConnect Gets Sysmon Network Connect events from one or more syslog files.
Get-SysmonLinuxProcessCreate Gets Sysmon Process Create events from one or more syslog files.
Get-SysmonLinuxProcessTerminate Gets Sysmon Process Terminate events from one or more syslog files.
Get-SysmonLinuxRawAccess Gets Sysmon Raw Access events from one or more syslog files.
Get-SysmonLinuxState Gets Sysmon Linux State events from one or more syslog files.

The Get-Help cmdlet or its alias help can be used to look at the parameters and their details for each of the functions. It will also show which parameters allow for wildcards so as to make searching for specific events much easier.

PS /home/carlos> help Get-SysmonLinuxEvent

NAME
    Get-SysmonLinuxEvent

SYNOPSIS
    Gets one or more Sysmon for Linux event types from Syslog logs.


SYNTAX
    Get-SysmonLinuxEvent -EventType <String[]> [[-SyslogFile] <String[]>] [-Image <String[]>] [-User 
    <String[]>] [<CommonParameters>]

    Get-SysmonLinuxEvent -EventType <String[]> [[-SyslogFile] <String[]>] [-ProcessGuid <String[]>] 
    [-Image <String[]>] [-User <String[]>] [<CommonParameters>]


DESCRIPTION
    Gets one or more Sysmon for Linux event types from Syslog logs. Allows for filtering by ProcessGUID 
    and User.


PARAMETERS
    -EventType <String[]>
        Event type to pull from Syslog log file.

        Required?                    true
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -SyslogFile <String[]>
        Specifies a path to one or more locations.

        Required?                    false
        Position?                    1
        Default value                @("/var/log/syslog")
        Accept pipeline input?       true (ByValue, ByPropertyName)
        Accept wildcard characters?  false

    -ProcessGuid <String[]>
        ProcessGuid to search for a given event type, ParentProcessGuid will also be matched to this 
        value.

        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false

    -Image <String[]>
        Image to search for a given event type.The '*' wildcard is supported for matching.

        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  true

    -User <String[]>
        User to seach for a given event type.

        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216). 

INPUTS
    System.IO.FileInfo


OUTPUTS
    System.Management.Automation.PSCustomObject


NOTES


        General notes

    -------------------------- EXAMPLE 1 --------------------------

    PS />Get-SysmonLinuxEvent -EventType Any -ProcessGuid "{de9527a5-6a3f-616f-a52f-d98154560000}"

    EventId           : 1
    Version           : 5
    EventType         : ProcessCreate
    Computer          : ubuntu
    EventRecordID     : 35705
    RuleName          : -
    UtcTime           : 2021-10-20 01:00:47.600
    ProcessGuid       : {de9527a5-6a3f-616f-a52f-d98154560000}
    ProcessId         : 2356
    Image             : /usr/sbin/dumpe2fs
    FileVersion       : -
    Description       : -
    Product           : -
    Company           : -
    OriginalFileName  : -
    CommandLine       : dumpe2fs -h /dev/sda5
    CurrentDirectory  : /
    User              : root
    LogonGuid         : {de9527a5-0000-0000-0000-000000000000}
    LogonId           : 0
    TerminalSessionId : 4294967295
    IntegrityLevel    : no level
    Hashes            : -
    ParentProcessGuid : {00000000-0000-0000-0000-000000000000}
    ParentProcessId   : 874
    ParentImage       : -
    ParentCommandLine : -
    ParentUser        : -

    EventId       : 9
    Version       : 2
    EventType     : RawAccessRead
    Computer      : ubuntu
    EventRecordID : 35706
    RuleName      : -
    UtcTime       : 2021-10-20 01:00:47.619
    ProcessGuid   : {de9527a5-6a3f-616f-a52f-d98154560000}
    ProcessId     : 2356
    Image         : /usr/sbin/dumpe2fs
    Device        : /dev/sda5
    User          : root

    EventId       : 5
    Version       : 3
    EventType     : ProcessTerminate
    Computer      : ubuntu
    EventRecordID : 35707
    RuleName      : -
    UtcTime       : 2021-10-20 01:00:47.620
    ProcessGuid   : {de9527a5-6a3f-616f-a52f-d98154560000}
    ProcessId     : 2356
    Image         : /usr/sbin/dumpe2fs
    User          : root

    Find all events that match the specified ProcessGuid.





RELATED LINKS

Leveraging the Functions

The functions are divided in 2 groups, all of the functions minus ConvertTo-SysmonRule are meant for getting from Syslog log files the events for their type and allow to target certain events by filtering based on their properties. Each function returns the log entry as an object, this allows for the use of regular built in PowerShell cmdlets to further filter and process the resulting log entry objects. Bellow we use the Select-Object cmdlet to select only some of the properties of the resulting objects and from the results only have unique entries.

PS /home/carlos> Get-SysmonLinuxNetworkConnect -Image /usr/lib/systemd/systemd-resolved | select destinationip,image -unique                       

DestinationIp Image
------------- -----
10.101.101.2  /usr/lib/systemd/systemd-resolved
127.0.0.1     /usr/lib/systemd/systemd-resolved
127.0.0.53    /usr/lib/systemd/systemd-resolved

By default the functions will open the /var/log/syslog file, a list of files can be passed to the -SyslogFile parameter or passed to the filtering functions via the pipeline. On most distributions of linux the lograted daemon runs on a schedule and archives the syslog log file in to a Gzip compressed file. The SysmonLinux.Util module can handle this files by decompressing in to the temp folder the files and processing each file if they have the .gz extension.

PS /home/carlos> ls /var/log/syslog* | Get-SysmonLinuxRawAccess | select image,user -Unique | Format-List       
Image : /usr/sbin/grub-probe
User  : root

Image : /usr/sbin/blkid
User  : root

Image : /usr/lib/systemd/systemd-logind
User  : root

Image : /usr/sbin/dumpe2fs
User  : root

Image : /usr/lib/systemd/system-generators/systemd-gpt-auto-generator
User  : root

Image : /usr/bin/mount
User  : root

Image : /usr/lib/systemd/systemd-udevd
User  : root

Image : /usr/lib/udev/scsi_id
User  : root

Image : /usr/lib/udev/cdrom_id
User  : root

Image : /usr/lib/udev/ata_id
User  : root

Image : /usr/lib/udisks2/udisksd
User  : root

The ConvertTo-SysmonRule function is the only function whose purpose is not the extraction of log entries from syslog files but for turning the resulting objects in to rules that can then be used for exclude or include rule groups to further tune configuration files.

PS /home/carlos> ls /var/log/syslog* | Get-SysmonLinuxRawAccess | select image,user -Unique | ConvertTo-SysmonRule
<Rule groupRelation="and">
  <Image condition='is'>/usr/sbin/grub-probe</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/sbin/blkid</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/systemd/systemd-logind</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/sbin/dumpe2fs</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/systemd/system-generators/systemd-gpt-auto-generator</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/bin/mount</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/systemd/systemd-udevd</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/udev/scsi_id</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/udev/cdrom_id</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/udev/ata_id</Image>
  <User condition='is'>root</User>
</Rule>
<Rule groupRelation="and">
  <Image condition='is'>/usr/lib/udisks2/udisksd</Image>
  <User condition='is'>root</User>
</Rule>

I do hope that others find the module useful and will leverage it when working with Sysmon for Linux.