Deploy in your cluster
Blog

Cryptomining Attacks in K8s: How Attackers Get In and How You Catch Them

A compromised deployment can become a mining rig within minutes. The tell-tale signs — CPU spike, outbound connection to mining pools, process name anomalies — are detectable at the kernel level if you're watching for them.

Cryptomining attack pattern in Kubernetes cluster visualization

Why Kubernetes Makes an Attractive Cryptomining Target

From an attacker's perspective, a mid-size K8s cluster is close to ideal for cryptomining. The compute is already provisioned and sitting there — often overprovisioned with headroom because teams size for peak load. The cloud provider bills the cluster owner. The attack surface (exposed API endpoints, misconfigured RBAC, vulnerable container images, misconfigured namespaces) is often broad. And the dwell time before detection is long: industry incident response reports published between 2022 and 2025 consistently place median cryptomining detection times in the range of days to weeks. Your billing dashboard is typically faster than your security tool at noticing something is wrong.

Published threat intelligence from cloud security vendors documents cryptomining as responsible for a substantial fraction of cloud security incidents — the figures commonly cited in published threat reports range between 25-35% of cloud compromise events. The attack vectors that reach K8s clusters most frequently include: exposed Kubernetes API servers (default or misconfigured without authentication), vulnerable web applications running in pods (SSRF → credential access → kubectl), and compromised container images from public registries with embedded miners that activate post-deploy. The MITRE ATT&CK for containers matrix maps cryptomining as an impact tactic (T1496: Resource Hijacking) but the entry vectors span Initial Access through Execution.

The Attack Chain: From Initial Access to Mining

A typical cryptomining attack against a K8s cluster follows a recognizable pattern. The variation is in the initial access vector; the post-access execution is remarkably consistent across observed incident patterns.

Initial access (most common vectors):

  • RCE vulnerability in an application pod (Spring4Shell, log4shell, or any unauthenticated RCE in a web framework running in a container). The attacker executes arbitrary commands in the application pod's context.
  • Exposed Helm Tiller v2 instance (pre-K8s 1.13 era, still found in legacy clusters) with cluster-admin ServiceAccount — one helm install deploys a mining workload as a new deployment.
  • Misconfigured RBAC where a ServiceAccount token in one namespace has create pods permissions cluster-wide — the attacker with access to that token calls the K8s API to create a new pod with a mining image.
  • Compromised image in a public registry that passes a Trivy or Grype scan (no known CVEs in the image) but contains a miner binary with a delayed start trigger or environment-variable-gated activation.

Post-access execution (consistent pattern):

Once the attacker has execution in a pod, the sequence is: download the miner binary (or it's already embedded), set environment variables (POOL_URL, WALLET_ADDRESS), execute the miner process, suppress stdout to avoid log-based detection, and optionally install persistence via a cron job or DaemonSet mutation (if they have sufficient RBAC permissions). The miner establishes an outbound TCP connection to a stratum mining pool on port 3333, 5555, 7777, or 14444 — the standard Stratum v1 protocol ports — and begins submitting hashes.

Detection Signal 1: Process Name and Ancestry

The simplest detection — and often the most reliable — is process name matching. XMRig (the dominant Monero miner used in cryptomining attacks) and its forks use a recognizable set of process names: xmrig, xmr-stak, minergate, kswapd0 (a common masquerade for the miner process), crypto-miner, and several others. These names are detectable via eBPF tracepoints on sys_enter_execve — every process execution fires this, and the argv[0] argument is readable from the eBPF context.

A Falco rule for this:

- list: cryptominer_binaries
  items: [xmrig, xmr-stak, minergate, "kswapd0", "crypto-miner", nbminer, cgminer, bfgminer]

- rule: Crypto Mining Binary Executed
  desc: Known cryptominer process name spawned in a container
  condition: >
    spawned_process
    and container
    and proc.name in (cryptominer_binaries)
  output: >
    "Cryptominer binary detected (container=%container.name
     image=%container.image.repository:%container.image.tag
     pid=%proc.pid cmdline=%proc.cmdline)"
  priority: CRITICAL
  tags: [cryptomining, T1496]

This rule is high-confidence and low-false-positive because no legitimate application workload should be named xmrig. The failure mode is attackers who rename their binary — which leads to the next detection signal.

