今年早些时候,作者在博客中公开了一个Oracle WebLogic Server中的反序列化漏洞。此漏洞是由Oracle补丁的,并分配了CVE-2020-2555。但是,VNPT ISC的研究员Quynh Le向ZDI提交了一个漏洞,该漏洞表明了可以绕过补丁利用此漏洞。Oracle 已通报此标记为CVE-2020-2883的漏洞可用于攻击。在此博客文章中,我们将详细介绍此最新补丁中的漏洞。

 https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-serverhttps://www.us-cert.gov/ncas/current-activity/2020/05/01/unpatched-oracle-weblogic-servers-vulnerable-cve-2020-2883https://www.zerodayinitiative.com/advisories/ZDI-20-570/

0x01  补丁绕过

CVE-2020-2555的原始补丁程序未修补以下gdaget利用链的部分:

 BadAttributeValueExpException.readObject()com.tangosol.util.filter.LimitFilter.toString() // <--- CVE-2020-2555在此处补丁com.tangosol.util.extractor.ChainedExtractor.extract()com.tangosol.util.extractor.ReflectionExtractor().extract()Method.invoke()//...com.tangosol.util.extractor.ReflectionExtractor().extract()Method.invoke()Runtime.exec()

调用ChainedExtractor.extract()仍将导致远程执行代码,Quynh Le的报告显示,ChainedExtractor.extract()仍然可以通过ExtractorComparator和AbstractExtractor类进行访问。我们从查看compare()方法ExtractorComparator:开始分析

 public int compare(T o1, T o2) {Comparable a1 = (o1 instanceof InvocableMap.Entry) ? (Comparable)((InvocableMap.Entry)o1).extract(this.m_extractor) : (Comparable)this.m_extractor.extract(o1);Comparable a2 = (o2 instanceof InvocableMap.Entry) ? (Comparable)((InvocableMap.Entry)o2).extract(this.m_extractor): (Comparable)this.m_extractor.extract(o2);if (a1 == null){return (a2 == null) ? 0 : -1;}if (a2 == null){return 1;}return a1.compareTo(a2);}

如上所示,仍然可以通过设置ChainedExtractor.extract()为this.m_extractor的实例来调用ChainedExtractor。

同样,compare()也可以使用AbstractExtractor抽象类的方法。

 public  int compare(Object o1,Object o2){ return  SafeComparator 。compareSafe(null,extract(o1),extract(o2)); }

MultiExtractor类扩展AbstractExtractor可以到达ChainedExtractor.extract():

 public abstract class AbstractCompositeExtractor   extends AbstractExtractor   [...Truncated...]public class MultiExtractorextends AbstractCompositeExtractor[...Truncated...]public Object extract(Object oTarget) {if (oTarget == null){return null;}ValueExtractor[] aExtractor = getExtractors();int cExtractors = aExtractor.length;Object[] aValue = new Object[cExtractors];for (int i = 0; i < cExtractors; i++){aValue[i] = aExtractor[i].extract(oTarget);<-----------------------}return new ImmutableArrayList(aValue);}

0x02  完整利用链

为了开发一个完整的gadget利用链,我们需要有调用compare()的能力,从方法Comparator到达readObject()。使用的公开记录的方法有PriorityQueue,有如下gadget类:BeanShell1,Jython1,CommonsCollections2,CommonsBeanutils1,CommonsCollections4和Groovy1:

 java.util 。PriorityQueue 。readObject()java.util 。PriorityQueue 。heapify()java.util 。PriorityQueue 。siftDown()java.util 。PriorityQueue 。siftDownUsingComparator()

SiftUpUsingComparator()可以调用compare()任意方法Comparator:

 private void siftUpUsingComparator(int paramInt, E paramE) {while (paramInt > 0) {int i = paramInt - 1 >>> 1;Object object = this.queue[i];if (this.comparator.compare(paramE, object) >= 0)<----------------break; this.queue[paramInt] = object;paramInt = i;} this.queue[paramInt] = paramE;}

还有其他实现此目的的方法。例如,使用以下方法:

 javax.management 。BadAttributeValueExpException 。readObject()  com.tangosol.internal.sleepycat.persist.evolve 。变异。toString()java.util.concurrent 。ConcurrentSkipListMap $ SubMap 。尺寸()java.util.concurrent 。ConcurrentSkipListMap $ SubMap 。isBeforeEnd()java.util.concurrent 。ConcurrentSkipListMap 。cpr()

