Security Operations Platform arrow_forward expand_more
Solutions arrow_forward expand_more
Why Chronicle arrow_forward expand_more
Why Chronicle

Rely on a modern approach to threat detection and response.

Why Chronicle
Partners arrow_forward expand_more
Resources arrow_forward expand_more
Security Operations Platform arrow_forward expand_more
Solutions arrow_forward expand_more
Why Chronicle arrow_forward expand_more
Why Chronicle

Rely on a modern approach to threat detection and response.

Why Chronicle
Partners arrow_forward expand_more
Resources arrow_forward expand_more
IDC Study: Customers cite 407% ROI with Google Chronicle. Learn More IDC Study: Customers cite 407% ROI with Google Chronicle. .
New to Chronicle: User Mailbag, Part 2

"New to Chronicle" is a deep-dive series by Google Cloud Principal Security Strategist John Stoner which provides practical guidance for security teams that are either new to SIEM or replacing their SIEM with Chronicle. You can view the entire series here.

This month we are dedicating New To Chronicle to common questions we receive from users. Let's dive into this second edition of User Mailbag.

How can I avoid syntax errors when building a rule against a list of suspicious ports?

I understand the pain that this one causes but there is a straightforward method to address this. Let’s start with the port fields. The UDM field list defines port fields as integer fields. This means that when they are used in search or rules, they are defined as the value itself whereas string fields will be enclosed in quotes. Here is a search to illustrate the different syntax used.

Taking this a step further, reference lists are expecting strings, but as we just mentioned, a port is an integer, not a string. The solution to this is to use the strings.concat function which will convert our integer to a string which can then be compared to a string reference list.

strings.concat($net.target.port,"") = $target_port $target_port in %suspicious_ports

Admittedly this rule is overly simplified and will need to be improved to identify network traffic flow, netblocks and more, but this will provide a good starting point. In the events section, we can use the strings.concat function to output the port value we are interested in, append a null string to it and output it to a placeholder variable. In the following line, we then take that placeholder variable and compare that to our list called suspicious_ports.

In our test rule results, we can see that ports including 135 and 445 are returned which align to the listing of ports in our list.

Can you clarify how logical operators and/or/not work together with parentheses?

We won’t be able to cover every permutation here, but here are a few tips that should help. 

  • If you are just using and between all criteria in the events section, nothing is required as the and operator is implied. 

  • If you are looking for two different values for the same field, use the or to separate them.

  • If you need to group fields together to build your conditions with parenthesis, operators are always required within the parenthesis. That goes for and as well as or.

This last bullet is what we are highlighting below. Here are a few different methods to identify an event log being cleared from a Windows system.

Lines 17-21 contain one method, 23-26 a second and 28-36 a third. Notice how each one is bounded with parenthesis and how each uses and/or to separate terms. If we don’t do this, that nice little green check mark in the corner turns red and we can’t save our rule.

Digging a little deeper into our third method, we can see that we have three distinct values we are looking for in specific fields and then we have two additional regular expression strings and we are expecting one or the other to meet this specific set of conditions. Notice that we have a parenthesis around those two pieces of criteria (lines 33-34) nested within the larger criteria and how we are using and/or throughout our criteria. Finally, notice that line 37 is outside of all the parenthesis and applies to any of the three methods listed above it. Because we are outside of the parentheses, we are back in a place where the and operator is assumed.

Pro tip: Using tabs to stagger criteria in the events section provides a nice way to visualize multiple sets of criteria and to more easily track where your and/or/not operators should be.

I was reading the CISA Joint Advisory on Living off the Land and wanted to build a detection similar to what was described in the Impacket section. Can you help?

Absolutely. In the Impacket section of the CISA Joint Advisory, it references the use of wmiexec which redirects output to a file containing an epoch timestamp for its name. In the example below, a command was executed by wmiexec.py and the logged event included a command line that looks like this: 

cmd.exe /Q /c dir 1> \\127.0.0.1\ADMIN$\__1684956600.123456 2>&1

The first thing to mention is that if you want to get familiar with Impacket (or any other tool), it’s best to load and test it to experience the different logs that it generates in your environment. That said, if we wanted to build a strict match, we could start our pattern with the cmd.exe. The problem with that approach is 1) PowerShell can be used as well, 2) even if you encounter cmd.exe /Q /c , the command that follows it could be just about anything and 3) cmd.exe /Q /c could be used legitimately. With that in mind, let’s start our match after the command is issued. Because wmiexe.py is using command redirection to the admin$ share, we could build a regular expression that starts with 1> and ends with 2>&1. Additional variation is possible, but for now, we will keep the admin$ share in our regular expression for the purpose of this example.

It is important to note that greater than (>), is stored in Chronicle as &gt;, less than (<) as &lt; and ampersand (&) as &amp;. So our regular expression will look something like this; 

re.regex($process.target.process.command_line, `1&gt;.*\\ADMIN\$\\__.*2&gt;&amp;1`) nocase

Pro tip: When working with command lines, always leverage the modifier nocase. I like using nocase on most non-enumerated fields, but always use it with command line.

This is why I mention ingesting sample data if possible. If we ingested the data into our Chronicle instance, we would see that the command_line value is stored in Chronicle like this:

target.process.command_line = "cmd.exe /Q /c dir c:\\windows 1&gt; \\\\127.0.0.1\\ADMIN$\\__1689025024.9777138 2&gt;&amp;1"

Of course, there are variations but this serves as a good place to start when building our detection for wmiexec.py. Here are the results of our test rule.

That last question was a bit heavier than I intended but hopefully these topics from the mailbag were helpful and can be applied to your rule writing moving forward!

New to Chronicle Series

Let’s work together

Ready for Google-speed threat detection and response?

Contact us Visit the contact us page