Was ist Poisoned Pipeline Execution (PPE)?

Poisoned Pipeline Execution (PPE), ein OWASP CI/CD-Sicherheitsrisiko, ist ein Angriffsvektor, der Zugriffsrechte auf ein Quellcode-Verwaltungssystem (SCM) missbraucht, um eine CI-Pipeline dazu zu bringen, bösartige Befehle auszuführen. PPE-Angreifer haben zwar keinen Zugriff auf die Build-Umgebung, aber sie haben sich Zugang zum SCM verschafft, was es ihnen ermöglicht, bösartigen Code in die Konfiguration der Build-Pipeline zu injizieren, um den Build-Prozess zu manipulieren.

 

CICD-SEC-4: Poisoned Pipeline Execution Erklärt

Poisoned Pipeline Execution (PPE), auf der OWASP Top 10 CI/CD Security Risks als CICD-SEC-4 aufgeführt, stellt eine ausgeklügelte Angriffsstrategie dar, die auf Systeme zur kontinuierlichen Integration und Bereitstellung (CI/CD) abzielt.

Den Kunden steht eine Vielzahl von Optionen zur Verfügung:

Bei der PPE-Strategie führen Angreifer bösartigen Code innerhalb des CI-Teils der CI/CD pipelineaus und umgehen damit die Notwendigkeit eines direkten Zugriffs auf das CI/CD-System. Die Methode beinhaltet die Manipulation von Berechtigungen in einem SCM-Repository (Source Code Management). Durch die Änderung von CI-Konfigurationsdateien oder anderen Dateien, von denen der CI-Pipeline-Job abhängt, injizieren Angreifer bösartige Befehle, die die CI-Pipeline effektiv vergiften und die Ausführung von nicht autorisiertem Code ermöglichen.

Erfolgreiche PSA-Angriffe können eine breite Palette von Operationen ermöglichen, die alle im Kontext der Identität der Pipeline ausgeführt werden. Zu den böswilligen Operationen gehören der Zugriff auf Geheimnisse, die dem CI-Job zur Verfügung stehen, der Zugriff auf externe Ressourcen, für die der Job-Knoten Berechtigungen hat, der Versand von scheinbar legitimem Code und Artefakten in der Pipeline und der Zugriff auf zusätzliche Hosts und Ressourcen im Netzwerk oder in der Umgebung des Job-Knotens.

Angesichts der kritischen Auswirkungen, der geringen Entdeckbarkeit und der Existenz mehrerer Ausnutzungstechniken stellt der PPE-Angriff eine weit verbreitete Bedrohung dar. Für Sicherheitsteams, Ingenieure und Red Teams ist das Verständnis von PSA und ihren Gegenmaßnahmen entscheidend für die CI/CD-Sicherheit

Pipeline-Ausführung definiert

Im Kontext der kontinuierlichen Integration (Continuous Integration, CI) bezieht sich der Ablauf der Pipeline-Ausführung auf die Abfolge von Operationen, die durch die CI-Konfigurationsdatei definiert sind, die in dem Repository gehostet wird, das die Pipeline erstellt. Diese Datei gibt die Reihenfolge der ausgeführten Aufträge an und enthält detaillierte Angaben zu den Einstellungen der Build-Umgebung und den Bedingungen, die den Ablauf beeinflussen. Wenn er ausgelöst wird, holt der Pipeline-Job den Code aus der gewählten Quelle (z.B. Commit/Ast) und führt die in der CI-Konfigurationsdatei angegebenen Befehle gegen diesen Code aus.

Die Befehle innerhalb der Pipeline werden entweder direkt durch die CI-Konfigurationsdatei oder indirekt durch ein Skript, einen Code-Test oder einen Linter in einer separaten Datei aufgerufen, auf die in der CI-Konfigurationsdatei verwiesen wird. CI-Konfigurationsdateien haben in der Regel einheitliche Namen und Formate, wie z.B. Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) und die GitHub Actions YAML-Dateien unter .github/workflows.

Angreifer können die Möglichkeit ausnutzen, Befehle, die von der Pipeline ausgeführt werden, entweder direkt oder indirekt zu manipulieren, um bösartigen Code in der KI auszuführen.

Wie die Ausnutzung von CICD-SEC-4 erfolgt

