Detection rules › Elastic

Bun Script Attempted to Access IMDS Metadata

Time window
1m
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Identifies Bun scripting interpreter establishing a network connection to the link-local instance metadata service address (169.254.169.254). Adversaries and cloud malware often query the instance metadata API to harvest IAM credentials, tokens, and other secrets from cloud-hosted workloads.

MITRE ATT&CK coverage

Telemetry coverage

Rule body

[rule]
description = """
Identifies Bun scripting interpreter establishing a network connection to the link-local instance metadata service
address (169.254.169.254). Adversaries and cloud malware often query the instance metadata API to harvest IAM
credentials, tokens, and other secrets from cloud-hosted workloads.
"""
id = "04a04478-10b8-4b3f-a4e1-fe0c49c0f65b"
license = "Elastic License v2"
name = "Bun Script Attempted to Access IMDS Metadata"
os_list = ["macos"]
reference = [
    "https://attack.mitre.org/techniques/T1552/005/",
    "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html",
    "https://www.elastic.co/security-labs/shai-hulud-chaindrop-npm-supply-chain",
]
version = "1.0.0"

query = '''
sequence by process.entity_id with maxspan=1m
  [process where event.type == "start" and event.action in ("start", "exec") and process.name : ("bun", "bun.exe") and 
   not process.command_line like ("bun --watch src/app.ts", 
                                  "bun test src/integrations/__tests__/*", 
                                  "bun run scripts/ingest-resilience-retrospectives.ts --ingest", 
                                  "bun packages/product-config/codegen/api-codegen.ts", 
                                  "bun run apps/backend/probe-pagination.ts")]
  [network where event.action == "connection_attempted" and destination.address == "169.254.169.254" and destination.port == 80]
'''

min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[threat.technique.subtechnique]]
id = "T1552.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"



[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and event.action in ("start", "exec") and process.name : ("bun", "bun.exe") and 
   not process.command_line like ("bun --watch src/app.ts", 
                                  "bun test src/integrations/__tests__/*", 
                                  "bun run scripts/ingest-resilience-retrospectives.ts --ingest", 
                                  "bun packages/product-config/codegen/api-codegen.ts", 
                                  "bun run apps/backend/probe-pagination.ts")]

Stage 2: network

[network where event.action == "connection_attempted" and destination.address == "169.254.169.254" and destination.port == 80]

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_linewildcardbun --watch src/app.ts, bun test src/integrations/__tests__/*, bun run scripts/ingest-resilience-retrospectives.ts --ingest, bun packages/product-config/codegen/api-codegen.ts, bun run apps/backend/probe-pagination.tsexcludes:process.command_line