Powershell Transcript / Filebeat

We have recently implemented a GPO which logs powershell transcript files from end points to a central file share. The intent here is looking for indications of compromise and powershell being used as an exploit tool.

The next obvious step is to ingest these logs into Graylog.

Deployed filebeat which began creating a log entry p/log line. Have put together a rudimentary multiline config so the message now appears as a single field, which helps a little with that but it’s not going to give me what I want.

Log files are created on each powershell session start and all data is logged to the same file until it’s closed. Multiline files.

I have two scenarios.

Scenario 1 - User runs a PS script, powershell opens/closes, filebeat sends log to Graylog.

In this scenario I would like to report:

  • Who : Username
  • Where : Machine
  • What : PS>

Example log:

**********************
Windows PowerShell transcript start
Start time: 20200203090638
**Username**: DOMAIN\Login
RunAs User: DOMAIN\Login
Configuration Name: 
**Machine**: COMPUTER_NAME (Microsoft Windows NT 10.0.17134.0)
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass POWERSHELL_SCRIPT.ps1
Process ID: 13884
PSVersion: 5.1.17134.858
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.858
BuildVersion: 10.0.17134.858
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
**********************
Command start time: 20200203090638
**********************
**PS>POWERSHELL_SCRIPT.ps1**
**********************
Command start time: 20200203090639
**********************
PS>$global:?
True
**********************
Windows PowerShell transcript end
End time: 20200203090639
********************** 

Question : What is the more correct method to extract components of the message into fields? Unless I misunderstood Grok is not multiline.

Scenario 2 - User opens powershell, log file is created, the Initial entry is sent via filebeat and each subsequent task is written to the same log file. filebeat pushes to Graylog as a separate messages each time it checks the file and finds new data.

Example :

**********************
Windows PowerShell transcript start
Start time: 20200203090638
**Username**: DOMAIN\Login
RunAs User: DOMAIN\Login
Configuration Name: 
**Machine**: COMPUTER_NAME (Microsoft Windows NT 10.0.17134.0)
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass POWERSHELL_SCRIPT.ps1
Process ID: 13884
PSVersion: 5.1.17134.858
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.858
BuildVersion: 10.0.17134.858
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************

Subsequent entries are appended to the log:

Command start time: 20200203145453
**********************
PS C:\Users\xxxx> get-aduser guest


DistinguishedName : CN=Guest,OU=Others,OU=Misc,DC=XXXXXXXXXXX,DC=co,DC=uk
Enabled           : False
GivenName         :
Name              : Guest
ObjectClass       : user
ObjectGUID        : 6b0b8f55-a6bb-4d7f-bfaf-e155daf45def
SamAccountName    : Guest
SID               : S-1-5-21-3489743409-770199431-2528730523-501
Surname           :
UserPrincipalName :

Again I would like to report

In this scenario I would like to report:

  • Who : Username
  • Where : Machine
  • What : PS>

But in this scenario the messages are missing some of that information. Who & Where. There is a common field, filebeat_source.

Is there a way to connect the first log entry which contains the fields I want to report, username etc with the second, (third, fourth etc) entries that dont using the filebeat_source?

or, if anyone has a better suggestion I’m all ears.

  1. GROK not multi-line: its a little uglier but a series of regex commands in a pipeline would do it.

  2. Connecting log entries: Possible on the filebeat side using the multiline options to capture entire powershell session - though long sessions might cause issues and harder to break out the commands.

    #pattern can be regex…
    multiline.pattern: ‘Windows PowerShell transcript’
    multiline.negate: true
    multiline.match: after
    multiline.timeout: 5m
    multiline.flush_pattern: ‘Windows PowerShell transcript end’

https://www.elastic.co/guide/en/beats/filebeat/6.8/multiline-examples.html

Caveat: Researched but not tested by me… hope it’s helpful…

On a side note we use Cylance which has a script control component to it.

Thanks for the reply, I’ll look at the examples.