Incident Library
  • Root cause
  • Component
  • Symptom
  • Contributing factor
  • Case

Cases2 cases

1 to 2 of 2

  1. Symptoms

    Aqua's research team Nautilus recorded the attack on one of its Kubernetes honeypots. What appeared in the cluster was a DaemonSet running the image kuberntesio/kube-controller:1.0.1 from Docker Hub on every node, using the nodes' CPU to mine Monero.

    Trigger

    An API server misconfigured to accept unauthenticated requests from anonymous users with privileges.

    Root cause
    Component
    Contributing factor
    Detection

    Aqua recorded the attacker's API requests on its honeypot; planted AWS access keys raised a beacon when the attacker tried to use them.

    Lessons

    Fixing an exposed API server is not enough once an attacker has been in: a ClusterRoleBinding to an attacker-created ServiceAccount keeps working after anonymous access is closed. Attackers name these objects and images after real Kubernetes components so they blend into the API audit logs and pass for legitimate deployments. Aqua recommends scanning clusters for vulnerabilities, exposed secrets and misconfigurations with a tool such as Trivy.

  2. Symptoms

    Datadog alerted the DevOps team to a high normalised load average, first on the staging cluster (Day 0, 21:06 EST) and the next day on the development cluster (Day 1, 16:53 EST). The load was first put down to a legitimate service that kept scaling up and down in both environments, and because of the volume of identical alerts they were muted until things settled.

    Trigger

    An automated crawler found the Weave Scope dashboard on a public load balancer that required no authentication. Weave Scope can open a shell in running containers, and its scope-agent containers ran privileged, as root and with the host's root filesystem mounted, so a command started there could run on the host.

    Root cause
    Component
    Contributing factor
    Detection

    Datadog alerts on high normalised load average, muted at first as noise from a legitimate service; on Day 3 an engineer ran top on a node and found the gcc process at 100% CPU.

    Remediation
    • stopped Weave Scope and removed its deployment from all Kubernetes clusters
    • checked access logs for unauthorised access to the instances
    • confirmed the miner's outbound connections went only to a mining pool
    • isolated one affected node for later investigation
    • rotated out every node in each cluster so all affected hosts were destroyed and rebuilt
    Action items
    • Audit all Kubernetes and deployment YAML files and security groups for services that are unintentionally public or misconfigured
    • Replace load-average alerts with more meaningful monitors and tune them to signal a real anomaly
    • Research tools such as falcon or sysdig for behavioural monitoring and anomaly and intrusion detection
    • Evaluate Istio and Linkerd for observing and controlling end-to-end network traffic
    • Analyse the cost of scanning Docker images and containers for known vulnerabilities
    • Set aside time in architecture discussions to revisit older choices such as running containers as root
    • Share knowledge of large projects, such as Kubernetes version migrations, across the whole team
    Lessons

    Load average was not a useful signal for spotting a problem in the clusters, and muted noisy alerts nearly hid the miner. A load balancer that Kubernetes creates belongs to Kubernetes: a manual security group edit in the AWS console is reverted, so internal exposure must be declared in the Kubernetes YAML. A dashboard that can open shells, in front of privileged agents that mount the host's root filesystem, gives whoever reaches it root on every node.

Check your cluster for this

These 2 cases involve Cloud load balancer and Cluster dashboard. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.

By root cause1