Damit ein PSA-Angriff erfolgreich ist, müssen mehrere Kriterien erfüllt sein:

  1. Der Angreifer muss Berechtigungen für ein SCM-Repository erhalten. Dies kann durch Benutzeranmeldeinformationen, Zugriffstoken, SSH-Schlüssel, OAuth-Token oder andere Methoden erfolgen. In manchen Fällen kann ein anonymer Zugriff auf ein öffentliches Repository ausreichen.
  2. Änderungen an dem betreffenden Repository müssen eine CI-Pipeline ohne zusätzliche Genehmigungen oder Überprüfungen auslösen. Dies kann durch direkte Pushs zu entfernten Zweigen oder durch Änderungen geschehen, die über eine Pull-Anfrage von einem entfernten Zweig oder einer Gabelung vorgeschlagen werden.
  3. Die vom Angreifer erhaltenen Berechtigungen müssen das Auslösen der Ereignisse erlauben, die die Ausführung der Pipeline verursachen.
  4. Die Dateien, die der Angreifer ändern kann, müssen die Befehle definieren, die (entweder direkt oder indirekt) von der Pipeline ausgeführt werden.
  5. Der Pipeline-Knoten muss Zugriff auf nicht-öffentliche Ressourcen haben, z. B. Geheimnisse, andere Knoten oder Rechenressourcen.

Pipelines, die ungeprüften Code ausführen, wie z.B. solche, die durch Pull-Requests oder Commits an beliebige Repository-Zweige ausgelöst werden, sind anfälliger für PPE. Sobald ein Angreifer bösartigen Code innerhalb der CI-Pipeline ausführen kann, kann er bösartige Operationen im Kontext der Identität der Pipeline durchführen.

Drei Arten der Ausführung von vergifteten Pipelines

Die Ausführung vergifteter Pipelines kann in drei verschiedenen Formen erfolgen: direkte PSA (D-PPE), indirekte PSA (I-PPE) und öffentliche PSA (3PE).

Direkt PSA

In einem direkten PSA-Szenario ändern Angreifer die CI-Konfigurationsdatei in einem Repository, auf das sie Zugriff haben, indem sie die Änderung entweder direkt in einen ungeschützten entfernten Zweig des Repositorys pushen oder eine Pull-Anfrage mit der Änderung von einem Zweig oder Fork einreichen. Die Ausführung der Pipeline wird durch die Push- oder Pull-Request-Ereignisse ausgelöst, die durch Befehle in der geänderten CI-Konfigurationsdatei definiert sind. Dies führt dazu, dass die bösartigen Befehle im Build-Knoten ausgeführt werden, sobald die Build-Pipeline ausgelöst wird.

Direkter Angriff auf die Ausführung einer vergifteten Pipeline

Abbildung 1: Direkter Angriff auf die Ausführung einer vergifteten Pipeline

Das in Abbildung 1 dargestellte Beispiel eines D-PPE-Angriffs läuft in der folgenden Abfolge von Schritten ab:

  1. Ein Angreifer initiiert eine neue Remote-Verzweigung innerhalb des Repositorys und ändert die Pipeline-Konfigurationsdatei mit schädlichen Anweisungen, um AWS-Zugangsdaten, die innerhalb der GitHub Organisation gespeichert sind, abzurufen und an einen externen Server unter der Kontrolle des Angreifers zu übertragen.
  2. Der Code-Push aktiviert eine Pipeline, die den Code, einschließlich der bösartigen Pipeline-Konfigurationsdatei, aus dem Repository abruft.
  3. Die Pipeline arbeitet gemäß der Konfigurationsdatei, die nun vom Angreifer verfälscht wurde. Die bösartigen Anweisungen befehlen, die AWS-Anmeldedaten, die als Repository-Geheimnisse gespeichert sind, in den Speicher zu laden.
  4. Den Anweisungen des Angreifers folgend, führt die Pipeline die Aufgabe aus, die AWS-Anmeldedaten an einen Server unter der Kontrolle des Angreifers zu übermitteln.
  5. Im Besitz der gestohlenen Zugangsdaten kann der Angreifer in die Produktionsumgebung eindringen.

Indirekte PSA