总而言之,toString()Mutations类的方法可能导致调用ConcurrentSkipListMap.size():

 ConcurrentSkipListMap$SubMap.classpublic int size() {Comparator cmp = m.comparator;long count = 0;for (ConcurrentSkipListMap.Node n = loNode(cmp);isBeforeEnd(n, cmp); = Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;}[...Truncated...]boolean isBeforeEnd(ConcurrentSkipListMap.Node n, Comparator cmp) {....int c = cpr(cmp, k, hi); 0 || (c == 0 && !hiInclusive))return false;return true;} [...Truncated...]static final int cpr(Comparator c, Object x, Object y) {return (c != null) ? c.compare(x, y) : ((Comparable)x).compareTo(y); <--------}

从ConcurrentSkipListMap.size()中可以调用compare()任意方法Comparator。

0x03  演示漏洞利用

通过使用上述方法,针对ExtractorComparator编译了以下完整的gadget链:

 javax.management.BadAttributeValueExpException.readObject()  com.tangosol.internal.sleepycat.persist.evolve.Mutations.toString()java.util.concurrent.ConcurrentSkipListMap$SubMap.size()java.util.concurrent.ConcurrentSkipListMap$SubMap.isBeforeEnd()java.util.concurrent.ConcurrentSkipListMap.cpr()com.tangosol.util.comparator.ExtractorComparator.compare()

以下视频演示了此gadget链用于通过T3协议获得RCE。

 https://www.youtube.com/watch?v=HM3Z-I998b4

对于该AbstractExtractor示例,使用了以下链:

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

以下视频演示了此gadget链用于通过T3协议获得RCE:

 https://youtu.be/juIucTRZUL8

0x04  通过HTTP利用漏洞

应当注意,此漏洞位于Coherence 库中。 在其代码路径中具有反序列化路径的任何具有Coherence 库的应用程序也容易受到攻击。一个产品示例是Oracle Business Intelligence,它部署在Oracle WebLogic上。

可以将这些gadget链与CVE-2020-2950 / ZDI-20-505结合使用,该工具由GreenDog的研究人员报告给ZDI,以通过HTTP实现远程代码执行。

