diff --git a/rules/network/credential_access_cloud_imds_credential_http_request.toml b/rules/network/credential_access_cloud_imds_credential_http_request.toml new file mode 100644 index 00000000000..116cfd1d184 --- /dev/null +++ b/rules/network/credential_access_cloud_imds_credential_http_request.toml @@ -0,0 +1,117 @@ +[metadata] +creation_date = "2026/05/23" +integration = ["network_traffic"] +maturity = "production" +updated_date = "2026/05/23" + +[rule] +author = ["Elastic"] +description = """ +Detects HTTP GET requests to the link-local instance metadata service (169.254.169.254) for cloud credential or token +paths on AWS, GCP, or Azure. Adversaries and vulnerable workloads use scripts, shells, or application runtimes to read +IAM role credentials or OAuth tokens from the metadata API. Requires the Network Packet Capture integration with HTTP +decoding on ports 80 and 443 and process enrichment enabled so "process.*" fields are present. +""" +false_positives = [ + """ + Cloud agents (SSM, waagent, cloud-init, instance connect) and authorized scanners may reach the same paths during + provisioning or health checks. Exclude known agent user agents, source hosts, or parent processes after baselining. + """, +] +from = "now-9m" +index = ["logs-network_traffic.http*", "packetbeat-*"] +language = "eql" +license = "Elastic License v2" +name = "Cloud Instance Metadata Credential Path HTTP Request" +note = """## Triage and analysis + +### Investigating Cloud Instance Metadata Credential Path HTTP Request + +This rule matches outbound HTTP GETs to `169.254.169.254` where the URL path requests IAM credentials or cloud OAuth +tokens, filtered to common scripting runtimes, suspicious executable paths, or tool-like user agents. + +### Investigation steps + +- Confirm `url.path` (AWS `security-credentials`, GCP `oauth2/access_token`, Azure `metadata/identity/oauth2/token`). +- Review `process.name`, `process.executable`, and `user_agent.original` — scripted tools and temp-path binaries are higher risk. +- Check `host.name` or `host.hostname` and whether the workload should run on a cloud VM with an instance profile or managed identity. +- Correlate with cloud audit or sign-in logs for role assumption or token use shortly after the request. +- If credentials may have been exposed, rotate the instance role or managed identity and review API activity from that principal. + +### False positives + +- Platform agents and bootstrap scripts on new instances; allowlist by user agent or host group where validated. + +### Response + +- Restrict IMDS access (IMDSv2 hop limit, network policy) and remove unnecessary instance permissions. +- Investigate the host for follow-on credential use or lateral movement. + +## Setup + +Deploy the [Network Packet Capture](https://www.elastic.co/docs/reference/integrations/network_traffic) integration via Fleet on cloud workloads. + +- Enable **Capture HTTP Traffic** and include ports **80** and **443**. +- Enable **Monitor Processes** so network events include the process that initiated the connection. +- Prefer ECS field remapping (`map_to_ecs`) on integration data streams. +""" +references = [ + "https://www.elastic.co/docs/reference/integrations/network_traffic", + "https://hackingthe.cloud/aws/general-knowledge/intro_metadata_service/" +] +risk_score = 47 +rule_id = "73dd1f2c-3c24-4e13-a64b-dfd510e9fd98" +severity = "medium" +tags = [ + "Domain: Cloud", + "Domain: Network", + "OS: Linux", + "OS: Windows", + "OS: macOS", + "Use Case: Threat Detection", + "Tactic: Credential Access", + "Data Source: Network Packet Capture", + "Resources: Investigation Guide", +] +timestamp_override = "event.ingested" +type = "eql" + +query = ''' +network where event.module == "network_traffic" and destination.ip == "169.254.169.254" and destination.port == 80 and +http.request.method == "GET" and url.path : ( + "/latest/meta-data/iam/security-credentials/*", + "*computeMetadata/v1/instance/service-accounts/?*/oauth2/access_token*", + "*metadata/identity/oauth2/token*" +) and ( + ?process.name : ( + "curl", "wget", "python*", "node", "bun", "php*", "ruby", "perl", "bash", "sh", "bash", "dash", "dash", "zsh", "busybox", + "bun.exe", "node.exe", "powershell.exe", "cmd.exe", "curl.exe", "wget.exe", "rundll32.exe", "w3wp.exe", "java*", + "go", "nc", "netcat", "nginx", "apache*", "httpd", "tomcat*", "catalina", "spring*", "dotnet", "gunicorn", "uwsgi", + ".*", "osascript" + ) or ?process.executable : ( + "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/home/*/*", "/var/run/*", "/run/*", "/boot/*", "/.*", "C:\\Users\\*", "?:\\ProgramData\\*" + ) or user_agent.original : ( + "curl*", "wget*", "python*", "ruby*", "Go-http-client*", "node*", "axios*", "undici*", "java*", "php*", "Bun*", + "Apache-HttpClient*", "okhttp*", "RestTemplate*", "*WindowsPowerShell*" + ) +) +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1552" +name = "Unsecured Credentials" +reference = "https://attack.mitre.org/techniques/T1552/" + +[[rule.threat.technique.subtechnique]] +id = "T1552.005" +name = "Cloud Instance Metadata API" +reference = "https://attack.mitre.org/techniques/T1552/005/" + +[rule.threat.tactic] +id = "TA0006" +name = "Credential Access" +reference = "https://attack.mitre.org/tactics/TA0006/"