Training
Get a free hour of SANS training

Experience SANS training through course previews.

Learn More
Learning Paths
Can't find what you are looking for?

Let us help.

Contact us
Resources
Join the SANS Community

Become a member for instant access to our free resources.

Sign Up
For Organizations
Interested in developing a training plan to fit your organization’s needs?

We're here to help.

Contact Us
Talk with an expert

Month of PowerShell: Solving Problems (DeepBlueCLI, Syslog, and JSON)

Let's look at an example of problem solving using PowerShell with DeepBlueCLI, Syslog, and JSON data.

Authored byJoshua Wright
Joshua Wright

#monthofpowershell

I'm an active contributor to the DeepBlueCLI project, a PowerShell module for threat hunting via Windows event logs. I don't mean for people to think that makes me a PowerShell developer because I'm not. I just Google things, look at how someone else solved the problem, then copy/transform/combine my way to success.

NOTE: I did a keynote presentation a few years ago on propelling your cyber security career that goes into the power of copy/transform/combine as a personal strategy for success. If you check out those slides, be sure to have audio turned up and look at the slides in presentation view.

In the spirit of the Month of PowerShell, I thought it would be a good idea to look at how I apply this in practice to solve problems. I think this will be immediately relatable to everyone -- at the end of the day, we learn a technology to help us solve problems, and PowerShell is no different. Hopefully my process will help you pick up some tips, or at least just be relatable in how you go about solving your own technical challenges.

The Question

GitHub ticket asking

I saw a GitHub email for a DeepBlueCLI ticket with a question:

I want to forward the DeepBlueCLI output into a logfile which can then be sent to a Syslog Server. Is there a way to do it? @therajriva

I didn't know the answer to this question, but I thought I'd see what I could figure out. I Google'd powershell syslog.

Animated GIF of Google search for

This search led me to the Posh-SYSLOG. I scrolled through the [code]README.MD[/code] file first, but the project doesn't include any use directions in the documentation. Fortunately, the project includes the next-best thing to good documentation: test cases.

Animated GIF of Posh-SYSLOG tests directory. Sample use example for use the module is in the Send-SyslogMessage.Tests.ps1 test script

The test case script [code]Send-SyslogMessage.Tests.ps1[/code] shows a sample use case for the module:

Send-SyslogMessage -Server $null -Message 'Test Syslog Message' -Severity 'Alert' -Facility 'auth'}

That looks promising, let's test it out!

Testing the Theory

Since DeepBlueCLI is a PowerShell module, it creates objects as the output. The working solution for this question is that we can [code]DeepBlue.ps1[/code] and send the pipeline output to a [code]ForEach-Object[/code] loop, sending the DeepBlueCLI alert to a specified Syslog server. First, download DeepBlueCLI and Posh-SYSLOG, unzipping the files to a local directory. For testing purposes, you can also download the free Windows software Kiwi Syslog Server Free Edition from Solarwinds (I installed Kiwi as an application during the installation choices).

NOTE: DeepBlueCLI doesn't have an official release version, but you can still download the module as a zip file by clicking the green Code button and selecting Download ZIP from the drop-down menu.

After downloading DeepBlueCLI and Posh-SYSLOG modules, unzip the files. For this article, I'll assume you have the [code]DeepBlueCLI[/code] and [code]Posh-SYSLOG[/code] directories in your [code]Downloads[/code] folder. Start PowerShell as an administrator by right-clicking on the PowerShell icon and select Run as administrator. Change to your [code]Downloads[/code] folder:

PS C:\WINDOWS\system32> cd ~/Downloads
PS C:\Users\Sec504\Downloads> dir


    Directory: C:\Users\Sec504\Downloads


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         6/13/2022   5:02 PM                DeepBlueCLI
d-----         7/14/2019  11:21 AM                Posh-SYSLOG

PowerShell Execution Mode

