Labeling endpoint actions with Logstash – Threat Hunting

There’s been plenty of instances where I have to go through an investigation after a user has clicked on a phishing email and find out what happened later. After performing this task multiple times I realized that it would be easier to label the actions the user took and create a dashboard that would indicate such events.

A typical example is a user opening a .pdf file with an embedded link, which either contains a phishing site, or might download a word document with a macro. This approach allows the attacker to bypass any type of sandboxing that would detect the macro behavior and reject the email along with the attachment. Once the user downloads, launches the word document, and enables the macro, typically an action will take place. Traditionally this might be Powershell spawning and downloading an additional payload from the internet and the rest is up to your imagination (ransomware, bitcoin miner, RAT, etc).

This is how the endpoint would log such actions:

  1. Outlook opened a .pdf document which launched Adobe Reader, or perhaps they clicked on a link within the email; therefore, Outlook launched Internet Explorer instead.
  2. Adobe Reader (.PDF Document) launched Internet Explorer (or your default web-browser)
  3. Internet Explorer downloaded a Word Document (.doc, .docm)
  4. Word Document spawned Powershell.exe
  5. Powershell.exe ran silently with commands such as (-nop, EncodedCommand, -NonInteractive, downloadstring, etc.. etc..)

Therefore, I wanted to display these actions in plain English to the Analyst reviewing these logs, it makes it much easier to identify abnormal behavior (such as Word.exe launching Powershell.exe)

Here’s how the proposed idea looks like:

This allowed me to know exactly what actions took place in an endpoint rather than having to look at raw logs and apply different filters to get what I wanted to see in the first place. The screenshot below shows the action for “File Created from Web Browser” which relates to Sysmon EventId 15.

This allowed me to easily Identify the file being downloaded and how it got downloaded.

Additionally, I created another filter that labels the file extension based on the file type, this way I can always filter on the file type and see actions related to such file. This helps identify files such as .exe, .hta, .js, etc.. that might stand out and trigger an investigation.

Looking for abnormal behavior

Once you label your use cases, it is easier to identify abnormal behavior and allows us to react faster rather than relying on our endpoint security product to detect a file hash, or malicious IP addresses. Focus on endpoint behavior! If your Word Document opens anything else besides a (.doc,docx,.docm) ensure that you are alerting on such actions. Understand your business applications and take appropriate actions when the attacker manipulates those applications outside of their intended scope.

Logstash Configuration Files

Below are two logstash configurations used.

Configuration 1 – Endpoint Actions
input {
  beats {
    port => 5050
	tags => [ "winlogbeat" ]
  }
}



################################# Endpoint Actions #####################################

 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(OUTLOOK.EXE)/ )
  and ([event_data][Image] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Browser Launched From Outlook Sysmon 1" } }}
   }
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(OUTLOOK.EXE)/ )
  and ([event_data][Image] =~ /(?i)(powershell.exe|wscript.exe|cmd.exe|taskeng.exe|cab.exe|java.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Powershell & Exes Launched From Outlook Sysmon 1" } }}
   }
   
  filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(WORD.EXE)/ )
  and ([event_data][Image] =~ /(?i)(.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Exes Launched From Word Sysmon 1" } }}
   }
   
   
  filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(WORD.EXE)/ )
  and ([event_data][Image] =~ /(?i)(powershell.exe|wscript.exe|cmd.exe|taskeng.exe|cab.exe|java.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Powershell & Exes Launched From Word Sysmon 1" } }}
   }
   
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ )
  and ([event_data][ParentCommandLine] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "File Launched From Web Browser Sysmon 1" } }}
   }


 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(OUTLOOK.EXE)/ )
  and ([event_data][Image] =~ /(?i)(WINWORD.EXE)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Word Launched From Outlook Sysmon 1" } }}
   }
   
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 1
  and ( ([event_data][ParentImage] =~ /(?i)(WINWORD.EXE)/ )
  and ([event_data][Image] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ ) )
  {
   mutate { 
   add_field => { "IOC" => "Web Browser Launched from Word Sysmon 1" } }}
   }
   
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 11
  and ([event_data][Image] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Web Browser Sysmon 11" } }}
   }
   
  filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 11
  and ([event_data][Image] =~ /(?i)(WINWORD.EXE)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Word Sysmon 11" } }}
   }
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 11
  and ([event_data][Image] =~ /(?i)(OUTLOOK.EXE)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Outlook Sysmon 11" } }}
   } 
   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15
  and ([event_data][Image] =~ /(?i)(OUTLOOK.EXE)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Outlook Sysmon 15" } }}
   }

   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15
  and ([event_data][Image] =~ /(?i)(iexplore.exe|chrome.exe|firefox.exe)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Web Browser Sysmon 15" } }}
   }

   
 filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational" and [event_id] == 15
  and ([event_data][Image] =~ /(?i)(WINWORD.EXE)/ ) 
  {
   mutate { 
   add_field => { "IOC" => "File Created from Word Sysmon 15" } }}
   }
   
   
