New to Google SecOps: Building Rules with Your Own Threat Intel Part 1

jstoner
Staff

"New to Google SecOps" 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 Google SecOps.

Threat intelligence is a critical component of security operations. But how does Google SecOps leverage threat intelligence? That, dear reader, is a topic that we will start to tackle today. In fact, to ensure a solid foundation around building rules with threat intelligence indicators, we will spend the next two posts demonstrating this concept.

Rather than bounce all over the threat intelligence landscape, we are going to focus on working with Malware Information Sharing Platform (MISP). The concepts we’ll demonstrate here can be applied to your threat intelligence source like Anomali, Recorded Future or Digital Shadows. The key is that we are ingesting the indicators into the Entity Graph and building rules from there.

You may have noticed that my recent posts discussing rule writing in Google SecOps involve the entity graph. That’s because the entity graph is such a powerful capability. While Google SecOps ingests events, it also leverages contextual information in the form of assets, users, threat indicators and much more from the entity graph. Two of our previous blogs highlighted this, first with context in general and then by applying it to rules.

When we use the term indicator, it is in reference to IP addresses, file hashes, domain names, URLs and mutexes. If you want to search for a specific indicator and view the underlying entity log, you can do this from our landing page.

We begin with the assumption that our MISP indicators have been ingested into Google SecOps already. Threat intelligence may be ingested with a forwarder or via Feed Management depending on the source of the data.

ntc-ti1-01.png

Notice how we are specifying the search to focus on the MISP Threat Intelligence log source. Also notice that Google SecOps recognizes that the value entered is a domain. You can also look at an investigation dashboard around this specific domain, but for now, we just want to view the entity event itself.

ntc-ti1-02.png

Our search returned the raw event that Google SecOps ingested from MISP and the parsed entity event. Knowing where values are parsed is important when it comes to rule writing, so I consider this a good first step to understand what our threat intelligence data looks like.

Notice in the parsed entity information on the right side of the image, we have both a metadata.vendor_name and metadata.product_name of MISP, a metadata.entity_type of DOMAIN_NAME and a number of fields that describe the entity. All of these values are derived from the MISP instance. At the bottom of the image, the entity.hostname field contains the key value that will be used to associate UDM events to the entity.

Using this indicator as a template, we are going to build a rule to detect events correlating with the domain threat indicators. For our rule, we are going to detect network DNS events making a request for one of these suspicious DNS domains that exist in our MISP instance. Because we are joining UDM events to IOCs, this rule is treated as a multi-event rule. Remember, whenever we join UDM events to the entity graph, it is always treated as a multi-event rule.

ntc-ti1-03.png

On lines 8-9 of our rule, the criteria for our DNS events is straightforward; the metadata.event_type is NETWORK_DNS and the value of the network.dns.questions.name field is written to the placeholder variable $dns_query. Placeholder variables can be named anything we want however, they should be descriptive because they will be used to join disparate events together.

The next set of criteria pertain to the MISP data. We are using the event variable of $ioc to describe this data set as IOCs. Because we want to focus our correlation to just the MISP data, we can use the field metadata.product_name to return only indicators with a value of MISP (line 12). If we have multiple sources of threat intelligence indicators, this line could be considered optional or alternatively, we could specify multiple product (or vendor names) separated by an OR statement. 

Line 13 is important because we want to focus our correlation on the metadata.entity_type of DOMAIN_NAME. This enumerated value serves as a way to take all of the data in the entity graph and narrow it down to domains for the join event. Adding this line will improve your rule performance. The metadata.source_type should be set to ENTITY_CONTEXT on line 14. You may be thinking to yourself, “Self, if I specify a product name or a vendor name, do I need to go to the trouble of specifying metadata.source_type?” It’s a fair question, but as we investigate other capabilities and data sets within the entity graph, we will uncover other metadata.source_type values. Setting this field in your rule will allow you to maintain focus on ingested threat intelligence indicators rather than other entity data that Google is providing or deriving.

The metadata.threat.summary field on line 16 is used to focus on identified C2 domains from the MISP data. This field (and others like it) are optional and are really used to sculpt your rule to focus on a specific class of indicator or a threat family or some other field that contextualizes your threat intelligence. If you want to correlate all of your MISP domain values, you can ignore this line of criteria. Last but certainly not least is the entity.hostname field on line 17 that contains the same placeholder variable that we specified in our DNS event and will join our indicators to our events.

If you are a devoted reader of this blog, you will recall the match section is required when building a multi-event rule. A time window is specified for the rule to collect events that match our criteria before triggering. In our example, we are looking for multiple network DNS requests with the same network.dns.questions.name value over a 5 minute period and rolling them into a single detection. So far so good?   The match variable, $dnsQuery, is used to associate our events and IOCs together, but the time window only applies to other events, not the entity data. The entity data has its own time window driven by the metadata.interval.start_time and metadata.interval.end_time that apply to the indicator, and as long as the time that we run our rule is within this time range, our indicator is valid. The condition section contains both of our event variables separated by an AND, because we need both event variables to exist for the rule to trigger.

rule ioc_domain_C2 {
 
  meta:
    author = "Google Cloud Security"
    description = "Detect DNS events that indicate communication to a C2 domain in MISP"
 
  events:
    $dns.metadata.event_type = "NETWORK_DNS"
    $dns.network.dns.questions.name = $dns_query

    // Correlates with MISP data; can be modified based on your MISP parser or other TI
    $ioc.graph.metadata.product_name = "MISP"
    $ioc.graph.metadata.entity_type = "DOMAIN_NAME"
    $ioc.graph.metadata.source_type = "ENTITY_CONTEXT"
    //Summary is used to focus on a specific subset of MISP indicators, can modify as needed
    $ioc.graph.metadata.threat.summary = "C2 domains"
    $ioc.graph.entity.hostname = $dns_query
 
  match:
    $dns_query over 5m

  condition:
    $dns and $ioc
}

Here we can see the detection with the underlying events and the associated entity. When we review our entity data, we can see the matching value along with our MISP context that describes the domain threat indicator.

ntc-ti1-04.png

Alright, that was a lot of information, but I hope that provides a solid foundation for building threat indicator rules. Our next blog will pick up here and address how we can take this rule template and easily customize it for other indicators as well as enriching the output of the rule!