EventLog Analysis

9 minute read

Windows EventLogs

EventLog analysis is extremely challenging in real-world cases as the Eventlog service collects too much info about the machine and not all of them is related to security incidents also not all of them can indicate some thing alone but needs to be correlated with other events to be meaningful and a lot of other challenges there.

So I decided to simplify the process starting with an explanation of how it works, how to extend its configuration to be more clear and easier, and how to script our own parser to automate the discovery of juicy findings.

Windows EventLogs Description

In Windows, the process responsible for collecting logs is called the Windows Event Log service. The service is implemented by the “Eventlog” system driver (eventlog.sys), which is a component of the Windows operating system.

Error Loading

This service collects logs for a huge number of event in mostly every action that happen on the device which is then categorized in different categories.

EventLog Structure

The main application for viewing EventLogs in Windows is EventViewer made by Microsoft.

Error Loading

As we can see we have two main classes one for Windows Logs which are logs collected from built-in Windows functionalities and another one which is Applications and Services Logs which are collected from installed applications and services actions.

For now, let us focus on Windows Logs, we can see that the logs are categorized based on different relations in the system for three main categories.

  • Application Log: The Application log records events generated by applications or programs running on the system. This log is useful for diagnosing application-specific issues, such as crashes, errors, warnings, and information messages. It may contain events from various software installed on the system, including third-party applications.

  • Security Log: The Security log records security-related events on the system. It includes events related to authentication, user access, account management, policy changes, and security audits. This log is crucial for monitoring user activity, detecting security breaches, and analyzing security-related incidents.

  • System Log: The System log captures events related to the Windows operating system and system components. It contains events such as driver failures, system startup and shutdown events, hardware errors, system service failures, and other system-level notifications. The System log helps identify issues that impact the overall stability and performance of the system.

Now let us take a look at how each log is structured.

logs are mainly stored in an XML format as follows:

Error Loading

As we can see this is a log from the system category indicating that the system started downloading an update for the defender’s security intelligence.

we have several important fields we need to understand that are found in every log you will face.

  • provider name (Application caused the log).
  • Event Id (identifier for the action in our case 44”windows update”).
  • Level (the severity of the log).
  • Time Created (the time of the log “machine time”).

other fields are also important but they are self-explanatory or I will mention them in their time for more explanation.

Extending Log capapilities

There are some ways to configure Windows to log specific Events you want based on your own rules to make it easier for you to control what you want to see in your event logs.

The most known one is using Sysmon which is a Windows utility used to capture logs based on defined rules.

Sysmon

After installation, you will see events triggered by your rules on the following path at Event Viewer

Applications and Services Logs/Microsoft/Windows/Sysmon/Operational

Now let us take a look at how Sysmon rules work.

Sysmon Configuration is written to a .xml file and can be applied by the command

sysmon.exe -c configuration.xml

This is an example configuration file for sysmon which is self explanatory but let us take a sample rule and break it down.