Indirekte PSA liegt vor, wenn ein Angreifer, der Zugriff auf ein SCM-Repository hat, nicht die Möglichkeit hat, D-PPE zu nutzen:

  • Wenn die Pipeline so konfiguriert ist, dass sie die CI-Konfigurationsdatei aus einem separaten, geschützten Zweig desselben Repositorys bezieht.
  • Wenn die CI-Konfigurationsdatei in einem vom Quellcode getrennten Repository gespeichert ist, ohne dass ein Benutzer die Möglichkeit hat, sie direkt zu bearbeiten.
  • Wenn der CI-Build im CI-System selbst definiert wird - statt in einer im Quellcode gespeicherten Datei.

In diesen Szenarien kann der Angreifer die Pipeline immer noch vergiften, indem er bösartigen Code in Dateien einschleust, auf die die Pipeline-Konfigurationsdatei verweist, z. B. in Skripte, auf die in der Pipeline-Konfigurationsdatei verwiesen wird, in Code-Tests oder in automatische Tools wie Linters und Sicherheitsscanner, die in der CI verwendet werden. Zum Beispiel:

  • Das Dienstprogramm make führt Befehle aus, die in der Datei Makefile definiert sind.
  • Skripte, auf die in der Konfigurationsdatei der Pipeline verwiesen wird und die im gleichen Repository wie der Quellcode selbst gespeichert sind (z.B. python myscript.py - wobei myscript.py vom Angreifer manipuliert werden würde).
  • Code-Tests: Test-Frameworks, die im Rahmen des Build-Prozesses auf Anwendungscode laufen, stützen sich auf spezielle Dateien, die im selben Repository wie der Quellcode gespeichert sind. Angreifer, die den für die Tests verantwortlichen Code manipulieren können, können dann bösartige Befehle innerhalb des Builds ausführen.
  • Automatische Werkzeuge: Linters und Sicherheitsscanner, die in der KI eingesetzt werden, verlassen sich in der Regel auf eine Konfigurationsdatei im Repository, die externen Code von einem in der Konfigurationsdatei definierten Ort lädt und ausführt.

Anstatt die Pipeline über direkte PSA zu vergiften, injiziert der Angreifer, der einen indirekten PSA-Angriff startet, bösartigen Code in Dateien, auf die die Konfigurationsdatei verweist. Der bösartige Code wird schließlich auf dem Pipeline-Knoten ausgeführt und führt die in den Dateien angegebenen Befehle aus.

Indirekte vergiftete Pipeline-Ausführung Angriffsablauf

Abbildung 2: Indirekte vergiftete Pipeline-Ausführung Angriffsablauf

In diesem Beispiel für einen I-PPE-Angriff läuft die Ereigniskette wie folgt ab:

  1. Ein Angreifer erstellt eine Pull-Anfrage im Repository und fügt bösartige Befehle an die Makefile-Datei an.
  2. Da die Pipeline so konfiguriert ist, dass sie bei jedem PR gegen das Repository ausgelöst wird, wird die Jenkins-Pipeline ausgelöst und holt sich den Code aus dem Repository - einschließlich des bösartigen Makefiles.
  3. Die Pipeline wird auf der Grundlage der im Hauptzweig gespeicherten Konfigurationsdatei ausgeführt. Es erreicht die Build-Phase und lädt die AWS-Anmeldedaten in die Umgebungsvariablen - wie in der ursprünglichen Jenkins-Datei definiert. Dann führt er den Befehl make build aus, der den bösartigen Befehl ausführt, der in Makefile hinzugefügt wurde.
  4. Die in der Makefile definierte bösartige Build-Funktion wird ausgeführt und sendet die AWS-Anmeldedaten an einen vom Angreifer kontrollierten Server.
  5. Der Angreifer kann dann die gestohlenen Anmeldeinformationen verwenden, um auf die AWS-Produktionsumgebung zuzugreifen.

Öffentliche PSA

Öffentliche PSA ist eine Art von PSA-Angriff, der von anonymen Angreifern über das Internet ausgeführt wird. Öffentliche Repositories erlauben es oft jedem Benutzer, einen Beitrag zu leisten, in der Regel durch das Erstellen von Pull Requests. Wenn die CI-Pipeline eines öffentlichen Repositorys ungeprüften, von anonymen Benutzern vorgeschlagenen Code ausführt, ist sie anfällig für einen öffentlichen PSA-Angriff. Die öffentliche PSA kann auch interne Werte preisgeben, wie z.B. Geheimnisse privater Projekte, wenn die Pipeline des verwundbaren öffentlichen Repositorys auf der gleichen CI-Instanz läuft wie private Projekte.

 

