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.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2024/11/04"
  3integration = ["aws"]
  4maturity = "production"
  5updated_date = "2025/12/04"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects when a single AWS resource is running multiple read-only, discovery API calls in a 10-second window. This
 11behavior could indicate an actor attempting to discover the AWS infrastructure using compromised credentials or a
 12compromised instance. Adversaries may use this information to identify potential targets for further exploitation or to
 13gain a better understanding of the target's infrastructure.
 14"""
 15false_positives = [
 16    """
 17    Administrators or automated systems may legitimately perform multiple `Describe`, `List`, `Get` and `Generate` API calls in a short
 18    time frame. Verify the user identity and the purpose of the API calls to determine if the behavior is expected.
 19    """,
 20]
 21from = "now-6m"
 22language = "esql"
 23license = "Elastic License v2"
 24name = "AWS Discovery API Calls via CLI from a Single Resource"
 25note = """## Triage and analysis
 26
 27> **Disclaimer**:
 28> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
 29
 30### Investigating AWS Discovery API Calls via CLI from a Single Resource
 31
 32This rule detects when a single AWS identity executes more than five unique discovery-related API calls (`Describe*`, `List*`, `Get*`, or `Generate*`) within a 10-second window using the AWS CLI.  
 33High volumes of diverse “read-only” API calls in such a short period can indicate scripted reconnaissance, often an early phase of compromise after credential exposure or access to a compromised EC2 instance.  
 34
 35#### Possible Investigation Steps
 36
 37**Identify the actor and session context**
 38- **Actor ARN (`aws.cloudtrail.user_identity.arn`)**: Determine which IAM user, role, or service principal performed the actions.  
 39  - Check whether this identity normally performs enumeration activity or belongs to automation infrastructure.  
 40- **Identity type (`Esql.aws_cloudtrail_user_identity_arn_type`)**: Validate if the caller is a human IAM user, assumed role, or federated identity. Unusual types (e.g., temporary credentials from an unfamiliar role) may indicate lateral movement.  
 41- **Access key (`Esql.aws_cloudtrail_user_identity_access_key_id_values`)** – Identify which specific access key or temporary credential was used.  
 42  - If multiple suspicious keys are found, use AWS IAM console or `aws iam list-access-keys` to determine when they were last used or rotated.  
 43- **Account (`Esql.cloud_account_id_values`)** – Confirm which AWS account was affected and whether it matches the intended operational context (e.g., production vs. sandbox).
 44
 45**Assess the API call pattern and intent**
 46- **Distinct action count (`Esql.event_action_count_distinct`)**: Note how many unique API calls occurred within each 10-second window. Counts far above normal operational baselines may indicate scripted reconnaissance.  
 47- **API actions (`Esql.event_action_values`)**: Review which discovery APIs were invoked.  
 48  - Focus on services such as EC2 (`DescribeInstances`), IAM (`ListRoles`, `ListAccessKeys`), S3 (`ListBuckets`), and KMS (`ListKeys`), which adversaries frequently query to map assets.  
 49- **Service providers (`Esql.event_provider_values`)**: Identify which AWS services were targeted.  
 50  - Multi-service enumeration (IAM + EC2 + S3) suggests broad discovery rather than a specific diagnostic task.  
 51- **Time window (`Esql.time_window_date_trunc`)**: Verify whether activity occurred during normal maintenance windows or outside expected hours.
 52
 53**Analyze the source and origin**
 54- **Source IP (`Esql.source_ip_values`)**: Check the originating IPs to determine whether the calls came from a known internal host, an EC2 instance, or an unfamiliar external network.  
 55  - Compare with known corporate CIDR ranges, VPC flow logs, or guardrail baselines.  
 56- **Source organization (`Esql.source_as_organization_name_values`)**: Review the associated ASN or organization.  
 57  - If the ASN belongs to a commercial ISP or VPN service, investigate possible credential compromise or remote attacker usage.
 58
 59**Correlate with additional events**
 60- Search CloudTrail for the same `aws.cloudtrail.user_identity.arn` or `aws_cloudtrail_user_identity_access_key_id_values` within ±30 minutes.  
 61  - Look for follow-on actions such as `GetCallerIdentity`, `AssumeRole`, `CreateAccessKey`, or data access (`GetObject`, `CopySnapshot`).  
 62  - Correlate this enumeration with authentication anomalies or privilege-related findings.  
 63- Cross-reference `Esql.cloud_account_id_values` with other alerts for lateral or privilege escalation patterns.
 64
 65### False positive analysis
 66
 67Legitimate, high-frequency API activity may originate from:
 68- **Inventory or compliance automation**: Scripts or tools such as AWS Config, Cloud Custodian, or custom CMDB collection performing periodic Describe/List calls.  
 69- **Operational monitoring systems**: DevOps pipelines, Terraform, or deployment verifiers enumerating resources.  
 70- **Security tooling**: Security scanners performing asset discovery across services.
 71
 72Validate by confirming:
 73- Whether the `aws.cloudtrail.user_identity.arn` corresponds to a documented automation or monitoring identity.  
 74- That the observed `Esql.event_action_values` match known inventory or cost-reporting workflows.  
 75- Timing alignment with approved maintenance schedules.
 76
 77### Response and remediation
 78
 79If the activity is unexpected or originates from unrecognized credentials, follow AWS’s incident-handling guidance:
 80
 81**1. Contain**
 82- Temporarily disable or rotate the access key (`Esql.aws_cloudtrail_user_identity_access_key_id_values`) using IAM.  
 83- Restrict outbound connectivity for the instance or resource from which the API calls originated.
 84
 85**2. Investigate**
 86- Retrieve full CloudTrail logs for the actor and `Esql.time_window_date_trunc` interval.  
 87- Identify any subsequent write or privilege-modification actions.  
 88- Review associated IAM policies for excessive permissions.
 89
 90**3. Recover and Harden**
 91- Rotate credentials, enforce MFA on human users, and tighten IAM role trust policies.  
 92- Implement AWS Config rules or SCPs to monitor and restrict large-scale enumeration.
 93
 94**4. Post-Incident Actions**
 95- Document the finding and response in your organization’s IR management system.  
 96- Update detection logic or allow-lists for known benign automation.  
 97- Validate recovery by confirming no new suspicious discovery bursts occur.
 98
 99### Additional information
