AWS EKS Pod Exec with Curl or Wget to HTTPS
Detects pod or attach exec API calls where the decoded request query implies "curl" or "wget" fetching an "https" URL. Attackers with permission to exec into workloads often run one-liners to stage tooling, pull scripts or binaries, or exfiltrate data over HTTPS—activity that should be rare compared to shells, debuggers, or expected health checks. The rule decodes the audit requestURI, reconstructs a readable command string from repeated command parameters, and applies noise filters for common cluster health and OIDC/JWKS endpoints so benign automation is less likely to alert.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/08/03"
3integration = ["aws"]
4maturity = "production"
5min_stack_comments = "The AWS integration adds the aws.eks_audit data stream in package 8.9.0, which requires Kibana 9.6.0 or later."
6min_stack_version = "9.6.0"
7updated_date = "2026/10/20"
8
9[rule]
10author = ["Elastic"]
11description = """
12Detects pod or attach exec API calls where the decoded request query implies "curl" or "wget" fetching an "https" URL.
13Attackers with permission to exec into workloads often run one-liners to stage tooling, pull scripts or binaries, or
14exfiltrate data over HTTPS—activity that should be rare compared to shells, debuggers, or expected health checks. The
15rule decodes the audit requestURI, reconstructs a readable command string from repeated command parameters, and applies
16noise filters for common cluster health and OIDC/JWKS endpoints so benign automation is less likely to alert.
17"""
18from = "now-6m"
19language = "esql"
20license = "Elastic License v2"
21name = "AWS EKS Pod Exec with Curl or Wget to HTTPS"
22note = """## Triage and analysis
23
24### Investigating AWS EKS Pod Exec with Curl or Wget to HTTPS
25Kubernetes audit logs record exec (and similar attach) calls on requestURI, including URL-encoded
26command segments. This rule URL-decodes the URI, extracts the query portion into a single string, and
27flags curl or wget combined with https, excluding several ommon health, localhost, and OIDC/JWKS patterns.
28
29### Possible investigation steps
30
31- Confirm who may exec into the target namespace: review aws.eks.audit.user.username, groups, impersonation, and
32 source.ip / user_agent.original (kubectl, CI, webhooks).
33- Map the pod (aws.eks.audit.objectRef.name) and workload owner; retrieve the exact decoded URI from
34 Esql.decoded_uri and the reconstructed Esql.command in the alert.
35- Search for adjacent audit events from the same identity: secret reads, additional execs, RBAC changes, or anonymous
36 access.
37- If malicious, revoke credentials used for exec, review RoleBindings for **`pods/exec`**, and inspect the pod
38 filesystem or snapshot for dropped artifacts.
39
40### False positive analysis
41
42- Approved runbooks or support sessions may use kubectl exec with curl/wget to test egress or download vendor tools;
43 document break-glass identities and tune exclusions.
44- Some cluster components use HTTPS to **kubernetes.default.svc** or **.well-known** endpoints; the rule attempts to
45 filter those—expand the exclusion list if your platform uses additional first-party URLs.
46
47### Response and remediation
48
49- Rotate any secrets accessible from the pod, cordon or delete the workload if compromised, and tighten RBAC so only
50 required principals retain **`pods/exec`** on sensitive namespaces."""
51references = [
52 "https://cloud.hacktricks.wiki/en/pentesting-cloud/kubernetes-security/kubernetes-privilege-escalation/workload-and-pod-access.html",
53]
54risk_score = 73
55rule_id = "7a12c6d0-720a-5763-a1f7-39ae37727f22"
56setup = """This rule reads EKS control-plane audit logs collected by the AWS integration
57into `logs-aws.eks_audit-*`, where the AWS EKS audit ingest
58pipelines normalize each audit record under `aws.eks.audit.*`.
59
60Enable the `audit` control-plane log type on the EKS cluster, send its
61CloudWatch log group through the AWS integration, and confirm events carry
62`data_stream.dataset: aws.eks_audit` and
63`cloud.provider: aws` before enabling this rule.
64"""
65severity = "high"
66tags = [
67 "Domain: Cloud",
68 "Domain: Containers",
69 "Platform: AWS",
70 "Platform: Kubernetes",
71 "Data Source: AWS",
72 "Data Source: Amazon Web Services",
73 "Data Source: Kubernetes API Server Audit Logs",
74 "Service: AWS EKS",
75 "Use Case: Threat Detection",
76 "Tactic: Execution",
77 "Tactic: Command and Control",
78 "Rule Type: ES|QL",
79 "Resources: Investigation Guide",
80 "Profile: Beta",
81]
82timestamp_override = "event.ingested"
83type = "esql"
84
85query = '''
86FROM logs-aws.eks_audit-* metadata _id, _index, _version
87| WHERE aws.eks.audit.objectRef.subresource == "exec"
88 AND aws.eks.audit.requestURI LIKE "*command=*"
89| EVAL decoded_uri = URL_DECODE(aws.eks.audit.requestURI)
90| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
91| EVAL command = REPLACE(raw_commands, "command=", "")
92| EVAL command = REPLACE(command, "&", " ")
93| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
94| WHERE Esql.executed_command IS NOT NULL
95 AND Esql.executed_command RLIKE """.*(curl.*https|wget.*https).*"""
96 AND NOT Esql.executed_command RLIKE """.*(/api/v1/health|/healthz|/readyz|/livez|127\.0\.0\.1|localhost|/openid/v1/jwks|/openid-connect/certs|/.well-known/openid-configuration|/.well-known/jwks\.json|kubernetes\.default\.svc).*"""
97| KEEP Esql.*, @timestamp, user.name, source.ip, user_agent.original, event.action, aws.eks.audit.objectRef.namespace, aws.eks.audit.objectRef.name, aws.eks.audit.requestURI, aws.eks.audit.user.username, data_stream.namespace, _id, _index, _version
98'''
99
100
101[[rule.threat]]
102framework = "MITRE ATT&CK"
103[[rule.threat.technique]]
104id = "T1609"
105name = "Container Administration Command"
106reference = "https://attack.mitre.org/techniques/T1609/"
107
108
109[rule.threat.tactic]
110id = "TA0002"
111name = "Execution"
112reference = "https://attack.mitre.org/tactics/TA0002/"
113[[rule.threat]]
114framework = "MITRE ATT&CK"
115[[rule.threat.technique]]
116id = "T1105"
117name = "Ingress Tool Transfer"
118reference = "https://attack.mitre.org/techniques/T1105/"
119
120
121[rule.threat.tactic]
122id = "TA0011"
123name = "Command and Control"
124reference = "https://attack.mitre.org/tactics/TA0011/"
Triage and analysis
Investigating AWS EKS Pod Exec with Curl or Wget to HTTPS
Kubernetes audit logs record exec (and similar attach) calls on requestURI, including URL-encoded command segments. This rule URL-decodes the URI, extracts the query portion into a single string, and flags curl or wget combined with https, excluding several ommon health, localhost, and OIDC/JWKS patterns.
Possible investigation steps
- Confirm who may exec into the target namespace: review aws.eks.audit.user.username, groups, impersonation, and source.ip / user_agent.original (kubectl, CI, webhooks).
- Map the pod (aws.eks.audit.objectRef.name) and workload owner; retrieve the exact decoded URI from Esql.decoded_uri and the reconstructed Esql.command in the alert.
- Search for adjacent audit events from the same identity: secret reads, additional execs, RBAC changes, or anonymous access.
- If malicious, revoke credentials used for exec, review RoleBindings for
pods/exec, and inspect the pod filesystem or snapshot for dropped artifacts.
False positive analysis
- Approved runbooks or support sessions may use kubectl exec with curl/wget to test egress or download vendor tools; document break-glass identities and tune exclusions.
- Some cluster components use HTTPS to kubernetes.default.svc or .well-known endpoints; the rule attempts to filter those—expand the exclusion list if your platform uses additional first-party URLs.
Response and remediation
- Rotate any secrets accessible from the pod, cordon or delete the workload if compromised, and tighten RBAC so only
required principals retain
pods/execon sensitive namespaces.
References
Related rules
- AWS EKS Pod Exec Potential Reverse Shell
- AWS EKS Pod Exec Cloud Instance Metadata Access
- AWS EKS Pod Exec Sensitive File or Credential Path Access
- AWS EKS Anonymous User Create/Update/Patch Pods Request
- AWS EKS Forbidden Creation Request