Skip to main content

Hi Team,

I'm trying to build some example YARA-L Metrics functions and one of the ones is resource_read_success/resource_read_fail. There's something strange about this one because in the documented supported filters it says principal.user (which is a proto not a string) and not the usual principal.user.userid which is a string. 

When I try to use principal.user in various flavors it starts giving random errors. Using principal.user.userid doesn't work because it says it excepts message not string, using principal.user doesn't complain but says that message can't be compared to string. If i try to capture the principal.user as $user then it says i can't use message as a match variable. I can't win!

In general using principal.user seems like a bug but maybe there's a way of using it that we are just not aware of. 

Here is a sample rule below:

rule aws101_increase_in_api_usage {
meta:
author = "Citreno"
description = "UEBA - monitors a large increase in API calls from a specific users"
data_source = "AWS,AZURE_ACTIVITY,GCP_CLOUDAUDIT"
severity = "Low"


events:
$attempt.metadata.log_type = "AWS_CLOUDTRAIL"
$attempt.metadata.event_type = "RESOURCE_READ"
$attempt.security_result.action = "ALLOW"
$attempt.principal.user.userid = $user


match:
$user over 1d


outcome:
// UEBA metrics and additional fields to help establish thresholds for the condition
$avg_access = max(metrics.resource_read_success(
period:1d, window:30d,
metric:event_count_sum,
agg:avg,
metadata.vendor_name: "AMAZON",
principal.user: $user
))
$avg_access_10x = 10 * $avg_access
$latest_access = count($attempt.metadata.event_type)

condition:
$attempt and $latest_access > $avg_access_10x and $avg_access > 0
}

But then I though maybe we can try with something that doesn't use a proto as a filter so tried with target.resource.name which is a documented supported filter, alas an "unsupported filter" error occurs again.

  • validating intermediate representation: unsupported filters for metric RESOURCE_READ_SUCCESS
    line: 23
    column: 28-49

This is the sample YARA-L:

rule aws101_increase_in_api_usage {
meta:
author = "Citreno"
description = "UEBA - monitors a large increase in API calls from a specific users"
data_source = "AWS,AZURE_ACTIVITY,GCP_CLOUDAUDIT"
severity = "Low"


events:
$attempt.metadata.log_type = "AWS_CLOUDTRAIL"
$attempt.metadata.event_type = "RESOURCE_READ"
$attempt.security_result.action = "ALLOW"
$attempt.target.resource.name = $resource



match:
$resource over 1d


outcome:
// UEBA metrics and additional fields to help establish thresholds for the condition
$avg_access = max(metrics.resource_read_success(
period:1d, window:30d,
metric:event_count_sum,
agg:avg,
metadata.vendor_name: "AMAZON",
metadata.product_name: "AWS CloudTrail",
target.resource.name: $resource
))
$avg_access_10x = 10 * $avg_access
$latest_access = count($attempt.metadata.event_type)

condition:
$attempt and $latest_access > $avg_access_10x and $avg_access > 0
}

I read through all of @jstoner 's wonderful blogs around metrics functions, but resource_read examples are not present and i strongly suspect there's a bug either in the documentation of these examples or the implementation of this specific metric. It's probably likely the documentation, since there are already curated rules for this, but alas their logic is not visible. 

Any help is appreciated!

Hello, 


Which curated detection are you speaking of here.   


Hey, sorry you're running into this. It's definitely a documentation bug; we'll get that cleaned up.


For your first example, try this:


events:
$attempt.metadata.log_type = "AWS_CLOUDTRAIL"
$attempt.metadata.event_type = "RESOURCE_READ"
$attempt.security_result.action = "ALLOW"

$user = $attempt.principal.user.userid
$vendor_name = $attempt.metadata.vendor_name
$product_name = $attempt.metadata.product_name

match:
$user, $vendor_name, $product_name over 1d

outcome:
$avg_access = max(metrics.resource_read_success(
period:1d, window:30d,
metric:event_count_sum,
agg:avg,
metadata.product_name: $product_name,
metadata.vendor_name: $vendor_name,
principal.user.userid: $user
))


The correct list of fields should be:


- principal.user.email_addresses, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, metadata.vendor_name, metadata.product_name
- principal.user.userid, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.userid, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.application, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.application, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.application, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.application, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.application, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- target.user.email_addresses, metadata.vendor_name, metadata.product_name
- target.user.employee_id, metadata.vendor_name, metadata.product_name
- target.user.product_object_id, metadata.vendor_name, metadata.product_name
- target.user.userid, metadata.vendor_name, metadata.product_name
- target.user.windows_sid, metadata.vendor_name, metadata.product_name


Hey, sorry you're running into this. It's definitely a documentation bug; we'll get that cleaned up.


For your first example, try this:


events:
$attempt.metadata.log_type = "AWS_CLOUDTRAIL"
$attempt.metadata.event_type = "RESOURCE_READ"
$attempt.security_result.action = "ALLOW"

$user = $attempt.principal.user.userid
$vendor_name = $attempt.metadata.vendor_name
$product_name = $attempt.metadata.product_name

match:
$user, $vendor_name, $product_name over 1d

outcome:
$avg_access = max(metrics.resource_read_success(
period:1d, window:30d,
metric:event_count_sum,
agg:avg,
metadata.product_name: $product_name,
metadata.vendor_name: $vendor_name,
principal.user.userid: $user
))


The correct list of fields should be:


- principal.user.email_addresses, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, metadata.vendor_name, metadata.product_name
- principal.user.userid, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.userid, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, principal.ip, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.application, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.application, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.application, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.application, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.application, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.application, target.location.name, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.resource.name, metadata.vendor_name, metadata.product_name
- principal.user.email_addresses, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.employee_id, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.product_object_id, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.userid, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- principal.user.windows_sid, target.resource.name, target.resource.resource_type, metadata.vendor_name, metadata.product_name
- target.user.email_addresses, metadata.vendor_name, metadata.product_name
- target.user.employee_id, metadata.vendor_name, metadata.product_name
- target.user.product_object_id, metadata.vendor_name, metadata.product_name
- target.user.userid, metadata.vendor_name, metadata.product_name
- target.user.windows_sid, metadata.vendor_name, metadata.product_name


Thank you for the fast reply, this worked great! 


I'll mention it here since it is probably a good reminder for everyone that all field filters need to be accounted for in the metric, so something like this could be fine as well,


 metadata.vendor_name: "AMAZON",
metadata.product_name: "AWS CloudTrail",
principal.user.userid: $user

but the key for folks reading this posting is that all the fields in the row in the docs need to be accounted for in the metric, ie 


principal.user.userid, metadata.vendor_name, metadata.product_name


principal.user.userid, target.application, metadata.vendor_name, metadata.product_name



Reply