此漏洞位于BIRemotingServlet中,会侦听TCP端口7780,并且不需要任何身份验证:

      BIRemotingServlet     oracle.bi.nanserver.fwk.servlet.as.BIRemotingServlet     1        BIRemotingServelet     /messagebroker/as/*        BIRemotingServlet     /messagebroker/cs/*

BIRemotingServlet 使用AMF(操作消息格式)与客户端进行通信。

 protected void handleRequest(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse) throws ServletException, IOException {[...Truncated...]RemotingSvs remotingSvs = BISvsManagerBase.getRemotingSvs(); <----------------------------------------------------remotingSvs.processCall(); <--------------------------------------------------------------------------------------------setContentType(paramHttpServletResponse, OutputForm.AMF3);paramHttpServletResponse.setContentLength(byteArrayOutputStream.size());byteArrayOutputStream.writeTo(paramHttpServletResponse.getOutputStream());paramHttpServletResponse.flushBuffer();}public int processCall() throws BISvsException {[...Truncated...]AMF3Packet aMF3Packet1 = deserializePacket(dataInputStream); <------------------------------------------------------------if (logger.isLoggable(Level.FINE)) {logger.fine("De-serialized request packet: " + aMF3Packet1.toString());}[...Truncated...]}oracle.bi.nanserver.fwk.util.remoting.RemotingSvsImpl.classpublic AMF3Packet deserializePacket(DataInputStream paramDataInputStream) throws BISvsException {try {AMFObjectInput aMFObjectInput = getAMF3DeSerializer(paramDataInputStream); <------------------------------------------------LegacyObjectInput legacyObjectInput = new LegacyObjectInput(paramDataInputStream, aMFObjectInput);AMF3Packet aMF3Packet = new AMF3Packet();aMF3Packet.deserialize(legacyObjectInput); <----------------------------------------------------------------------------------return aMF3Packet;}catch (Exception exception) {handleException(exception);return null;} }public AMFObjectInput getAMF3DeSerializer(DataInputStream paramDataInputStream) throws BISvsException {try {Class clazz = (Class)amf3DeSerializerClass.get();if (clazz == null) {String str = (String)BISvsManagerBase.getContextSvs().getValue("amf3DeSerializer");if (str == null || str.trim().length() == 0) {clazz = oracle.bi.nanserver.fwk.util.amf.AMF3ObjectInput.class; <--------------------------------------------------------amf3DeSerializerClass.compareAndSet(null, clazz);logger.info("Using default AMF3 De-Serializer");[...Truncated...]}

如图所示,当对AMF数据包进行反序列化时,可以通过调用AMF3ObjectInput来重建任意对象readComplexObject()。

 protected Object readComplexObject(GenericTypeInfo paramGenericTypeInfo) throws ClassNotFoundException, IOException {try {int i = readAMF3IntegerVal();if ((i & true) == 0) {return getVisitedObject(i >> 1);}ClassMetadata classMetadata = readClassMetadata(i);String str = this.proxySvs.getConcreteClassName(classMetadata.name);if (str == null) {str = classMetadata.name;}//  CVE-2020-2950 patch//if (isBlacklisted(str))//{//  throw new SecurityException("Unsupport class type:" + str);//}Class clazz = Class.forName(str);ClassProxy classProxy = this.proxySvs.getProxy(clazz);Object object1 = classProxy.newInstance(clazz);int j = this.objectRefList.size();markObjectVisited(object1);if (classMetadata.externalizable) {if (paramGenericTypeInfo != null) {classProxy.readExternal(new GenericResult(object1, paramGenericTypeInfo), this);} else {classProxy.readExternal(object1, this);}}else if (clazz == oracle.bi.nanserver.fwk.util.remoting.messages.RemotingMessage.class) {populateRemotingMessage(object1, classMetadata, classProxy);} else {String[] arrayOfString = classMetadata.getFieldNames();Object[] arrayOfObject = new Object[arrayOfString.length];for (byte b = 0; b < arrayOfString.length; b++) {arrayOfObject[b] = readObject();}this.proxySvs.setFieldValues(object1, arrayOfString, arrayOfObject, classProxy);if (classMetadata.dynamic) {while (true) {String str1 = readAMF3String();if (str1 == null || str1.length() == 0) {break;}Object object = readObject();this.proxySvs.setFieldValue(object1, str1, object, classProxy);} }}

在此示例中,UnicastRef重构了一个对象,从而导致对远程对象的服务器端分布式垃圾回收器的调用,从而使我们能够响应任意的序列化对象。如上所述响应gadget链之一会产生RCE。

有关在Java AMF实现中利用Java反序列化的更多详细信息,请参阅Code White的这篇文章。gadget链已添加到ysoserial中,并且使用JRMP侦听器来利用此漏洞。

 https://codewhitesec.blogspot.com/2017/04/amf.htmlhttps://github.com/frohoff/ysoserial

以下视频演示了这一操作:

 https://www.youtube.com/embed/h1c0sfVZNO8

0x05  分析总结

有关Java反序列化漏洞的更多详细信息,请参阅Moritz Bechler的白皮书。Oracle的博客没有说明攻击的广泛性,但是其指导很明确:需要立即打补丁。他们还提供有关如何限制Oracle WebLogic Server的T3 / T3S协议流量的指南。Oracle补丁程序的下一个版本计划于2020年7月14日发布,我们将持续关注在该更新之后还剩下多少反序列化漏洞。

 https://github.com/mbechler/marshalsec/blob/master/marshalsec.pdfhttps://blogs.oracle.com/security/apply-april-2020-cpu

Oracle WebLogic 最新补丁的绕过漏洞分析 cve-2020-2883相关推荐

  1. 身份验证绕过漏洞分析

    0x01 前言 最近Tenable 披露了Arcadyna 网络设备身份验证绕过漏洞,并且很多的厂商都采用产生漏洞的组件,由于Arcadyan 设备固件厂商并没有开源出来,在官网支持里面下载的文件是w ...

  2. war包启动命令_【漏洞预警】Oracle WebLogic远程命令执行0day漏洞(CVE20192725补丁绕过)...

    概述 近日,奇安信天眼与安服团队通过数据监控发现,野外出现Oracle WebLogic远程命令执行漏洞最新利用代码,此攻击利用绕过了厂商今年4月底所发布的最新安全补丁(CVE-2019-2725). ...

  3. oracle11g远程命令执行漏洞,漏洞应急|Oracle Weblogic Server远程代码执行漏洞(CVE-2021-2109)...

    近日,锐捷网络CERT安全应急响应团队关注到Oracle官方发布了2021年1月关键补丁更新公告,该补丁中修补了包括 CVE-2021-2109 Weblogic Server远程代码执行漏洞在内的多 ...

  4. 【CVE-2020-1957】shiro搭配spring时身份验证绕过漏洞分析

    0x00 漏洞简介 https://www.openwall.com/lists/oss-security/2020/03/23/2 0x01 漏洞分析 翻查官方commit,在commit http ...

  5. Shiro 权限绕过漏洞分析(CVE-2020-1957)

    1## 前言 2020年3月23号,Shiro开发者Brian Demers在用户社区发表帖子,提醒shiro用户进行安全更新,本次更新进行了三个修复,其中就包括了对编号为CVE-2020-1957的 ...

  6. Shiro权限绕过漏洞分析(CVE-2020-1957)

    这篇是实战:https://xz.aliyun.com/t/10328,不过中间的以下条件的"2.要以路径通配符**结尾"是错的,这个不是条件,只要让路径规范化处理完后匹配上ano ...

  7. 【认证绕过】NACOS身份认证绕过漏洞分析

    前言 工作中遇到一个nacos服务认证绕过的问题,在此总结一下漏洞原因. 一.nacos简介 官方文档描述: Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮 ...

  8. oracle官方最新补丁,最新oracle 补丁下载

    最新oracle 补丁下载 使用迅雷新建任务下载地址填写 ftp://updates.oracle.com//p__.zip 就可以下载到你想要的补丁了. 以下是几个常用补丁的下载地址. (10.2. ...

  9. Weblogic12c T3 协议安全漏洞分析【CVE-2020-14645 CVE-2020-2883 CVE-2020-14645】

    给个关注?宝儿! 给个关注?宝儿! 给个关注?宝儿! 关注公众号:b1gpig信息安全,文章推送不错过 ## 前言 WebLogic是美国Oracle公司出品的一个application server ...

最新文章

  1. Keil uVision5 下载程序 add flash programming algorithm选项缺少需要的下载算法的解决办法
  2. 《从零开始学Swift》学习笔记(Day 6)——哎呀常量和变量都该什么时候用啊?...
  3. 反射_Class对象功能_获取Field
  4. 实现一个无法被继承的C++类
  5. iOS block 用法
  6. svn在linux下的使用(svn命令)[转]
  7. 使用八爪鱼工具爬取京东当前所有手机信息存入mysql
  8. java 最大流最小割_最大流, 最小割问题及算法实现
  9. linux把m4s格式转换mp4,批量将哔哩哔哩缓存M4S格式视频改成MP4格式
  10. textaligncenter仍然不居中_你不知道的中华文化,中华文化的根源不是儒家而是河图洛书...
  11. 小黄鸡 php,Simsimi (小黄鸡) API接口(PHP)公布,小黄鸡API接口非官方PHP版本来啦...
  12. Java面试官:java的跨平台原理
  13. 在IE中打开或下载文件
  14. 公司流程 企业所得税 个人所得税
  15. C/C++编程日记:C++ 实现太阳系行星项目系统
  16. 海康威视接口调用报错处理
  17. 通过WIFI双向透传串口向Arduino Uno 无线上传(更新)程序
  18. 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
  19. 使用交叉编译工具链编译并调试linux内核
  20. Magento时代的全球开源网店系统格局(一)

热门文章

  1. 论字符界面和WEB界面配置的优缺点
  2. DataBinder
  3. NFV — Overview
  4. 高频变压器的磁饱和及变压器最大电流测量
  5. SSM整合Shiro 身份验证及密码加密简单实现
  6. [LAMP]Apache和PHP的结合
  7. 广东省“安网2016”网络安全专项治理行动正式启动
  8. Web常见约定规范(精选)
  9. ASI和AFN的区别
  10. SQLServer存储过程