Detection Signal 2: Stratum Protocol Outbound Connections

Cryptomining requires communicating with a mining pool. The Stratum protocol (both v1 and the newer Stratum v2) operates over TCP and uses a distinctive JSON-RPC message format. The initial handshake includes a mining.subscribe message followed by a mining.authorize with the wallet address. These are observable at the kernel level via sys_enter_connect (destination IP and port) and, if you attach uprobes to the TLS layer or the miner binary itself, the message content.

The practical eBPF detection approach is IP/port-based: flag any container making outbound TCP connections to the known Stratum mining pool port range (3333, 3334, 4444, 5555, 7777, 14444) to public internet addresses. This is high-signal in production environments where known-good outbound connectivity is defined — a payment service pod has no business connecting to port 3333 on a random public IP. The challenge is in development or test environments where developers might legitimately run miners or where security research pods exist.

An additional DNS signal: many mining pools use domain names (pool.hashvault.pro, xmrpool.net, c3pool.com). Correlating sys_enter_connect with DNS queries (observable via eBPF on the DNS socket calls) to known mining pool domains provides a second layer.

Detection Signal 3: CPU Anomaly Baseline Deviation

CPU spike detection is the last line — the signal that gets caught by billing alerts before security tools. But it's still a detection signal that eBPF can surface faster than billing. An eBPF program on a timer (BPF_PROG_TYPE_PERF_EVENT with a hardware performance counter) sampling CPU usage per-cgroup can identify containers exceeding their normal CPU utilization baseline by a statistically significant margin. A container that normally runs at 15% CPU utilization spiking to 98% and sustaining it is a mining indicator when combined with other signals.

The nuance: CPU anomaly alone has high false positive rate. A batch processing job, a compilation step, or a machine learning training run also saturates CPU. The CPU signal is most useful as a correlation factor: "CPU spike in container AND outbound connection to port 3333 AND process kswapd0 spawned as child of sh" is extremely high-confidence. The combination collapses the false positive rate to near zero.

A Realistic Attack Scenario: Test Namespace Persistence

Consider a plausible scenario: a 35-node GKE cluster running a multi-tenant SaaS product, with developers having create pods permissions in a dev namespace for testing. A developer's laptop credential is phished. The attacker uses the stolen kubeconfig to call kubectl run miner --image=docker.io/some-public-image:latest -n dev. The image appears benign (it's based on ubuntu:22.04 with no known CVEs) but contains a dormant XMRig binary that activates when a specific environment variable is set. The attacker's kubectl command sets that environment variable in the pod spec.

The attack runs undetected because: the image scan passed (no CVEs in the ubuntu base), the admission controller approved the pod (no PodSecurityStandards violation — the pod isn't privileged, doesn't use hostPID, runs as a normal user), and no one is watching the dev namespace closely. The miner runs for 6 days before a cloud billing alert fires at a 40% monthly cost increase.

With kernel-level detection: the execve tracepoint catches xmrig executing within 200ms of start. The Stratum outbound connection to pool port 3333 fires a second alert within seconds. Both alerts go to the SRE's Slack channel with process tree context showing: containerd-shimshxmrig, pod name miner, namespace dev, image digest. Triage time: under 5 minutes from detection to pod termination. Dwell time: under 10 minutes total.

What Detection Can't Do: The Image Supply Chain Problem

We're not saying runtime detection solves the image supply chain problem. A miner embedded in a supply chain-compromised base image still gets deployed if your image scanning doesn't catch it at build time. Runtime detection catches the execution — but for a supply chain compromise, the question is how quickly you catch it after deployment, not whether you catch it at build time.

The practical defense against this scenario is layered: image signing (cosign, Sigstore) to verify the provenance of images you deploy, admission policy requiring signed images, and runtime detection as the backstop when an attacker manages to inject a signed malicious image or when a zero-day enables post-deploy injection. Each layer catches different failure modes. Runtime detection's role is catching the things that got past the build and deploy layers — which, in practice, happens more often than the "shift-left first" narrative suggests.

See the cryptomining detection use case page for the full detection coverage matrix and response playbook, or read about how runtime detection fits alongside shift-left tools in a complete K8s security strategy. The platform page covers the eBPF engine and baseline learning mechanism in detail.