
AWS EKS Forensics: Data Sources and Investigation Tooling
Synacktiv's CSIRT breaks down the forensic data sources exposed by Amazon EKS across three layers — Kubernetes control plane (audit logs), data plane (Container Insights/Fluent Bit), and AWS services (GuardDuty EKS Protection, CloudTrail) — and provides concrete CloudWatch Logs Insights queries for RBAC-escalation detection, static pod persistence, node credential theft, and other attack indicators. It also covers node-level acquisition (SSM, kubectl debug), containment pitfalls that destroy evidence, and a full investigation workflow from GuardDuty finding to cross-layer timeline correlation.
What it is
A field guide from Synacktiv's CSIRT to what an EKS compromise leaves behind and how to pull it back out of AWS-native telemetry. The summary already names the three log layers and the general query targets; below are the concrete commands, detection tells, and constraints the summary cannot carry.
Preconditions
Compute mode decides node access and is the first triage step: standard clusters run worker nodes as EC2 instances reachable via SSH/SSM; under Auto Mode or Fargate the host is AWS-managed and direct node access is unavailable. Almost nothing is logged by default — control plane logs are off, Container Insights and GuardDuty Runtime Monitoring are opt-in — so the investigation's outcome is largely fixed before the incident.
What to do
Enable all five control-plane log types (all land in /aws/eks/[cluster]/cluster):
aws eks update-cluster-config --name <cluster> --region <region> \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'Static-pod persistence is the page's marquee detection. On EKS-optimized AMIs the kubelet does not watch a manifests dir by default (staticPodPath absent from /etc/kubernetes/kubelet/config.json), so an attacker must set it and restart the service — an artifact observable on the node before any pod event. The kubelet registers a mirror pod (visible to kubectl) and GuardDuty raises Execution:Kubernetes/AnomalousBehavior.WorkloadDeployed. The conclusive audit-log tell is a pod created by a system:node: identity carrying annotation kubernetes.io/config.source = "file" (vs "api"):
fields @timestamp, user.username, objectRef.name,
`requestObject.metadata.annotations.kubernetes.io/config.source` as config_source
| filter verb = "create" and objectRef.resource = "pods"
| filter user.username like "system:node:"
| sort @timestamp descNode-local token theft — projected ServiceAccount tokens of pods scheduled on a node are a common target:
find /var/lib/kubelet/pods -path "*/kubernetes.io~projected/*/token" -type fNode acquisition: prefer aws ssm start-session --target [node instance-id]. Fall back to kubectl debug node/[node] only as last resort — it schedules a workload on the node under examination and leaves fresh create pods entries in the audit log; use deliberately and document it.
Containment ordering matters: kubectl delete destroys process state, the writable upper layer, and projected tokens the analysis depends on, and a controller may reschedule the workload. Isolate at the network layer (NetworkPolicies, Security Groups) while keeping liveness/readiness probes satisfied so the pod is neither killed nor moved. But network isolation does not stop a stolen AWS identity — a node-role or ServiceAccount token replays from anywhere, so revoke/rotate those credentials.
Caveats
- GuardDuty is a black box: detection rules are undisclosed and non-extensible; a finding is a lead, never a verdict. Runtime Monitoring (eBPF syscall visibility) is optional, adds pods, and is unsupported on Fargate — without it, in-container command execution is the coverage gap that only a third-party agent fills.
- Kubelet checkpoint API (CRIU-based, Beta since v1.30) is not usable on EKS as of writing — the EKS-optimized AMIs do not ship CRIU in the CRI runtime.
- Third-party runtime tools (Falco, Sysdig, Wiz) are explicitly out of scope.
Organisations named here
- Execution:Kubernetes/AnomalousBehavior.WorkloadDeployed
- Synacktiv
Technologies named here
- Amazon EKS
- CloudWatch Logs Insights
- EKS worker nodes
- Amazon GuardDuty
- AWS CloudTrail
- EKS-optimized AMIs
- kubectl
- AWS Fargate
- kubectl debug node/[node]
- AWS SSM Session Manager
- Amazon CloudWatch / CloudWatch Logs Insights
- amazon-cloudwatch-observability EKS add-on
- IAM
- Fluent Bit
- Kubernetes kubelet checkpoint API
- CloudWatch agent
- Falco
- Argo CD
- Sysdig
- Wiz
- CRIU
- AWS
- Kubernetes
- AWS GuardDuty
- AWS CloudWatch
Techniques named here
- Helm template injection via GitOps controller
- RBAC reconnaissance
- RBAC privilege escalation via 'escalate' verb
- Pod Security Admission evasion
- Node account self-permission evaluation
- Privileged container abuse
- Sensitive host path mount
- Reverse shell execution
- Instance credential exfiltration
- ServiceAccount token theft
- Static pod persistence
- Anomalous workload deployment
- Container checkpointing
- Cloud-resource discovery from stolen token
- PrivilegeEscalation:Kubernetes/PrivilegedContainer
- Persistence:Kubernetes/ContainerWithSensitiveMount
- Execution:Runtime/ReverseShell
Also named here
- UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS
Related in Cloud & Infra


Orca Security: GenAI Risks in Cloud Environments
.png)
Google API keys keep working after you delete them
