Elastic low stable kql

AWS Discovery API Calls via CLI from a Single Resource

Detects when a single AWS resource is running multiple read-only, discovery API calls in a 10-second window. This behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to gain a better understanding of the target's infrastructure.

View Source

Detection Logic

from logs-aws.cloudtrail-* metadata _id, _version, _index
// create time window buckets of 10 seconds
| eval Esql.time_window_date_trunc = date_trunc(10 seconds, @timestamp)
| where
    data_stream.dataset == "aws.cloudtrail"
    
    // exclude service account and console behavior
    and source.ip IS NOT NULL
    and aws.cloudtrail.session_credential_from_console IS NULL
    and event.provider in (
      "iam.amazonaws.com",
      "ec2.amazonaws.com",
      "s3.amazonaws.com",
      "rds.amazonaws.com",
      "lambda.amazonaws.com",
      "dynamodb.amazonaws.com",
      "kms.amazonaws.com",
      "cloudfront.amazonaws.com",
      "elasticloadbalancing.amazonaws.com", 
      "cloudtrail.amazonaws.com",
      "sts.amazonaws.com",
      "ses.amazonaws.com",
      "organizations.amazonaws.com"
    )
    // ignore AWS service actions
    and aws.cloudtrail.user_identity.type != "AWSService"
    // filter for aws-cli specifically
    and user_agent.name == "aws-cli"
    // exclude DescribeCapacityReservations events related to AWS Config
    and event.action != "DescribeCapacityReservations"
    and user.name != "AWSServiceRoleForConfig"

// filter for Describe, Get, List, and Generate API calls
| where true in (
    starts_with(event.action, "Describe"),
    starts_with(event.action, "Get"),
    starts_with(event.action, "List"),
    starts_with(event.action, "Generate")
)

// keep relevant fields (preserving ECS fields and computed time window)
| keep 
    @timestamp, 
    Esql.time_window_date_trunc, 
    event.action, 
    aws.cloudtrail.user_identity.arn, 
    aws.cloudtrail.user_identity.type, 
    aws.cloudtrail.user_identity.access_key_id, 
    source.ip, 
    cloud.account.id, 
    event.provider, 
    user_agent.name, 
    source.as.organization.name, 
    cloud.region,
    data_stream.namespace

// count the number of unique API calls per time window and actor
| stats
    Esql.event_action_count_distinct = count_distinct(event.action),
    Esql.event_action_values = VALUES(event.action),
    Esql.event_timestamp_values = VALUES(@timestamp),
    Esql.aws_cloudtrail_user_identity_type_values = VALUES(aws.cloudtrail.user_identity.type),
    Esql.aws_cloudtrail_user_identity_access_key_id_values = VALUES(aws.cloudtrail.user_identity.access_key_id),
    Esql.source_ip_values = VALUES(source.ip),
    Esql.cloud_account_id_values = VALUES(cloud.account.id),
    Esql.event_provider_values = VALUES(event.provider),
    Esql.user_agent_name_values = VALUES(user_agent.name),
    Esql.source_as_organization_name_values = VALUES(source.as.organization.name),
    Esql.cloud_region_values = VALUES(cloud.region),
    Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
  by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn

// filter for more than 5 unique API calls per 10s window
| where Esql.event_action_count_distinct > 5
| keep
    aws.cloudtrail.user_identity.arn,
    Esql.time_window_date_trunc,
    Esql.event_action_count_distinct,
    Esql.event_action_values,
    Esql.event_timestamp_values,
    Esql.aws_cloudtrail_user_identity_type_values,
    Esql.aws_cloudtrail_user_identity_access_key_id_values,
    Esql.source_ip_values,
    Esql.cloud_account_id_values,
    Esql.event_provider_values,
    Esql.user_agent_name_values,
    Esql.source_as_organization_name_values,
    Esql.cloud_region_values,
    Esql.data_stream_namespace_values

False Positives

  • Administrators or automated systems may legitimately perform multiple `Describe`, `List`, `Get` and `Generate` API calls in a short time frame. Verify the user identity and the purpose of the API calls to determine if the behavior is expected.

Field Validations

Loading…

Comments (0)

Loading comments...