By default, PowerShell works in the restricted execution mode, where it will not allow third-party, unsigned scripts to execute. This has little practical benefit, since an attacker has many options to bypass this restriction. For this article, we'll change the execution policy to unrestricted (you can always change it back to restricted when you finish with this exercise):

PS C:\Users\Sec504\Downloads> Set-ExecutionPolicy unrestricted -Force
PS C:\Users\Sec504\Downloads>

TIP: I added [code]-Force[/code] as an argument to avoid the interactive prompt when using this command. Leave [code]-Force[/code] off if you feel inclined to read Microsoft's warning about changing the execution policy mode.

Run DeepBlue.ps1

Next, change to the [code]DeepBlue[/code] directory and run the [code]DeepBlue.ps1[/code] script, using one of the sample EVTX files included for testing:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx


Date    : 9/21/2016 3:41:13 AM
Log     : Security
EventID : 4688
Message : Suspicious Command Line
Results : Metasploit-style cmd with pipe (possible use of Meterpreter 'getsystem')

Command : cmd.exe /c echo hgabms > \\.\pipe\hgabms
Decoded :

Date    : 9/21/2016 3:40:37 AM
Log     : Security
EventID : 1102
Message : Audit Log Clear
Results : The Audit log was cleared.
          Account Name: IEUser
Command :
Decoded :

TIP: You can choose any of the sample files in the DeepBlue [code]evtx[/code] directory; they all generate at least one detection event.

Here we see a few alerts from DeepBlue, corresponding to a Metasploit-style [code]getsystem[/code] attack. Next, let's look at sending this data to the Syslog server.

Import Posh-SYSLOG

We need to import the Posh-SYSLOG command to invoke it as part of the DeepBlueCLI pipeline. Do that by running [code]Import-Module[/code], followed by the path to the Posh-SYSLOG module:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> Import-Module ..\Posh-SYSLOG\Posh-SYSLOG.psd1
PS C:\Users\Sec504\Downloads\DeepBlueCLI>

NOTE: Posh-SYSLOG distributes the PowerShell module as a module manifest data file, which uses the extension [code].psd1[/code] as opposed to the more familiar [code].ps1[/code] extension.

Send Syslog Messages

Press the up arrow a few times to recall that previous [code]DeepBlue.ps1[/code] command, then add [code]Send-SysLogMessage[/code] to the pipeline in the style we saw in the Posh-SYSLOG test case, as shown here:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | ForEach-Object { Send-SyslogMessage -Server '127.0.0.1' -Message "$_.Message - $_.Results" -Severity 'Alert' -Facility 'Local0' }

Let's break down this command step-by-step:

  • [code]\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | [/code]: Run DeepBlueCLI, reading from an EVTX file; start a pipeline
  • [code]ForEach-Object { [/code]: Start a loop for object returned by [code]DeepBlue.ps1[/code], executing the code block until the closing [code]}[/code] for each object
  • [code]Send-SyslogMessage [/code]: Invoke the [code]Send-SyslogMessage[/code] cmdlet, part of the Posh-SYSLOG module
  • [code]-Server '127.0.0.1' [/code]: Specify the destination Syslog server (our Kiwi server at 127.0.0.1 or the local system)
  • [code]-Message "\(_.Message - $_.Results" [/code]: Specify the message to send in the Syslog payload where [code]\)_[/code] is the current object in the [code]ForEach-Object[/code] loop; I opted to concatenate the DeepBlueCLI Message and Results parameter with a hyphen separating the two values using PowerShell string interpolation.
  • [code]-Severity 'Alert' [/code]: Specify the Syslog message severity level
  • [code]-Facility 'Local0'[/code]: Specify the Syslog message facility code
  • [code]}[/code]: End the [code]ForEach-Object[/code] block.

Checking the Kiwi server shows success!

Kiwi Syslog server shows two messages corresponding to the two DeepBlueCLI alerts

The Solution

GitHub ticket response from Josh suggesting the use of Posh-SYSLOG as a solution to the question, followed by a thank you message and a ticket close status.

Success! 🙌

The Add-On Question

Addition to the GitHub ticket, asking

