New to Google SecOps: Single event rules

jstoner
Staff

The “New to Chronicle” blog found on chronicle.security has moved to the Community Blog. This blog was originally published on August 18th, 2022 by John Stoner. Going forward, all Google Security Operations (formerly known as Chronicle Security Operations) blogs will be published here. 

This is the second post from Google Cloud Principal Security Strategist John Stoner as part of his deep-dive "New to Google SecOps" series, which helps propel security teams either new to SIEM or replacing their SIEM with Google SecOps.

The rules engine is a fundamental component of Google SecOps. Ingesting and searching data is important, but if you cannot generate detection events, analysts are left with petabytes of data to search through without a specific focus or prioritization.

Our goal today is to introduce you to the Google SecOps rules engine and explore the capabilities it provides. This blog post is the tip of the iceberg in regard to the rules engine. Subsequent posts will go deeper into the engine so if you don’t see exactly what you are looking for today, don’t worry, there is more to come!

The rules engine in Google SecOps uses a language called YARA-L to build detections. For those not familiar with YARA, it is the language that Google’s VirusTotal team developed for use with malware samples. The concepts of YARA have been adapted to focus on logs and its associated telemetry, and we call it YARA-L.

YARA-L can be used for detection as events are being ingested and it can be used to look retrospectively across historical data. This provides analysts with flexibility to develop new detections and use historical data to validate and test rules, as well as uncover threats that were not previously known.

YARA-L has a fixed format of sections used when creating rules. While there are six sections as of today, only three are required to get started. Let's focus just on the components needed to write a single event rule. In future posts, we will cover the additional areas as we build increasingly robust rules.

The three required sections of any YARA-L rule are the meta, events, and condition sections.

  • Meta contains the metadata associated with the rule itself.
  • Events contain the UDM fields and their associated values that are being evaluated to determine if criteria exist for the rule to fire.
  • Condition specifies the circumstances that would cause the rule to fire. (Spoiler alert, this is really simple for a single event rule, but gets a lot more fun for multi-event rules!)

Let’s take a look at an example to see how this works. In this example, we want to detect adversaries who are searching the Windows Registry for credentials that may be stored there. This rule is based on the MITRE ATT&CK technique, Unsecured Credentials: Credentials in Registry. This rule was originally written by the team at SOC Prime and was converted from Sigma. I adapted it to reflect the current technique and sub-technique. I also adapted the event section for greater precision.

Meta

In the meta section, we have a number of fields defined, including the author of the rule, a description of what the rule does, and the severity of the rule. We added a 'last_updated' field as well, as well as additional specificity around the ATT&CK tactic and technique that we are attempting to detect.

ntc-single-rule-01.png

This metadata can be seen when viewing the rule detections.

ntc-single-rule-02.png

This view provides that summary information at the top of the page and the detections that fired.

Events

The event section contains the criteria that needs to be observed within the logs for the detection to fire. Each item in the event section that is being evaluated will be prepended by a variable. In our example, you can see the string $process is prepended to our UDM fields. This event variable is arbitrary, but establishing a common taxonomy for your organization is important as you build out your rules.

Wait, what’s an entity field? Don’t worry, we will get to entity fields in a future post.

ntc-single-rule-03.png

As we start introducing multiple events into our rules, having that common taxonomy will become important.

Three operators are available to connect criteria together. They are and, or, and not. By default, and is assumed in the absence of other operators. In fact, in the example above, with one piece of criteria on each line, YARA-L reads this as:

 

 

 

$process.metadata.event_type = "PROCESS_LAUNCH" and $process.target.process.file.full_path = /reg.exe/

 

 

Parenthesis can also be used to group items together. The final two lines in our example contain two different registry queries, and the existence of either one will trigger our rule to fire. We can bind them with parenthesis and separate them with the operator or.

 

 

(
$process.target.process.command_line = /reg.*query HKLM \/f password \/t REG_SZ \/s/ nocase or 
$process.target.process.command_line = /reg.*query HKCU \/f password \/t REG_SZ \/s/ nocase
)

 

 

The 'not operator' provides a way to exclude certain criteria from consideration. If we wanted to exclude a specific user or specific host from consideration, the not operator could be prepended to the event criteria.

Search criteria can take the form of a string match as we see in the first line.

 

 

$process.metadata.event_type = "PROCESS_LAUNCH"

 

 

Regular expression matching is also possible. Chronicle uses RE2 for those who are aficionados of regular expressions. Sadly, I’m not, but I digress. There are functions for regular expressions that will be discussed in a future blog but we can use forward slashes around a value to denote a regular expression. We can add '.*' to handle variability in spaces, file extensions, or other unpredictability within the values that we are searching in our criteria. Because the forward slash is used to bound our search term and denote a regular expression, backslashes are used as escape characters to indicate that forward slashes within the string are to be treated as a forward slash and not as the end of a regular expression.

 

 

$process.target.process.command_line = /reg.*query HKLM \/f password \/t REG_SZ \/s/

 

 

If we wanted to loosen our search terms to find greater variability in our events, we could add additional .* between our values. We can also add the modifier nocase to the end of our expression to insulate ourselves against adversaries mixing their case in their commands.

 

 

(
$process.target.process.command_line = /reg.*query HKLM \/f password \/t REG_SZ \/s/ nocase or 
$process.target.process.command_line = /reg.*query HKCU \/f password \/t REG_SZ \/s/ nocase
)

 

 

Condition

The final mandatory section, and the last one we will talk about today, is the condition section. Now, for a single event rule, the condition section is kind of boring. It is basically going to be $process or whatever the variable we are using for the event itself. When we get to multi-event rules, this will get more interesting.

ntc-single-rule-04.png

With that, we have a single event rule. But before deploying it, perhaps we want to test it against our events to ensure we are getting detections that we expect. Google SecOps has us covered with the test rule capability within the rule editor.

ntc-single-rule-05.png

Simply specify the time range and click 'Run Test' and the rule will run against our data during the time period specified and return any detections. We can also drill into both the raw and UDM event to see the underlying data and can further refine our rule as needed.

I hope this provides you a good understanding around how a rule is created. While this was a relatively simple example, building a good foundation is important, and the concepts covered here will make it easier as we move into more robust rule development. If you want to learn more about YARA-L, check out our syntax guide.

Until next time!

2 0 2,449
Authors