Die Bedeutung der sicheren Ausführung von Pipelines in CI/CD

Das Ausführen von bösartigem, nicht überprüftem Code im CI über einen erfolgreichen PPE-Angriff verschafft Angreifern den gleichen Zugriff und die gleichen Möglichkeiten wie der Build-Job:

  • Zugriff auf Geheimnisse, die dem CI-Job zur Verfügung stehen, wie z.B. Geheimnisse, die als Umgebungsvariablen injiziert wurden oder zusätzliche Geheimnisse, die im CI gespeichert sind. Da CI/CD-Systeme für die Erstellung von Code und die Bereitstellung von Artefakten verantwortlich sind, enthalten sie in der Regel Dutzende von hochwertigen Anmeldeinformationen und Token - beispielsweise für einen Cloud-Anbieter, für Artefaktregistrierungen und für das SCM selbst.
  • Zugriff auf externe Assets, auf die der Job-Knoten Zugriffsrechte hat, z. B. auf Dateien, die im Dateisystem des Knotens gespeichert sind, oder auf Zugangsdaten zu einer Cloud-Umgebung, die über den zugrunde liegenden Host zugänglich ist.
  • Die Möglichkeit, Code und Artefakte weiter unten in der Pipeline auszuliefern, unter dem Deckmantel von legitimem Code, der durch den Build-Prozess erstellt wurde.
  • Möglichkeit des Zugriffs auf zusätzliche Hosts und Assets im Netzwerk/der Umgebung des Job Nodes.

Aber Organisationen können ihre Softwareprodukte und ihre Infrastruktur mit einer sicheren Pipeline-Ausführung schützen, die sicherstellt, dass der gesamte kompilierte, getestete und bereitgestellte Code legitim und unangetastet ist.

Risiken im Zusammenhang mit der Ausführung von vergifteten Pipelines

Die Folgen von PSA können schwerwiegend sein und reichen von unbefugtem Datenzugriff, beeinträchtigter Software-Integrität, Systemunterbrechungen bis hin zu Datenverletzungen oder sogar einer vollständigen Systemübernahme. Diese Risiken stellen eine erhebliche Bedrohung sowohl für das Unternehmen als auch für seine Kunden dar, was die Bedeutung von PSA unterstreicht.

Nachgelagerte Auswirkungen einer vergifteten CI-Pipeline

Abbildung 3: Nachgelagerte Auswirkungen einer vergifteten CI-Pipeline

Bei der Kompromittierung der Lieferkette in acht Schritten, die in Abbildung 3 zu sehen ist, verschafft sich der Angreifer Zugang zur CI-Pipeline und vergiftet Komponenten der SaaS-Anwendung. Über die vergiftete Komponente baut der Angreifer Backdoor-Funktionen in die Anwendung ein und sendet die vergifteten Plugins an nachgeschaltete Clients. Da die nachgelagerten Organisationen das vergiftete Paket wahrscheinlich für legitim halten, bauen sie es in ihre Cloud- oder firmeninterne Infrastruktur ein.

Von einer vergifteten CI-Pipeline aus erreicht der Angreifer einen exponentiellen Kollateralschaden, da er sich durch eine Hintertür Zugang zu unzähligen Organisationen verschafft hat. Dies war der Fall bei dem SolarWinds Angriff.

LESEN SIE MEHR: Anatomie eines Angriffs auf eine CI/CD-Pipeline

 

Verhinderung der Ausführung von vergifteten Pipelines