The Add-On Solution

Once you learn some of the constructs of PowerShell like working with the pipeline, and some of the built-in commands such as ConvertTo-JSON, the pieces come together without too much difficulty. The question doesn't specify whether all of the output from DeepBlueCLI should be one JSON blob and one Syslog message, or a different JSON blob and Syslog message for each alert, but we can compose both pretty easily.

First, let's look at taking the DeepBlueCLI output and converting it to JSON. This is pretty straightforward:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | ConvertTo-Json
[
    {
        "Date":  "\/Date(1474429273078)\/",
        "Log":  "Security",
        "EventID":  4688,
        "Message":  "Suspicious Command Line",
        "Results":  "Metasploit-style cmd with pipe (possible use of Meterpreter \u0027getsystem\u0027)\n",
        "Command":  "cmd.exe /c echo hgabms \u003e \\\\.\\pipe\\hgabms",
        "Decoded":  ""
    },
    {
        "Date":  "\/Date(1474429237088)\/",
        "Log":  "Security",
        "EventID":  1102,
        "Message":  "Audit Log Clear",
        "Results":  "The Audit log was cleared.\nAccount Name:\tIEUser",
        "Command":  "",
        "Decoded":  ""
    }
]

JSON isn't always the nicest to look at, but it is a powerful way to encode data for compatibility between applications. Here, sending the DeepBlueCLI output to [code]ConvertTo-Json[/code] in the pipeline is all that is needed to produce JSON-encoded output. Next, we need to send this output with [code]Send-SyslogMessage[/code]. At first, I tried this:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | ConvertTo-Json | Send-SyslogMessage -Server '127.0.0.1' -Severity 'Alert' -Facility 'Local0'
Send-SyslogMessage : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

This produced an error The input object cannot be bound to any parameters for the command. Note to that I didn't specify the [code]-Message[/code] argument in [code]Send-SyslogMessage[/code] in this example -- I hoped that [code]Send-SyslogMessage[/code] would support parameter binding and accept the output of [code]ConvertTo-JSON[/code] as the message. Sadly, this is not a feature of Posh-SYSLOG, but we can work around it.

NOTE: Parameter binding is pretty graceful when it is supported by PowerShell commands. We'll investigate it in another #MOPS article later this month.

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | ConvertTo-JSON -OutVariable json
[
    {
        "Date":  "\/Date(1655033354955)\/",
        "Log":  "Security",
        "EventID":  4672,
        "Message":  "Multiple admin logons for one account",
        "Results":  "Username: Sec504\nUser SID Access Count: 2",
        "Command":  "",
        "Decoded":  ""
    },
    {
        "Date":  "\/Date(1655033354955)\/",
        "Log":  "Security",
        "EventID":  4672,
        "Message":  "Multiple admin logons for one account",
        "Results":  "Username: Sec504\nUser SID Access Count: 2",
        "Command":  "",
        "Decoded":  ""
    }
]
PS C:\Users\Sec504\Downloads\DeepBlueCLI> Send-SyslogMessage -Server '127.0.0.1' -Facility local0 -severity alert -message $json

This solution is written in two PowerShell commands for clarity. Let's break down the first, step-by-step:

  • [code].\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx |[/code] - Run DeepBlueCLI, reading from the specified EVTX file, starting a PowerShell pipeline
  • [code]ConvertTo-JSON[/code] - Convert the data to JSON format
  • [code]-OutVariable json[/code] Display the JSON output to the screen AND save it to a variable called [code]json[/code] (that we can reference as [code]$json[/code] in subsequent commands); [code]-OutVariable[/code] is a common argument, meaning it is almost universally accessible for different PowerShell commands

The next command is similar to what we've seen before except for the [code]-message $json[/code] piece. Here, we're specifying the variable [code]$json[/code] as the message for [code]Send-SyslogMessage[/code] with the other familiar [code]-server[/code], [code]-facility[/code], and [code]-severity[/code] arguments.