################################# End of Endpoint Actions #####################################



output {
if "winlogbeat" in [tags] {
    elasticsearch {
    hosts => ["http://yourELK:9200"]
	index => "logstash-winlogbeat-%{+xxxx.ww}"

  }
 }

This configuration relies on Sysmon Event ID 1, and 15 which typically contain the source process and destination file which is typically involved in the scenario explained earlier. You can always make it look neater by combining the events with an “or” statement within the Logstash configuration, or create a pattern within the pattern directory to make it cleaner. I’m including basic actions such as web browsers launching executable files, Outlook launching web browsers, etc.. to provide me with a narrative once such actions occur.

Configuration 2 – File Extensions
#Create Field Based on File Type
filter {
  if "winlogbeat" in [tags] and [log_name] == "Microsoft-Windows-Sysmon/Operational"
  and [event_data][TargetFilename] =~ /(?i)\.(exe|ps1)$/ {
   mutate { 
   add_field => { "FileExtension" => "EXE" } }}
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(PS1|PSM1)$/  {
   mutate { 
   add_field => { "FileExtension" => "Powershell" }}}
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(VBS|VBE)$/  {
   mutate { 
   add_field => { "FileExtension" => "VBS" }}}
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(HTA|WSF)$/  {
   mutate { 
   add_field => { "FileExtension" => "Script" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(log)$/  {
   mutate { 
   add_field => { "FileExtension" => "log" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(etl)$/  {
   mutate { 
   add_field => { "FileExtension" => "MS log File" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(sys)$/  {
   mutate { 
   add_field => { "FileExtension" => "Driver File" }}}
   
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(crt)$/  {
   mutate { 
   add_field => { "FileExtension" => "Certificate File" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(asp|html|php|htm)$/  {
   mutate { 
   add_field => { "FileExtension" => "Web Page File" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(txt|ini)$/  {
   mutate { 
   add_field => { "FileExtension" => "text based" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(xml)$/  {
   mutate { 
   add_field => { "FileExtension" => "xml" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(dll)$/  {
   mutate { 
   add_field => { "FileExtension" => "dll" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(json)$/  {
   mutate { 
   add_field => { "FileExtension" => "json" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(JS)$/  {
   mutate { 
   add_field => { "FileExtension" => "JavaScript" }}}
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(pdf)$/  {
   mutate { 
   add_field => { "FileExtension" => "PDF" }}}
 else if 
  [event_data][TargetFilename] =~ /(?i)\.(DOC|DOCM|RTF|DOCX)$/  {
   mutate { 
   add_field => { "FileExtension" => "Word Document" }}}   

 else if 
  [event_data][TargetFilename] =~ /(?i)\.(xls|xlsx|xlsm|csv)$/  {
   mutate { 
   add_field => { "FileExtension" => "Excel" }}}   
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(msp|wmf|db|pptx|ppt|rtc)$/  {
   mutate { 
   add_field => { "FileExtension" => "Other Microsoft Products" }}}   
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(bat|cmd)$/  {
   mutate { 
   add_field => { "FileExtension" => "Command" }}} 
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(ica)$/  {
   mutate { 
   add_field => { "FileExtension" => "Citrix" }}}   
      
 else if 
  [event_data][TargetFilename] =~ /(?i)\.(website)$/  {
   mutate { 
   add_field => { "FileExtension" => "URL Shortcut" }}}
   
   
 else if 
  [event_data][TargetFilename] =~ /(?i)\.(jpg|png|jpeg)$/  {
   mutate { 
   add_field => { "FileExtension" => "Pictures" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(sql)$/  {
   mutate { 
   add_field => { "FileExtension" => "Pictures" }}}
   
  else if 
  [event_data][TargetFilename] =~ /(?i)\.(tmp)$/  {
   mutate { 
   add_field => { "FileExtension" => "Temp File" }}}
   
   

 else if 
  [event_data][TargetFilename] =~ /(?i)\.(7zip|TAR|GZIP|zip)$/  {
   mutate { 
   add_field => { "FileExtension" => "Compressed File" }}}  
   
}

This configuration is based on a regex pattern to match file extension and adds a field name for those file extension.

Conclusion

As mentioned earlier, focus on Behavior! as this will allow you to see what’s abnormal and rely on your own intelligence rather than an outdated definition from your [insert vendor name here] endpoint solution. Lastly, I called these IOCs which might be misleading, it’s just what I felt like calling it; however, you’re entitled to your own descriptions.

The next article I will include email alerts on abnormal behavior that allows you to react on unexpected endpoint actions.

Thanks for reading.

Special thanks to Mr. Pietri for pointing out a regex correction in my configuration.

 

 

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments