Jenkins Security
Grundlegende Informationen
Jenkins ist ein Tool, das eine einfache Methode zur Einrichtung einer kontinuierlichen Integration oder kontinuierlichen Bereitstellung (CI/CD)-Umgebung für fast jede Kombination von Programmiersprachen und Quellcode-Repositories mithilfe von Pipelines bietet. Darüber hinaus automatisiert es verschiedene routinemäßige Entwicklungsaufgaben. Obwohl Jenkins nicht die Notwendigkeit beseitigt, Skripte für einzelne Schritte zu erstellen, bietet es dennoch eine schnellere und robustere Möglichkeit, die gesamte Sequenz von Build-, Test- und Bereitstellungstools zu integrieren, als man dies manuell leicht erstellen könnte.
pageBasic Jenkins InformationNicht authentifizierte Enumeration
Um nach interessanten Jenkins-Seiten ohne Authentifizierung zu suchen (wie z. B. /people oder /asynchPeople, die die aktuellen Benutzer auflisten), können Sie Folgendes verwenden:
Überprüfen Sie, ob Sie Befehle ohne Authentifizierung ausführen können:
Ohne Anmeldeinformationen können Sie den Pfad /asynchPeople/ oder /securityRealm/user/admin/search/index?q= nach Benutzernamen durchsuchen.
Sie können die Jenkins-Version möglicherweise aus dem Pfad /oops oder /error erhalten.
Bekannte Sicherheitslücken
Anmeldung
In den grundlegenden Informationen können Sie alle Möglichkeiten überprüfen, sich bei Jenkins anzumelden:
pageBasic Jenkins InformationRegistrierung
Sie können Jenkins-Instanzen finden, die es Ihnen ermöglichen, ein Konto zu erstellen und sich darin anzumelden. So einfach ist das.
SSO-Anmeldung
Wenn auch SSO-Funktionalität/-Plugins vorhanden waren, sollten Sie versuchen, sich mit einem Testkonto (z. B. einem Test-Github/Bitbucket-Konto) in der Anwendung anzumelden. Trick von hier.
Bruteforce
Jenkins fehlt eine Passwortrichtlinie und eine Benutzername-Brute-Force-Mitigation. Es ist wichtig, Benutzer durch Brute-Force zu ermitteln, da schwache Passwörter oder Benutzernamen als Passwörter verwendet werden können, sogar umgekehrte Benutzernamen als Passwörter.
Passwort-Spraying
Verwenden Sie dieses Python-Skript oder dieses PowerShell-Skript.
Umgehung der IP-Whitelist
Viele Organisationen kombinieren SaaS-basierte Quellcode-Verwaltungssysteme (SCM) wie GitHub oder GitLab mit einer internen, selbstgehosteten CI-Lösung wie Jenkins oder TeamCity. Diese Konfiguration ermöglicht es CI-Systemen, Webhook-Ereignisse von SaaS-Quellcode-Anbietern zu empfangen, hauptsächlich zur Auslösung von Pipeline-Jobs.
Um dies zu erreichen, whitelisten Organisationen die IP-Bereiche der SCM-Plattformen, um diesen den Zugriff auf das interne CI-System über Webhooks zu ermöglichen. Es ist jedoch wichtig zu beachten, dass jeder ein Konto bei GitHub oder GitLab erstellen und es konfigurieren kann, um einen Webhook auszulösen, der möglicherweise Anfragen an das interne CI-System sendet.
Überprüfen Sie: shttps://www.cidersecurity.io/blog/research/how-we-abused-repository-webhooks-to-access-internal-ci-systems-at-scale/
Interne Jenkins-Missbräuche
In diesen Szenarien gehen wir davon aus, dass Sie über ein gültiges Konto zum Zugriff auf Jenkins verfügen.
Je nach konfiguriertem Autorisierungsmechanismus in Jenkins und den Berechtigungen des kompromittierten Benutzers können Sie die folgenden Angriffe möglicherweise oder auch nicht durchführen.
Für weitere Informationen überprüfen Sie die grundlegenden Informationen:
pageBasic Jenkins InformationAuflisten von Benutzern
Wenn Sie auf Jenkins zugegriffen haben, können Sie andere registrierte Benutzer unter http://127.0.0.1:8080/asynchPeople/ auflisten.
Dumping von Builds zur Suche nach Klartextgeheimnissen
Verwenden Sie dieses Skript, um Build-Konsolenausgaben und Build-Umgebungsvariablen zu dumpen und hoffentlich Klartextgeheimnisse zu finden.
Stehlen von SSH-Anmeldeinformationen
Wenn der kompromittierte Benutzer ausreichende Berechtigungen hat, um einen neuen Jenkins-Knoten zu erstellen/zu ändern und SSH-Anmeldeinformationen bereits gespeichert sind, um auf andere Knoten zuzugreifen, könnte er diese Anmeldeinformationen stehlen, indem er einen Knoten erstellt/ändert und einen Host einstellt, der die Anmeldeinformationen aufzeichnet, ohne den Hostschlüssel zu überprüfen:
In der Regel finden Sie Jenkins-SSH-Anmeldeinformationen in einem globalen Anbieter (/credentials/
), sodass Sie sie auch wie jedes andere Geheimnis auslesen können. Weitere Informationen im Abschnitt zum Auslesen von Geheimnissen.
RCE in Jenkins
Das Erhalten einer Shell im Jenkins-Server gibt dem Angreifer die Möglichkeit, alle Geheimnisse und Umgebungsvariablen preiszugeben und andere Maschinen im selben Netzwerk oder sogar Cloud-Anmeldeinformationen zu nutzen.
Standardmäßig wird Jenkins als SYSTEM ausgeführt. Daher gibt das Kompromittieren dem Angreifer SYSTEM-Berechtigungen.
RCE Erstellen/Ändern eines Projekts
Das Erstellen/Ändern eines Projekts ist eine Möglichkeit, RCE über den Jenkins-Server zu erhalten:
pageJenkins RCE Creating/Modifying ProjectRCE Ausführen eines Groovy-Skripts
Sie können auch RCE erhalten, indem Sie ein Groovy-Skript ausführen, was möglicherweise unauffälliger ist als das Erstellen eines neuen Projekts:
pageJenkins RCE with Groovy ScriptRCE Erstellen/Ändern einer Pipeline
Sie können auch RCE erhalten, indem Sie eine Pipeline erstellen/ändern:
pageJenkins RCE Creating/Modifying PipelinePipeline-Ausnutzung
Um Pipelines auszunutzen, benötigen Sie immer noch Zugriff auf Jenkins.
Build-Pipelines
Pipelines können auch als Build-Mechanismus in Projekten verwendet werden, in diesem Fall kann eine Datei im Repository konfiguriert werden, die die Pipelinesyntax enthält. Standardmäßig wird /Jenkinsfile
verwendet:
Es ist auch möglich, Pipeline-Konfigurationsdateien an anderen Orten zu speichern (zum Beispiel in anderen Repositories), um den Zugriff auf das Repository und den Zugriff auf die Pipeline zu trennen.
Wenn ein Angreifer Schreibzugriff auf diese Datei hat, kann er sie ändern und möglicherweise die Pipeline auslösen, ohne überhaupt Zugriff auf Jenkins zu haben. Es ist möglich, dass der Angreifer einige Zweig-Schutzmechanismen umgehen muss (je nach Plattform und den Benutzerberechtigungen können sie umgangen werden oder nicht).
Die häufigsten Auslöser für die Ausführung einer benutzerdefinierten Pipeline sind:
Pull-Anforderung an den Hauptzweig (oder möglicherweise an andere Zweige)
Push zum Hauptzweig (oder möglicherweise zu anderen Zweigen)
Aktualisierung des Hauptzweigs und Warten, bis er auf irgendeine Weise ausgeführt wird
Wenn Sie ein externer Benutzer sind, sollten Sie nicht erwarten, eine PR an den Hauptzweig des Repos eines anderen Benutzers/Unternehmens zu erstellen und die Pipeline auszulösen... aber wenn sie schlecht konfiguriert ist, könnten Sie Unternehmen vollständig kompromittieren, indem Sie dies ausnutzen.
Pipeline-RCE
Im vorherigen Abschnitt zu RCE wurde bereits eine Technik angegeben, um RCE durch Ändern einer Pipeline zu erhalten.
Überprüfen von Umgebungsvariablen
Es ist möglich, Klartext-Umgebungsvariablen für die gesamte Pipeline oder für bestimmte Phasen zu deklarieren. Diese Umgebungsvariablen sollten keine sensiblen Informationen enthalten, aber ein Angreifer könnte immer alle Pipeline-Konfigurationen/Jenkinsfiles überprüfen:
Dumping von Geheimnissen
Für Informationen darüber, wie Geheimnisse normalerweise von Jenkins behandelt werden, schauen Sie sich die grundlegenden Informationen an:
pageBasic Jenkins InformationAnmeldeinformationen können auf globale Anbieter (/credentials/
) oder auf spezifische Projekte (/job/<project-name>/configure
) beschränkt sein. Daher müssen Sie mindestens alle Projekte kompromittieren, die Geheimnisse enthalten, und benutzerdefinierte/verseuchte Pipelines ausführen, um alle von ihnen zu exfiltrieren.
Es gibt ein weiteres Problem: Um ein Geheimnis innerhalb der Umgebung einer Pipeline zu erhalten, müssen Sie den Namen und Typ des Geheimnisses kennen. Wenn Sie beispielsweise versuchen, ein usernamePassword
-Geheimnis als string
-Geheimnis zu laden, erhalten Sie diesen Fehler:
Hier ist der Weg, um einige gängige Arten von Geheimnissen zu laden:
Am Ende dieser Seite finden Sie alle Arten von Anmeldeinformationen: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
Der beste Weg, um alle Geheimnisse auf einmal preiszugeben, besteht darin, die Jenkins-Maschine zu kompromittieren (zum Beispiel durch Ausführen einer Reverse-Shell im integrierten Knoten) und dann die Master-Schlüssel und die verschlüsselten Geheimnisse zu leaken und offline zu entschlüsseln. Mehr dazu finden Sie im Abschnitt Nodes & Agents und im Abschnitt Post Exploitation.
Auslöser
Aus der Dokumentation: Die triggers
-Direktive definiert die automatisierten Methoden, mit denen der Pipeline erneut ausgelöst werden soll. Für Pipelines, die mit einer Quelle wie GitHub oder BitBucket integriert sind, sind triggers
möglicherweise nicht erforderlich, da wahrscheinlich bereits eine Integration basierend auf Webhooks vorhanden ist. Die derzeit verfügbaren Auslöser sind cron
, pollSCM
und upstream
.
Cron-Beispiel:
Überprüfen Sie andere Beispiele in der Dokumentation.
Knoten & Agenten
Eine Jenkins-Instanz könnte verschiedene Agenten auf verschiedenen Maschinen ausführen. Aus der Perspektive eines Angreifers bedeutet der Zugriff auf verschiedene Maschinen verschiedene potenzielle Cloud-Anmeldeinformationen, die gestohlen werden könnten, oder verschiedene Netzwerkzugriffe, die missbraucht werden könnten, um andere Maschinen zu kompromittieren.
Für weitere Informationen überprüfen Sie die grundlegenden Informationen:
pageBasic Jenkins InformationSie können die konfigurierten Knoten in /computer/
aufzählen, normalerweise finden Sie den Built-In Node
(der den Jenkins ausführenden Knoten darstellt) und möglicherweise weitere:
Es ist besonders interessant, den Built-In-Knoten zu kompromittieren, da er sensible Jenkins-Informationen enthält.
Um anzuzeigen, dass Sie die Pipeline im eingebauten Jenkins-Knoten ausführen möchten, können Sie die folgende Konfiguration innerhalb der Pipeline angeben:
Vollständiges Beispiel
Pipeline in einem spezifischen Agenten, mit einem Cron-Auslöser, mit Pipeline- und Stage-Umgebungsvariablen, die 2 Variablen in einem Schritt laden und eine Reverse-Shell senden:
Post-Exploitation
Metasploit
Jenkins Geheimnisse
Sie können die Geheimnisse auflisten, indem Sie auf /credentials/
zugreifen, wenn Sie über ausreichende Berechtigungen verfügen. Beachten Sie, dass dies nur die Geheimnisse in der Datei credentials.xml
auflistet, aber Build-Konfigurationsdateien können auch weitere Anmeldeinformationen enthalten.
Wenn Sie die Konfiguration jedes Projekts einsehen können, können Sie auch dort die Namen der Anmeldeinformationen (Geheimnisse) sehen, die zur Authentifizierung am Repository verwendet werden, sowie andere Anmeldeinformationen des Projekts.
Von Groovy
pageJenkins Dumping Secrets from GroovyVom Datenträger
Diese Dateien sind erforderlich, um Jenkins-Geheimnisse zu entschlüsseln:
secrets/master.key
secrets/hudson.util.Secret
Solche Geheimnisse sind normalerweise in zu finden:
credentials.xml
jobs/.../build.xml
jobs/.../config.xml
Hier ist ein Regex, um sie zu finden:
Entschlüsseln von Jenkins-Geheimnissen offline
Wenn Sie die benötigten Passwörter zum Entschlüsseln der Geheimnisse abgerufen haben, verwenden Sie dieses Skript zum Entschlüsseln dieser Geheimnisse.
Entschlüsseln von Jenkins-Geheimnissen aus Groovy
Neuen Admin-Benutzer erstellen
Greifen Sie auf die Jenkins-Konfigurationsdatei unter
/var/lib/jenkins/config.xml
oderC:\Program Files (x86)\Jenkins\
zu.Suchen Sie nach dem Wort
<useSecurity>true</useSecurity>
und ändern Sie das Worttrue
infalse
.sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
Starten Sie den Jenkins-Server neu:
service jenkins restart
Gehen Sie erneut zum Jenkins-Portal, und Jenkins wird dieses Mal keine Anmeldeinformationen anfordern. Navigieren Sie zu "Jenkins verwalten", um das Administratorpasswort erneut festzulegen.
Aktivieren Sie die Sicherheit erneut, indem Sie die Einstellungen auf
<useSecurity>true</useSecurity>
ändern, und starten Sie Jenkins erneut.
Referenzen
Last updated