This is the third post from Google Cloud Principal Security Strategist John Stoner as part of his deep-dive "New to Chronicle" series, which helps propel forward security teams either new to SIEM or replacing their SIEM with Chronicle.
We hope you have enjoyed our initial installments of the "New to Chronicle" series and have gotten an opportunity to try the techniques we discussed in our previous post about single event rules.
Our post today will focus on building multi-event rules, and we will take the concepts that we previously discussed around single event rules and build on them to enhance our coverage. That said, this isn’t the end of our rules journey. Future posts will continue to extend this functionality, so as I said before, if this doesn’t answer all your questions, don’t worry, we will continue adding additional guidance!
Building multi-event searches is pretty straightforward because at its heart, it adds one additional section to our YARA-L rule. If you recall, all rules have meta, events, and condition sections. Multi-event rules add a match section to the rule. At its most basic, the match section is going to group events by one or more fields across a time window that you specify.
When working with multiple events, you need to establish commonality between the events to bind them together. For example, if you are looking for two kinds of events on the same system, you might establish the hostname as the common field. In other cases, you might look for both the username and the hostname.
In our previous blog, we introduced event variables which are prepended to each field in the events section of the rule. With the addition of the multi-event rule, we are going to also introduce placeholder and match variables that we will use within our rule.
Another new concept that we are going to cover are time windows. Time windows help Chronicle constrain the amount of data that is being looked at to determine if a rule should fire or not. There are two different kinds of time windows. The first is a hop and the second is a sliding window.
The default hop window takes into account all events that match our criteria during the time window but it does not take into account the order that the events occurred. Sliding windows will focus on a specific event order, but this does have a performance impact. The syntax for sliding windows is slightly different. When I say "different," I mean it takes into account an initial trigger event that you can think of as a “stake in the ground” that other events must occur before or after for the rule to trigger.
With these concepts laid out, let’s look at an example. Let’s say you want to build a rule to detect temporary accounts being utilized. Specifically, the use case is that you want to detect when an account has been created, used to login, and then deleted. For our purposes, we will define our threshold for these events to occur within four hours, but this time range can be adjusted based on what you define as a temporary account. The match condition time range can range from one minute to 48 hours, so there is a good deal of flexibility to work with.
Because we covered the meta section in our previous post and nothing fundamentally changes here, we aren’t going to cover that in our example. The events section will include our event criteria for each of our events; account creation, user login and account deletion. Fortunately, we can use the metadata.event_type enumerated values of USER_CREATION, USER_LOGIN and USER_DELETION to denote each one of these events.
$create.metadata.event_type = "USER_CREATION"
$create.target.user.userid = $targetUser
$create.metadata.event_timestamp.seconds <= $login.metadata.event_timestamp.seconds
$login.metadata.event_type = "USER_LOGIN"
$login.target.user.userid = $targetUser
$login.metadata.event_timestamp.seconds <= $delete.metadata.event_timestamp.seconds
$delete.metadata.event_type = "USER_DELETION"
$delete.target.user.userid = $targetUser
Unlike in the single event rule, we need to differentiate these three events from one another, so our event variables are going to be unique from one another. We could use '$e1' or '$selection' or any other name to describe each event, but a concise, descriptive variable name will pay dividends down the road. That is foreshadowing, so stick with me. We will use '$create,' '$login' and '$delete' to describe each of these three events.
The second line of criteria under each of the three 'metadata.event_type fields' is what is called a placeholder variable. The idea behind the placeholder variable is to take the value of a field in an event, in this case the target.user.userid field and write it to a variable that can be used elsewhere in our rule. This is done for each of the three events because we will need to link them together. You might be thinking, does this field need to be the same field in all events? The answer there is no, it can be any field, but in this example, it is the same field.
The final pieces of criteria in the events section are the two less than or equal to statements that are comparing times. These two lines of criteria allow us to order the create event before the login event and the login event before the delete event.
You might be thinking, 'What about the talk of sliding windows. Why don’t you just use that?' Well, there is no reason you couldn’t use it, but because you are looking for a specific order across all events, you can enforce greater control by saying create comes first, then login, and then deletion based on the event timestamp. You can just collect all the events in the window and evaluate it together!
With our event criteria specified, we are going to move to the match section. The match section is where we will use our match variable. Now, the match variable looks like the placeholder variable from the events section. That’s because it is the same but this is where it is used to join, our distinct events together.
If we had multiple fields to join, we would have multiple placeholder variables defined in the events section and multiple match variables, separated by a comma in the match section.
$targetUser over 4h
$create and $login and $delete
The condition section is a bit more robust than what we saw in a single event role, but it is still pretty straightforward. Our condition is that we need at least one event of each type; create, login and delete to exist for our rule to fire. This is why we have all three event variables in the condition, separated by the operator and.
Wait a second, that’s not very descriptive. OK, fair, but if we click the '> 'sign next to the detection we get this:
If we look back at our events section, we can see that we have our 'metadata.event_type' values in the purple boxes ordered. We can see our placeholder and match variable representing the 'target.user.userid' for each event, and in this case the temporary account that was created is named Alice.Jones.
We added a column for the product event codes so we could see the Windows event codes for those familiar with them, but that is just for reference. Now, check out the black boxes under the detection column. Notice that they say Create, Login and Delete. Hey, we’ve seen these terms before! That’s right, they are the event variables. By using brief but descriptive terms for event variables, our analysts can benefit from that when looking at the detection and quickly understanding the context around the detections and the underlying events they are looking at.
Just like single event rules, multi-event rules can be set to run on a frequency. As mentioned before, there are three distinct frequencies that can be set in the UI.
With that, it’s time to wrap this up. We now have a rule to detect creation, login, and deletion of a temporary accountand hopefully a better understanding around how you can create your own multi-event rules.
Until next time!