Kiwi syslog, showing a single Syslog message consisting of multiple DeepBlueCLI alerts in JSON format

This works, but it sends all of the alerts in a single Syslog message. Since the message size for Syslog is limited to 16,384 bytes (for TCP) and 4,096 bytes (for UDP), this might produce truncated JSON output.

As an alternative, we can use the [code]ForEach-Object[/code] loop again, sending each alert from DeepBlueCLI as a Syslog message:

PS C:\Users\Sec504\Downloads\DeepBlueCLI> .\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx | ForEach-Object { $_ | ConvertTo-Json -outvariable json ; Send-SyslogMessage -Server '127.0.0.1' -Facility local0 -severity alert -message $json }
{
    "Date":  "\/Date(1474429273078)\/",
    "Log":  "Security",
    "EventID":  4688,
    "Message":  "Suspicious Command Line",
    "Results":  "Metasploit-style cmd with pipe (possible use of Meterpreter \u0027getsystem\u0027)\n",
    "Command":  "cmd.exe /c echo hgabms \u003e \\\\.\\pipe\\hgabms",
    "Decoded":  ""
}
{
    "Date":  "\/Date(1474429237088)\/",
    "Log":  "Security",
    "EventID":  1102,
    "Message":  "Audit Log Clear",
    "Results":  "The Audit log was cleared.\nAccount Name:\tIEUser",
    "Command":  "",
    "Decoded":  ""
}

Let's break this command down step-by-step as well:

  • [code].\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx |[/code] - Run DeepBlueCLI, reading from the specified EVTX file, starting a PowerShell pipeline
  • [code]ForEach-Object { [/code]: Start a loop for object returned by [code]DeepBlue.ps1[/code], executing the code block until the closing [code]}[/code] for each object
  • [code]\(_ | [/code]: Use the current object [code]\)_[/code], starting another pipeline, independent of the earlier one because it is in the [code]{}[/code] block
  • [code]ConvertTo-Json -outvariable json[/code]: Convert the object (the DeepBlueCLI alert) into JSON, saving it in a variable called [code]json[/code]
  • [code];[/code]: End the pipeline, starting a new command -- still within the [code]ForEach-Object[/code] block [code]{}[/code]
  • [code]Send-SyslogMessage -Server '127.0.0.1' -Facility local0 -severity alert -message $json[/code]: Send a syslog message with the message using the [code]$json[/code] variable
  • [code]}[/code]: End the [code]ForEach-Object[/code] block

Personally I think this works a little nicer, and it keeps the message size down for the Syslog messages.

Kiwi syslog, showing a two Syslog messages in JSON format, one for each DeepBlueCLI alert

Again here, developing some understanding of the PowerShell pipeline and looping using [code]ForEach-Object[/code] gives you a lot of flexibility to solve your tasks.

GitHub ticket from @therajvira stating

The Takeaway

There's a lot of great community support for PowerShell. This is one of my favorite things about Python as my preferred programming language too: someone else has probably already done what you need to do. It's often just a matter of finding the solution that will work for you, and copy/transform/combine to produce the best solution that will work for you.

Summary

In this article we look a look at a problem: How can we take the output of DeepBlueCLI and send it via Syslog? After a quick search we discovered the Posh-SYSLOG module, and even some test cases quickly revealed sample use. Then it was a matter of putting it into practice, testing with a sample Syslog server to verify functionality. We also looked at a follow-on request to convert the Syslog message to JSON format, building on the [code]Send-SyslogMessage[/code] functionality using [code]ConvertTo-Json[/code]. Throughout, we leveraged the PowerShell pipeline as the building blocks to make the challenging, attainable.

Until next time!

-Joshua Wright

Return to Getting Started With PowerShell


Joshua Wright is the author of SANS SEC504: Hacker Tools, Techniques, and Incident Handling, a faculty fellow for the SANS Institute, and a senior technical director at Counter Hack.

Month of PowerShell: Solving Problems (DeepBlueCLI, Syslog, and JSON) | SANS Institute