Cyberbedrohungen
Undichte Labels: Umgehen von Traefik Proxy
Container-Labels sind nicht immer der sicherste Weg, um sensible Informationen wie Anmeldedaten und Metadaten zu Objekten zu speichern. Deren Verarbeitung für eine Funktion bleibt nämlich unter Umständen unbemerkt. Wir haben die Einzelheiten.
Wir beschrieben bereits, wie falsch konfigurierte Implementierungen des Container Advisors (cAdvisor) versehentlich in Umgebungsvariablen gespeicherte Informationen, die Anmeldeinformationen, Token und Ähnliches enthalten, in Form von Prometheus-Metriken offenlegen können. Darüber hinaus stellten fest, dass die Metriken standardmäßig alle Container-Labels für jeden laufenden Container enthielten. Im Allgemeinen werden Container-Labels nicht als Geheimnis betrachtet - oder doch? Anhand einer Fallstudie eines weit verbreiteten Cloud Native Application Proxy, bekannt als Traefik Proxy, sollen die Risiken offener Container-Labels in cAdvisor-Metriken dargestellt werden.
Bei der Untersuchung der im Metrik-Endpunkt von cAdvisor angezeigten Informationen fiel auf, dass Container-Labels für alle laufenden Container am Endpunkt /metrics angezeigt werden. Container-Labels sind Schlüssel-Wert-Paare, die als String gespeichert werden. Sie werden verwendet, um Metadaten wie Lizenzinformationen, Betreuerinformationen und Versionsangaben zu Container-Objekten wie Container-Images, laufenden Containern, Volumes, Daemons und Netzwerken zu speichern. Best Practices für den Einsatz von Container Labels finden Interessierte in den Guidelines der Open Container Initiative (OCI) auf GitHub.
Werden diese Container-Labels als ein Geheimnis betrachtet? Sie sind lediglich als Metadaten zum Objekt gedacht. Wenn beispielsweise ein Image eines Containers öffentlich zugänglich ist und von jedermann abgerufen werden kann, wird erwartet oder angenommen, dass die in der LABEL-Anweisung angegebenen Metadaten keine Geheimnisse enthalten. Um die Metriken in einem viel besser lesbaren Format von einem exponierten /metrics-Endpunkt zu erhalten, lässt sich ein Open-Source-Tool von den Prometheus-Entwicklern namens prom2json verwenden. Mit diesem Tool werden Prometheus-Metriken ausgelesen und in JSON-Dateien umgewandelt.
Danach wollten wir wissen, was diese Container-Labels in öffentlich zugänglichen cAdvisor-Instanzen enthielten. Auffällig waren bestimmte Container-Labels, die mit container_label_traefik_ beginnen und scheinbar Benutzernamen und Passwort-Hashes enthalten.
Dazu muss man verstehen, was Traefik Proxy ist. Es ist ein quelloffener, Cloud-nativer Anwendungsproxy, der als Ingress Controller, Reverse Proxy, Web Application Firewall und Load Balancer fungieren kann. Er verwendet Service Discovery, um das Routing dynamisch zu konfigurieren und unterstützt alle wichtigen Protokolle wie HTTP/2, HTTP/3, TCP, UDP, WebSockets sowie gRPC und nutzt Middleware für Load Balancing, Ratenbegrenzung, Circuit Breakers, Mirroring, Authentifizierung und mehr. Traefik Proxy unterstützt auch die SSL-Terminierung und kann zur automatischen Generierung von Zertifikaten mit Anbietern wie Let's Encrypt verwendet werden.
Mit nativer Unterstützung für Services und Plattformen wie Kubernetes, Docker Swarm, etcd, Azure Service Fabric, Amazon Elastic Container Service (ECS), Azure Kubernetes Service (AKS), Elastic Kubernetes Service (EKS), Google Kubernetes Engine (GKE) und OpenShift ist der Traefik-Proxy weit verbreitet und mit über 48.000 Sternen auf GitHub sehr beliebt. Die umfangreichen Funktionen und Möglichkeiten machen ihn zu einem umfassenden Gateway für verschiedene Anwendungsgruppen.
Traefik enthält folgende Komponenten: Providers, EntryPoints, Routers, Middleware und Services. Einzelheiten dazu enthält der Originalbeitrag.
Von diesen Komponenten sind EntryPoints und Provider statischer Natur, d.h. sie werden nur beim Start benötigt und ändern sich nach dem Start des Traefik-Proxys nicht mehr. Die übrigen Komponenten verarbeiten und leiten eingehende Anfragen weiter und sind vollständig dynamisch.
Quelle: Traefik
Wir interessieren uns insbesondere dafür, wie die Konfigurationsermittlung für Docker-Container funktioniert. Bei der Verwendung von Docker, Swarm oder Amazon ECS als Provider kann der Traefik-Proxy die Routing-Konfiguration dynamisch auffüllen, indem er entweder Container-Labels oder dynamische Konfigurationen verwendet, die als Dateien angegeben werden. Bei Docker-Compose holt sich der Traefik-Proxy die Routing-Konfiguration aus der „labels“-Direktive der „Services“-Objekte.
Quelle: Traefik
Einzelheiten und ein Beispiel, finden sich im Originalbeitrag.
Zusammenfassend lässt sich sagen, dass wir bei der Bestimmung der Traefik-Konfiguration, bei der der Provider Docker ist, Container-Labels für den Traefik-Proxy verwendeten, um den Service dynamisch zu erkennen und die Anfragen auf der Grundlage des Host-Header-Matchers und der BasicAuth-Middleware weiterzuleiten. Diese Konfigurationsinformationen können auch aus den Labels des laufenden Containers mit "docker inspect" geholt werden. Dies ist eine offensichtliche, aber interessante Beobachtung, dass die Container-Labels für den Ziel-Service die Traefik-Regelkonfiguration enthalten.
cAdvisor
In einer Standardkonfiguration gibt cAdvisor Container-Labels als Prometheus-Metriken aus. Da es sich hierbei um eine Standardkonfiguration handelt, wollten wir sehen, ob es echte Implementierungen gibt, bei denen Traefik-Proxy und cAdvisor mit den exponierten cAdvisor-Metriken laufen. Es ist erwähnenswert, dass der cAdvisor-Metriken-Endpunkt nicht nativ mit cAdvisor geschützt werden kann.
Einzelheiten zu einer angreifbaren Beispielskonfiguration von Docker Compose YAML umfasst der Originalbeitrag.
Exploit-Szenarien
Da die Traefik-Proxy-Konfiguration aufgrund der Art und Weise, wie cAdvisor Container-Labels in den Metriken ausgibt, exponiert ist, kann dies von Angreifern ausgenutzt werden, um den Traefik-Proxy vollständig zu umgehen und auf folgende Weise unbefugten Zugriff auf die von Traefik geschützten Services zu erhalten:
- Der Angreifer könnte Container-Labels vom "/metrics"-Endpunkt einer exponierten cAdvisor-Instanz abrufen. Da der "/metrics"-Endpunkt standardmäßig aktiviert ist, kann dieser nicht mit cAdvisor nativ geschützt werden und gibt alle Container-Labels für alle laufenden Container preis.
- Anhand der Container-Labels könnten Angreifer den Zielservice, der durch den Traefik-Proxy geschützt wird, ermitteln. Sie könnten zum Beispiel den "Host"-Header-Matcher oder die BasicAuth-Middleware-Konfiguration verwenden, die Hashes für Benutzernamen und Passwörter enthält, da diese als Container-Labels gespeichert sind. Angreifer könnten versuchen, diese Hashes offline zu knacken.
- Mit dem geknackten Anmeldedatenpaar und/oder durch Missbrauch der Reverse-Proxy-Konfiguration könnte ein Angreifer den Traefik-Proxy vollständig umgehen und auf die zu schützenden Services zugreifen.
Neben den Traefik-Konfigurationen stießen wir auf Container-Labels mit Amazon ECS-Metadaten, die den Namen des ECS-Containers, des ECS-Clusters und der ECS-Task-ARNs offenbaren. Mit diesen Informationen kann ein Unbefugter Informationen über die AWS-Umgebung wie AWS-Konto-IDs erhalten.
Schutzmaßnahmen
Es mag so aussehen, als ob Container-Labels der einzige Weg sind, um mit Docker, ECS und Swarm-Anbietern voranzukommen. Es gibt jedoch eine sichere Möglichkeit, Traefik ohne Container-Labels einzusetzen. Ein Beispiel im Originalbeitrag zeigt, wie man dynamische Konfigurationen in Dateien anstelle von Container-Etiketten angeben kann.
Als Abwehrmaßnahmen zum Schutz vor unbeabsichtigten Enthüllungen können die Verteidiger Folgendes tun:
- Muss Ihr Metrik-Endpunkt wirklich öffentlich zugänglich sein? Wenn nicht, schützen Sie ihn.
- Erstellen Sie ein Bedrohungsmodell für Ihre Edge-Router, indem Sie die Funktionen und die damit verbundenen Risiken gründlich prüfen. Verwenden Sie beispielsweise die Konfigurationsoption usersFile anstelle von usersin der BasicAuth-Middleware, um zu verhindern, dass die Hashes der Anmeldedaten nach außen dringen, falls die Container-Labels von Komponenten wie cAdvisor ausgelesen werden. Das Lesen einer Datei von der Festplatte im Vergleich zur Anzeige von Metriken erschwert Angreifern die Ausnutzung.
- Überwachen Sie die Offenlegung Ihrer Umgebung kontinuierlich, um solche unbeabsichtigte Exponierung zu vermeiden.
- Scannen Sie proaktiv Ihre Codebasen (Docker-Compose-YAMLs, Kubernetes-Objekt-YAMLs und ähnliche Vorlagen) auf Instanzen von Anbietern, bei denen Traefik auf Container-Labels angewiesen ist, wie Amazon ECS-, Docker- und Swarm-Konfigurationen, die mit cAdvisor verwendet werden. Vermeiden Sie die Verwendung von Container-Labels für die Speicherung von Anmeldedaten oder sensiblen Informationen und verwenden Sie stattdessen Dateianbieter.
- Die cAdvisor-Bereitstellung kann durch die Verwendung von TLS und der BasicAuth-Middleware gesichert werden, um zu verhindern, dass cAdvisor der Öffentlichkeit zugänglich gemacht wird.
- Um zu verhindern, dass cAdvisor alle Container-Labels prüft, kann man die Option --store_container_labels verwenden oder eine Erlaubnisliste von Container-Labels erstellen und --whitelisted_container_labels verwenden.
- Verhindern Sie, dass cAdvisor-Dashboards der Öffentlichkeit zugänglich gemacht werden.
Fazit
Für sich genommen ist der Traefix-Proxy bereits von Haus aus ziemlich sicher. Aufgrund der Funktionen und Designentscheidungen zur Verwendung von Container-Labels für Docker-, ECS- und Swarm-Anbieter wird es jedoch unscharf, wenn andere Komponenten wie cAdvisor ins Spiel kommen. Wir schätzen Traefiks Einblicke in die Ergebnisse dieser Untersuchung, was zu seinem Vorschlag für zusätzliche Sicherheitsrichtlinien führte, die nun hier integriert wurden. Nach der Überprüfung stimmt Traefik zu, dass die Verwendung von Docker-Labels kein sicherer Weg ist, um sensible Informationen wie Anmeldedaten zu speichern. Traefik empfiehlt jedoch sicherere Methoden zur Speicherung vertraulicher Daten, wie die Verwendung von Dateien oder Geheimnissen.
Aufgrund der gegenseitigen Abhängigkeit und potenzieller Diskrepanzen zwischen der Art und Weise, wie bestimmte Funktionen verwendet werden, und der Art und Weise, wie sie verwendet werden sollen, Angreifer letztendlich erfolgreich sind und Verteidiger es schwer machen. Außerdem können bei der Verwendung mehrerer Services die Funktionen, die diese Services bieten, gefährlich werden, wenn sie nicht entsprechend behandelt werden. Die Verwendung von Container-Label für die Speicherung von Metadaten eines Objekts ist vernünftig; allerdings kann deren Verarbeitung für eine Funktionalität unbemerkt bleiben, da Container-Labels für einen Nutzer im Vorfeld nicht wirklich sichtbar sind (es sei denn, der Nutzer überprüft die Label des Objekts manuell). Die Absicherung der Anwendungen erfordert ein tiefes Verständnis der komplexen Beziehungen zwischen verschiedenen Komponenten und Services.