100
101- **AWS Documentation**
102  - [CloudTrail Event Reference](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference.html)
103  - [AWS Security Incident Response Guide](https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/aws-security-incident-response-guide.pdf)
104- **AWS Playbook Resources**
105  - [AWS Incident Response Playbooks](https://github.com/aws-samples/aws-incident-response-playbooks/tree/c151b0dc091755fffd4d662a8f29e2f6794da52c/playbooks)
106  - [AWS Customer Playbook Framework](https://github.com/aws-samples/aws-customer-playbook-framework)
107
108"""
109references = ["https://stratus-red-team.cloud/attack-techniques/AWS/aws.discovery.ec2-enumerate-from-instance/"]
110risk_score = 21
111rule_id = "74f45152-9aee-11ef-b0a5-f661ea17fbcd"
112severity = "low"
113tags = [
114    "Domain: Cloud",
115    "Data Source: AWS",
116    "Data Source: AWS EC2",
117    "Data Source: AWS IAM",
118    "Data Source: AWS S3",
119    "Data Source: AWS Cloudtrail",
120    "Data Source: AWS RDS",
121    "Data Source: AWS Lambda",
122    "Data Source: AWS STS",
123    "Data Source: AWS KMS",
124    "Data Source: AWS SES",
125    "Data Source: AWS Cloudfront",
126    "Data Source: AWS DynamoDB",
127    "Data Source: AWS Elastic Load Balancing",
128    "Use Case: Threat Detection",
129    "Tactic: Discovery",
130    "Resources: Investigation Guide",
131]
132timestamp_override = "event.ingested"
133type = "esql"
134
135query = '''
136from logs-aws.cloudtrail-* metadata _id, _version, _index
137// create time window buckets of 10 seconds
138| eval Esql.time_window_date_trunc = date_trunc(10 seconds, @timestamp)
139
140| where
141    event.dataset == "aws.cloudtrail"
142    // filter on CloudTrail audit logs for IAM, EC2, S3, etc.
143    and event.provider in (
144      "iam.amazonaws.com",
145      "ec2.amazonaws.com",
146      "s3.amazonaws.com",
147      "rds.amazonaws.com",
148      "lambda.amazonaws.com",
149      "dynamodb.amazonaws.com",
150      "kms.amazonaws.com",
151      "cloudfront.amazonaws.com",
152      "elasticloadbalancing.amazonaws.com", 
153      "cloudtrail.amazonaws.com",
154      "sts.amazonaws.com",
155      "ses.amazonaws.com"
156    )
157    // ignore AWS service actions
158    and aws.cloudtrail.user_identity.type != "AWSService"
159    // filter for aws-cli specifically
160    and user_agent.name == "aws-cli"
161    // exclude DescribeCapacityReservations events related to AWS Config
162    and event.action != "DescribeCapacityReservations"
163
164// filter for Describe, Get, List, and Generate API calls
165| where true in (
166    starts_with(event.action, "Describe"),
167    starts_with(event.action, "Get"),
168    starts_with(event.action, "List"),
169    starts_with(event.action, "Generate")
170)
171
172// extract owner, identity type, and actor from the ARN
173| dissect aws.cloudtrail.user_identity.arn "%{}::%{Esql_priv.aws_cloudtrail_user_identity_arn_owner}:%{Esql.aws_cloudtrail_user_identity_arn_type}/%{Esql.aws_cloudtrail_user_identity_arn_roles}"
174
175| where starts_with(Esql.aws_cloudtrail_user_identity_arn_roles, "AWSServiceRoleForConfig") != true
176
177// keep relevant fields (preserving ECS fields and computed time window)
178| keep 
179    @timestamp, 
180    Esql.time_window_date_trunc, 
181    event.action, 
182    aws.cloudtrail.user_identity.arn, 
183    aws.cloudtrail.user_identity.type, 
184    aws.cloudtrail.user_identity.access_key_id, 
185    source.ip, 
186    cloud.account.id, 
187    event.provider, 
188    user_agent.name, 
189    source.as.organization.name, 
190    cloud.region,
191    data_stream.namespace
192
193// count the number of unique API calls per time window and actor
194| stats
195    Esql.event_action_count_distinct = count_distinct(event.action),
196    Esql.event_action_values = VALUES(event.action),
197    Esql.event_timestamp_values = VALUES(@timestamp),
198    Esql.aws_cloudtrail_user_identity_type_values = VALUES(aws.cloudtrail.user_identity.type),
199    Esql.aws_cloudtrail_user_identity_access_key_id_values = VALUES(aws.cloudtrail.user_identity.access_key_id),
200    Esql.source_ip_values = VALUES(source.ip),
201    Esql.cloud_account_id_values = VALUES(cloud.account.id),
202    Esql.event_provider_values = VALUES(event.provider),
203    Esql.user_agent_name_values = VALUES(user_agent.name),
204    Esql.source_as_organization_name_values = VALUES(source.as.organization.name),
205    Esql.cloud_region_values = VALUES(cloud.region),
206    Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
207  by Esql.time_window_date_trunc, aws.cloudtrail.user_identity.arn
208
209// filter for more than 5 unique API calls per 10s window
210| where Esql.event_action_count_distinct > 5
211'''
212
213
214[[rule.threat]]
215framework = "MITRE ATT&CK"
216[[rule.threat.technique]]
217id = "T1580"
218name = "Cloud Infrastructure Discovery"
219reference = "https://attack.mitre.org/techniques/T1580/"
220
221
222[rule.threat.tactic]
223id = "TA0007"
224name = "Discovery"
225reference = "https://attack.mitre.org/tactics/TA0007/"
226
227[rule.investigation_fields]
228field_names = [
229  "Esql.event_action_count_distinct", 
230  "Esql.time_window_date_trunc", 
231  "aws.cloudtrail.user_identity.arn", 
232  "Esql.aws_cloudtrail_user_identity_type_values",
233  "Esql.aws_cloudtrail_user_identity_access_key_id_values", 
234  "Esql.source_ip_values", 
235  "Esql.source_as_organization_name_values", 
236  "Esql.event_provider_values", 
237  "Esql.event_action_values", 
238  "Esql.cloud_account_id_values",
239  "Esql.cloud_region_values",
240  "Esql.data_stream_namespace_values"
241  ]

Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating AWS Discovery API Calls via CLI from a Single Resource

This rule detects when a single AWS identity executes more than five unique discovery-related API calls (Describe*, List*, Get*, or Generate*) within a 10-second window using the AWS CLI.
High volumes of diverse “read-only” API calls in such a short period can indicate scripted reconnaissance, often an early phase of compromise after credential exposure or access to a compromised EC2 instance.

Possible Investigation Steps

Identify the actor and session context

  • Actor ARN (aws.cloudtrail.user_identity.arn): Determine which IAM user, role, or service principal performed the actions.
    • Check whether this identity normally performs enumeration activity or belongs to automation infrastructure.
  • Identity type (Esql.aws_cloudtrail_user_identity_arn_type): Validate if the caller is a human IAM user, assumed role, or federated identity. Unusual types (e.g., temporary credentials from an unfamiliar role) may indicate lateral movement.
  • Access key (Esql.aws_cloudtrail_user_identity_access_key_id_values) – Identify which specific access key or temporary credential was used.
    • If multiple suspicious keys are found, use AWS IAM console or aws iam list-access-keys to determine when they were last used or rotated.
  • Account (Esql.cloud_account_id_values) – Confirm which AWS account was affected and whether it matches the intended operational context (e.g., production vs. sandbox).

Assess the API call pattern and intent

  • Distinct action count (Esql.event_action_count_distinct): Note how many unique API calls occurred within each 10-second window. Counts far above normal operational baselines may indicate scripted reconnaissance.
  • API actions (Esql.event_action_values): Review which discovery APIs were invoked.
    • Focus on services such as EC2 (DescribeInstances), IAM (ListRoles, ListAccessKeys), S3 (ListBuckets), and KMS (ListKeys), which adversaries frequently query to map assets.
  • Service providers (Esql.event_provider_values): Identify which AWS services were targeted.
    • Multi-service enumeration (IAM + EC2 + S3) suggests broad discovery rather than a specific diagnostic task.
  • Time window (Esql.time_window_date_trunc): Verify whether activity occurred during normal maintenance windows or outside expected hours.

Analyze the source and origin

  • Source IP (Esql.source_ip_values): Check the originating IPs to determine whether the calls came from a known internal host, an EC2 instance, or an unfamiliar external network.
    • Compare with known corporate CIDR ranges, VPC flow logs, or guardrail baselines.
  • Source organization (Esql.source_as_organization_name_values): Review the associated ASN or organization.
    • If the ASN belongs to a commercial ISP or VPN service, investigate possible credential compromise or remote attacker usage.

Correlate with additional events

  • Search CloudTrail for the same aws.cloudtrail.user_identity.arn or aws_cloudtrail_user_identity_access_key_id_values within ±30 minutes.
    • Look for follow-on actions such as GetCallerIdentity, AssumeRole, CreateAccessKey, or data access (GetObject, CopySnapshot).
    • Correlate this enumeration with authentication anomalies or privilege-related findings.
  • Cross-reference Esql.cloud_account_id_values with other alerts for lateral or privilege escalation patterns.

False positive analysis

Legitimate, high-frequency API activity may originate from:

  • Inventory or compliance automation: Scripts or tools such as AWS Config, Cloud Custodian, or custom CMDB collection performing periodic Describe/List calls.
  • Operational monitoring systems: DevOps pipelines, Terraform, or deployment verifiers enumerating resources.
  • Security tooling: Security scanners performing asset discovery across services.

Validate by confirming:

  • Whether the aws.cloudtrail.user_identity.arn corresponds to a documented automation or monitoring identity.
  • That the observed Esql.event_action_values match known inventory or cost-reporting workflows.
  • Timing alignment with approved maintenance schedules.

Response and remediation

If the activity is unexpected or originates from unrecognized credentials, follow AWS’s incident-handling guidance:

1. Contain

  • Temporarily disable or rotate the access key (Esql.aws_cloudtrail_user_identity_access_key_id_values) using IAM.
  • Restrict outbound connectivity for the instance or resource from which the API calls originated.

2. Investigate

  • Retrieve full CloudTrail logs for the actor and Esql.time_window_date_trunc interval.
  • Identify any subsequent write or privilege-modification actions.
  • Review associated IAM policies for excessive permissions.

3. Recover and Harden

  • Rotate credentials, enforce MFA on human users, and tighten IAM role trust policies.
  • Implement AWS Config rules or SCPs to monitor and restrict large-scale enumeration.

4. Post-Incident Actions

  • Document the finding and response in your organization’s IR management system.
  • Update detection logic or allow-lists for known benign automation.
  • Validate recovery by confirming no new suspicious discovery bursts occur.

Additional information

References

Related rules

to-top