Die Vorbeugung und Entschärfung von PPE-Angriffen umfasst mehrere Maßnahmen, die sowohl SCM- als auch CI-Systeme umfassen:

  • Stellen Sie sicher, dass Pipelines, die ungeprüften Code ausführen, auf isolierten Knoten ausgeführt werden und nicht in geheimen und sensiblen Umgebungen.
  • Evaluieren Sie die Notwendigkeit, Pipelines für öffentliche Repositories von externen Autoren zu starten. Verzichten Sie nach Möglichkeit auf die Ausführung von Pipelines, die von Forks stammen, und ziehen Sie zusätzliche Kontrollen in Betracht, wie z.B. eine manuelle Genehmigung für die Ausführung von Pipelines.
  • Bei sensiblen Pipelines, z.B. solchen, die Geheimnissen ausgesetzt sind, stellen Sie sicher, dass jede Verzweigung, die so konfiguriert ist, dass sie eine Pipeline im CI-System auslöst, über eine korrelierende Zweigschutzregel im SCM verfügt.
  • Um die Manipulation der CI-Konfigurationsdatei zur Ausführung von bösartigem Code in der Pipeline zu verhindern, muss jede CI-Konfigurationsdatei vor der Ausführung der Pipeline überprüft werden. Alternativ kann die CI-Konfigurationsdatei in einem entfernten Zweig verwaltet werden, getrennt von dem Zweig, der den Code enthält, der in der Pipeline gebaut wird. Der entfernte Zweig sollte als geschützt konfiguriert werden.
  • Entfernen Sie Berechtigungen für das SCM-Repository von Benutzern, die sie nicht benötigen.
  • Jede Pipeline sollte nur auf die Zugangsdaten zugreifen können, die sie zur Erfüllung ihres Zwecks benötigt. Die Berechtigungsnachweise sollten über die erforderlichen Mindestberechtigungen verfügen.

 

FAQs zur vergifteten Pipeline-Ausführung

Ein Build-Server ist ein Rechner, auf dem der Build-Prozess eines Projekts ausgeführt wird. Es kompiliert den Quellcode in ausführbaren Code.
Eine Staging-Umgebung ist eine Nachbildung der Produktionsumgebung, die zum Testen verwendet wird. Es hilft, potenzielle Fehler oder Probleme zu erkennen, bevor sie sich auf den Endbenutzer auswirken.
Ein Linter ist ein Werkzeug, das den Quellcode analysiert, um Programmierfehler, Bugs, stilistische Fehler und verdächtige Konstruktionen zu erkennen. Wenn der Linter Probleme meldet, kann die Pipeline so konfiguriert werden, dass sie fehlschlägt, so dass der Code nicht zur nächsten Stufe übergehen kann. Dies hilft Organisationen, nur Code bereitzustellen, der den definierten Qualitätsstandards entspricht.
Die Bereitstellung von Blue/Green ist eine Strategie für das Versionsmanagement, die Ausfallzeiten und Risiken reduziert, indem zwei identische Produktionsumgebungen, genannt Blue und Green, betrieben werden. Zu jeder Zeit ist nur eine davon live, wobei die Live-Umgebung den gesamten Produktionsverkehr bedient.
Ein Rollback ist die Rückkehr zur vorherigen Version einer Softwareanwendung, wenn die neue Version Probleme aufweist. Es handelt sich um eine Sicherheitsmaßnahme, die die Systemstabilität im Falle einer problematischen Bereitstellung gewährleistet.
Ein Smoke-Test, auch bekannt als Build-Verifikationstest, ist eine Art von Softwaretest, der eine nicht erschöpfende Reihe von Tests umfasst, die sicherstellen sollen, dass die wichtigsten Funktionen funktionieren.
Ein Canary-Release ist eine Technik zur Verringerung des Risikos bei der Einführung neuer Softwareversionen in der Produktion, indem die Änderung langsam an eine Untergruppe von Benutzern ausgerollt wird, bevor sie in der gesamten Infrastruktur eingeführt wird.
Infrastructure as codeist der Prozess der Verwaltung und Provisionierung von Computer-Rechenzentren durch maschinenlesbare Definitionsdateien anstelle von physischer Hardware-Konfiguration oder interaktiven Konfigurations-Tools.
Kontinuierliche Integration ist eine Entwicklungspraxis, bei der Entwickler ihre Codeänderungen kontinuierlich in ein zentrales Repository einbringen, gefolgt von automatisierten Builds und Tests.
Unter Continuous Delivery versteht man die Automatisierung des gesamten Software-Release-Prozesses. Nach Bestehen der automatisierten Tests werden die Codeänderungen automatisch in einer produktionsähnlichen Umgebung für weitere Tests und Validierungen bereitgestellt.
Eine Bereitstellungspipeline ist der Weg, den eine Codeänderung von der Versionskontrolle bis zur Produktionsumgebung nimmt. Es umfasst Phasen wie Erstellung, Test und Bereitstellung.
Zurück Was ist eine unsichere Systemkonfiguration?