AWS Service Quotas Multi-Region GetServiceQuota Requests

Last updated 17 days ago on 2025-12-15
Created a year ago on 2024-08-26

About

Identifies when a single AWS principal makes GetServiceQuota API calls for the EC2 service quota L-1216C47A, across more than 10 AWS regions within a 30-second window. This quota represents the vCPU limit for on-demand EC2 instances. Adversaries commonly enumerate this quota across regions to assess capacity for large-scale instance deployment, including cryptocurrency mining, malware hosting, or command-and-control infrastructure. This behavior may indicate cloud infrastructure discovery using compromised credentials or a compromised workload.
Tags
Domain: CloudData Source: AWSData Source: Amazon Web ServicesData Source: AWS Service QuotasUse Case: Threat DetectionTactic: DiscoveryLanguage: esql
Severity
low
Risk Score
21
MITRE ATT&CK™

Discovery (TA0007)(external, opens in a new tab or window)

False Positive Examples
Organizations with mature multi-region operations may legitimately query EC2 service quotas across regions for capacity planning, automation, or compliance validation. Infrastructure-as-code tooling, quota monitoring solutions, or centralized cloud governance platforms may also generate similar activity. Validate the identity, purpose, and historical behavior of the calling principal before treating this activity as malicious.
License
Elastic License v2(external, opens in a new tab or window)

Definition

Integration Pack
Prebuilt Security Detection Rules
Related Integrations

(external, opens in a new tab or window)

Query
text code block:
from logs-aws.cloudtrail-* METADATA _id, _version, _index // filter for GetServiceQuota API calls | where event.dataset == "aws.cloudtrail" and event.provider == "servicequotas.amazonaws.com" and event.action == "GetServiceQuota" // truncate the timestamp to a 30-second window | eval Esql.time_window_date_trunc = date_trunc(30 seconds, @timestamp) // dissect request parameters to extract service and quota code | dissect aws.cloudtrail.request_parameters "{%{?Esql.aws_cloudtrail_request_parameters_service_code_key}=%{Esql.aws_cloudtrail_request_parameters_service_code}, %{?quota_code_key}=%{Esql.aws_cloudtrail_request_parameters_quota_code}}" // filter for EC2 service quota L-1216C47A (vCPU on-demand instances) | where Esql.aws_cloudtrail_request_parameters_service_code == "ec2" and Esql.aws_cloudtrail_request_parameters_quota_code == "L-1216C47A" // keep only the relevant fields | keep Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn, cloud.region, Esql.aws_cloudtrail_request_parameters_service_code, Esql.aws_cloudtrail_request_parameters_quota_code, aws.cloudtrail.request_parameters, @timestamp, aws.cloudtrail.user_identity.type, aws.cloudtrail.user_identity.access_key_id, source.ip, cloud.account.id, user_agent.original, source.as.organization.name, data_stream.namespace // count the number of unique regions and total API calls within the time window | stats Esql.cloud_region_count_distinct = count_distinct(cloud.region), Esql.event_count = count(*), Esql.aws_cloudtrail_request_parameters_values = VALUES(aws.cloudtrail.request_parameters), 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.user_agent_original_values = VALUES(user_agent.original), 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 API calls in more than 10 regions within the 30-second window | where Esql.cloud_region_count_distinct >= 10 and Esql.event_count >= 10

Install detection rules in Elastic Security

Detect AWS Service Quotas Multi-Region GetServiceQuota Requests in the Elastic Security detection engine by installing this rule into your Elastic Stack.

To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).