<!--SYSMON EVENT ID 2 : FILE CREATION TIME RETROACTIVELY CHANGED IN THE FILESYSTEM [FileCreateTime]-->
    <!--COMMENT:  [ https://attack.mitre.org/wiki/Technique/T1099 ] -->

    <!--DATA: UtcTime, ProcessGuid, ProcessId, Image, TargetFilename, CreationUtcTime, PreviousCreationUtcTime-->
  <RuleGroup name="" groupRelation="or">
    <FileCreateTime onmatch="include">
      <Image name="T1099" condition="begin with">C:\Users</Image> <!--Look for timestomping in user area, usually nothing should be doing that here-->
      <TargetFilename name="T1099" condition="end with">.exe</TargetFilename> <!--Look for backdated executables anywhere-->
      <Image name="T1099" condition="begin with">\Device\HarddiskVolumeShadowCopy</Image> <!--Nothing should be written here | Credit: @SBousseaden [ https://twitter.com/SBousseaden/status/1133030955407630336 ] -->
    </FileCreateTime>
  </RuleGroup>

This rule is used to trace TimeStamp manipulation if TIME RETROACTIVELY CHANGED. here we can find the Event ID that we will see in the logs for this rule, we can define a name and a logical condition for triggering, we can include or exclude specific actions to be more focused, and other filtering ways can be applied.

here is an example log that was saved when I triggered this rule.

Error Loading

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Microsoft-Windows-Sysmon" Guid="{5770385f-c22a-43e0-bf4c-06f5698ffbd9}" /> 
  <EventID>2</EventID> 
  <Version>5</Version> 
  <Level>4</Level> 
  <Task>2</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8000000000000000</Keywords> 
  <TimeCreated SystemTime="2023-07-18T14:17:35.8129262Z" /> 
  <EventRecordID>134160</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="5240" ThreadID="7776" /> 
  <Channel>Microsoft-Windows-Sysmon/Operational</Channel> 
  <Computer>Spider0x</Computer> 
  <Security UserID="S-1-5-18" /> 
  </System>
- <EventData>
  <Data Name="RuleName">T1099</Data> 
  <Data Name="UtcTime">2023-07-18 14:17:35.812</Data> 
  <Data Name="ProcessGuid">{ccaef897-9eff-64b6-23f2-000000008000}</Data> 
  <Data Name="ProcessId">7860</Data> 
  <Data Name="Image">C:\Users\Amras\Downloads\nTimestomp_v1.2_x64.exe</Data> 
  <Data Name="TargetFilename">C:\Users\Amras\Downloads\client (2).exe</Data> 
  <Data Name="CreationUtcTime">2009-07-04 09:25:23.223</Data> 
  <Data Name="PreviousCreationUtcTime">2023-07-04 09:25:23.223</Data> 
  <Data Name="User">Spider0x\Amras</Data> 
  </EventData>
  </Event>

EventLogs With PowerShell

As we discussed earlier our goal is to write our own parser for the EventLogs to automate finding different attacks, So I will start by speaking about how to deal with EventLogs programmatically with PowerShell.

The command “Get-WinEvent” is used to interact with events in Powershell, for start we will supply the logname for the provider to display its content.

Error Loading

but as you can imagine writing this every time is a bad practice so I will define a function that we can use to interact with the Sysmon logs directly.

After writing our simple code for start we need to load the module we have written and check if it’s imported successfully.

Error Loading

and here is a simple search result

Error Loading

We can also deal with it directly in Powershell like this

Error Loading

This is a small approach to clarify how we will deal with event logs in Powershell throw writing our parser module.

Now let us move to the part where we actually investigating the attack and the resulting logs.

Suspisious Logins

To start investigating Suspicious Logins and scripting the detection for it, we need first to identify what is considered a suspicious login.

here are some examples:

  • Login time is out of working hours.
  • unusual Remote login.
  • bruteforce

We need to implement a function that can alert us in each of the previous cases.

Login out of working hours

here is a simple function that can test that for us.

Error Loading

you can improve it more yourself to work for the vacation days also.

Remote logins

This is a small function that parses login successful events to find a login with types (3 or 10) which are the remote login and RDP login types.

function Remote-Login{

    Get-WinEvent -FilterHashtable @{Logname = "Security" ; ID = 4624 } | where {$_.Properties[8].Value -eq 3 -or $_.Properties[8].Value -eq 10} 

}

from there we can start investigating the ip initiated the connection.

BruteForce

To check for a BruteForce attack signs in event logs we can search for multiple login faild events with id 4625 on the security log.

we can use the following script to do that

function BruteForceDetect {
    param (
        [string]$logName = "Security",
        [int]$eventID = 4625,
        [int]$failedAttemptsThreshold = 5,
        [int]$timeWindow = 60 # Time window in minutes to check for repeated login attempts
    )

    $startTime = (Get-Date).AddMinutes(-$timeWindow)
    
    # Define the filter hashtable
    $filterHash = @{
        LogName = $logName
        ID = $eventID
        StartTime = $startTime
    }

    $events = Get-WinEvent -FilterHashtable $filterHash

    $failedAttempts = @{}
    foreach ($event in $events) {
        $userName = $event.Properties[5].Value
        $sourceIPAddress = $event.Properties[19].Value

        if ($userName -and $sourceIPAddress) {
            if ($failedAttempts.ContainsKey($userName)) {
                $failedAttempts[$userName]++
            } else {
                $failedAttempts[$userName] = 1
            }
        }
    }

    $failedAttempts.GetEnumerator() | Where-Object { $_.Value -ge $failedAttemptsThreshold } | Sort-Object Value -Descending


  if ($bruteForceEvents.Count -gt 0) {
    # brute force detected
        Write-Host "Brute Force Attacks Detected:"
        foreach ($entry in $bruteForceEvents) {
            Write-Host ("User: {0}, Failed Attempts: {1}" -f $entry.Name, $entry.Value)
        }
  } else {
        Write-Host "No brute force attacks detected within the specified time window."
    }
}

Binary Attacks

Windows has some mitigations against exploitation using some known techniques like return-oriented programming "ROP" we can find the logs for detected exploits in the Microsoft-Windows-Security-Mitigations/UserMode log

This is a small script to check for that

Get-WinEvent -FilterHashTable @{LogName ='Microsoft-Windows-Security-Mitigations/UserMode'} | Format-List -Property Id, TimeCreated

Office Phishing

One of the most used ways of phishing is using office documents to launch another hidden payload, So I will monitor for any process spawned by Word or Excel other office documents in the same way.

 Get-SysmonEvents 1 | Where-Object { $_.Properties[20].Value -match "word|Excel" } | Format-List TimeCreated, @{label = "ParentImage" ; Expression = {$_.properties[20].value}}, @{label= "Image" ; Expression= {$_.properties[4].value}}

Service Manipulation

One way to detect Manipulating services using the command line is monitoring for the use of Sc.exe executable.

Here is a small script to do that

Get-SysmonEvents 1 | Where-Object { $_.Properties[4].Value -match "\\sc.exe" } | Format-List TimeCreated, @{label = "ParentImage" ; Expression = {$_.properties[20].value}}, @{label= "Image" ; Expression= {$_.properties[4].value}},@{label = "CommandLine" ; Expression = {$_.properties[10].value}}

For other persistence techniques I have another PowerShell script to collect a lot more persistence artifacts from live machine here.

Conclusion

Here I was discussing understanding how to deal with EventLogs and automating your own functions to detect some attacks, as it’s a huge number of techniques I decided just to talk about the foundation you need to continue by yourself.

Resources

  • “OSDA” Course