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: A potpourri of functions

This is the 11th 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. You can view the entire series here.

With the holiday season now behind us, I felt like a nice potpourri of functions would be an apt way to wrap up this segment of our "New to Chronicle" series. That’s not to say we are going away. In this new year, we'll be getting into entities and contextual awareness, but after spending much of the fall with regular expressions, lists and other functions, it made sense to cover a mixture of the remaining functions.

In case you are late to the party, here is a quick summary of the blogs that covered the other functions already, so in case you are looking for your favorite and don’t see it here, you can quickly find an example.

String Concatenation

Alright, let’s start with string concatenation. This can be used in a few different ways as you build your rule. We can take strings, integers or a combination and fuse them together for use in a rule. By the way, when I say string that could be a string from a UDM field or it could be a constant, though the constant needs to have quotes around it. Much like other functions, they can be nested together and can be compared to other values or used as placeholder or match variables.

Here’s a little trick that I have found useful when working with lists. Reference lists are looking for strings, but perhaps you have a rule where you want to compare the port number from the event to a list of known good (or known bad) ports. You can use strings.concat to convert that port number to a string and then do your list comparison.

In this example, we are looking at network connections coming from a GCP firewall, over TCP that have a target port value that is less than 49152. Why 49152? Ports up to 49151 are user or registered ports. We have a list of known “good” ports called acceptable_ports and using the strings.concat function, we are converting the numeric port to a string that is then compared to the acceptable port list. With the not operator in front of that line of criteria, we can return events that contain ports that are not on the list. Finally, we are concatenating the constant TCP with the port and using that as a grouping mechanism over 30 minutes in the match section. This rule could be further evolved using the network CIDR function.

rule port_watcher {

meta: author = "Google Cloud Security" description = "8:00 AM local time" severity = "Low"

events: $event.metadata.event_type = "NETWORK_CONNECTION" $event.metadata.vendor_name = "Google Cloud Platform" $event.metadata.product_name = "GCP Firewall" $event.network.ip_protocol = "TCP" $event.target.port < 49152 not strings.concat($event.target.port,"") in %acceptable_ports $portprotocol = strings.concat("TCP", $event.target.port) match: $portprotocol over 30m

condition: $event }

Absolute Value

We’ve talked about the outcome section in an earlier blog, so I am not going to get into the aggregate functions like count and count_distinct and stay focused on functions. The math.abs function returns an absolute value which could be compared to a value or used with a placeholder variable, as we have in the example below. 

I will admit that with a little thought I could probably arrange my ingest and event timestamps in such a way to always ensure that the larger value always goes first in my calculation, but the use of math.abs takes that concern away and when working with other fields where there may be less predictability, this can be a nice function to have in your toolkit. 

This example measures the ingestion latency of events coming from Microsoft O365 and Azure and triggers when the ingestion time exceeds 20 minutes from the time of the event. We have filtered on specific events to focus our rule and then calculated the time difference with our function. We can see the results of this rule below with events grouped by the product_name within a 30 minute window along with the latency in seconds as well as the ingestion and event timestamps.

rule latency_cloud_collection {

meta: author = "GCP Cloud Security" description = "Detect Latency from Cloud Based Event Sources" severity = "Low"

events: $event.metadata.vendor_name = "Microsoft" ($event.metadata.product_name = "Azure AD" or $event.metadata.product_name = "Office 365" or $event.metadata.product_name = "Azure AD Directory Audit") not $event.target.user.email_addresses = "sync_win-adfs_faeb54d7a0af@th7sz.onmicrosoft.com" nocase not $event.target.application = "SecurityComplianceCenter" $event.metadata.product_name = $productName $latency = math.abs($event.metadata.ingested_timestamp.seconds - $event.metadata.event_timestamp.seconds) $latency > 1200

match: $productName over 30m

outcome: $latency_seconds = max($latency)

condition: $event }

Date Functions

The last section of our potpourri of functions is around dates. No, not the chewy, sweet kind that can be found in supermarkets. Date functions, when applied to rules, can be used to focus on certain time windows. Perhaps you want to look for certain activities on the weekend that would be considered normal during the week. No problem, add this line to your events section and use the timestamp.get_day_of_week function where Sunday is 1 and Saturday is 7.  

timestamp.get_day_of_week($e.metadata.event_timestamp.seconds)= 1 or timestamp.get_day_of_week($e.metadata.event_timestamp.seconds)= 7

You can even return a specific week, the current seconds or focus on a specific minute. If you have an administrative task that kicks off at a specific hour and minute that you wanted to track or suppress, a combination of timestamp.get_hour and timestamp.get_minute functions could be used. In this example, we are detecting remote desktop inbound traffic and focusing our rule on after hours successful connections. Our time range is essentially 2200 UTC through the night to 0359 UTC. 

rule rdp_allow_traffic {  meta:    author = "Google Cloud Security"    description = "Detect RDP Inbound Traffic to Network"    severity = "Medium"  events:    $e.metadata.event_type = "NETWORK_CONNECTION"    not net.ip_in_range_cidr($e.principal.ip, "10.0.0.0/8")    $e.principal.ip = $principalIP    $e.security_result.action = "ALLOW"    $e.network.direction = "INBOUND"    net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")    $e.target.ip = $targetIP    $e.target.port = 3389    (timestamp.get_hour($e.metadata.event_timestamp.seconds) > 21 or        timestamp.get_hour($e.metadata.event_timestamp.seconds) < 4)  match:    $principalIP, $targetIP over 1h  condition:    $e }

Yes, maybe that would be the time you would expect RDP connections to occur, but stick with me for a minute.

All of the date functions can also be used with time zones. As you all likely know, Chronicle captures functions in UTC, which is a wonderful thing, but suppose you want to build a rule and utilize a different timezone. When you use the date functions, you can! Now, the formatting of the time zone is not going to be EST (for eastern standard time), it follows the naming in the TZ database. If we take our rule above, we could take the line in bold and write an equivalent line of criteria like this: 

(timestamp.get_hour($e.metadata.event_timestamp.seconds, "America/New_York")> 16 or timestamp.get_hour($e.metadata.event_timestamp.seconds, "America/New_York") < 9)

Running the rule with either line returns the same data, the difference is that the function will do the calculation to UTC for you based on the timezone specified. If you don’t want to deal with time zones, no problem, it is an optional value in the function and by default, Chronicle uses UTC.

This wraps up our potpourri edition of YARA-L functions within Chronicle. I hope this, combined with our earlier posts, provides you a better understanding of how Chronicle functions can be used to write better and more precise YARA-L rules. As we move into the new year, we will continue to explore Chronicle and its many capabilities!

New to Chronicle Series

Let’s work together

Ready for Google-speed threat detection and response?

Contact us Visit the contact us page