CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

栏目: Java · 发布时间: 6年前

内容简介:CVE-2019-2725、CNVD-C-2019-48814WebLogic是美国Oracle公司出品的一个Application Server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。此漏洞存在于

漏洞编号

CVE-2019-2725、CNVD-C-2019-48814

漏洞简介

WebLogic是美国Oracle公司出品的一个Application Server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的 Java 应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。

此漏洞存在于 wls-wsat.warbea_wls9_async_response.war 中的多个路由中。攻击者可利用该漏洞在未授权的情况下远程执行命令。

漏洞影响

  • Oracle WebLogic Server10.3.6.0.0
  • Oracle WebLogic Server12.1.3.0.0

环境搭建

  • Windows Server 2012
  • JDK 1.7.0_21
  • Oracle WebLogic Server10.3.6.0.0

前置知识

在漏洞分析之前,我想先说两个和这个漏洞有关的前置知识:SOAP和Context Propagation

SOAP

SOAP全称Simple Object Access Protocol(简单对象访问协议),是一种XML协议,且通常基于HTTP。用于应用之间的通信和数据交换。

SOAP的消息是一个XML文档,它包含以下元素:

  • 将XML文档标识为SOAP消息的Envelope元素,用于封装SOAP中的所有详细信息。
<soapenv:Envelope>
    <!-- omit... -->
</soapenv:Envelope>
  • 包含头信息的Header元素,头信息可以包含被调用应用需要使用的身份验证凭据,也可以包含SOAP消息中需要使用的复杂类型的定义。
<soapenv:Header>
    <!-- omit... -->
<soapenv:Header>
  • 包含调用和响应信息的Body元素,其中含有需要在Web服务和调用应用程序之间发送的实际数据
<soap:Body>
   <GetSomeInfo>
        <SomeInfoId>omit...</SomeInfoId> 
   </GetSomeInfo>
</soap:Body>

这些元素的结构如下图所示:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析 我们把这些元素合在一起,得到下面的例子:
<soapenv:Envelope>
    <soapenv:Header>
        <!-- omit... -->
    <soapenv:Header>
    <soap:Body>
       <GetSomeInfo>
            <SomeInfoId>omit...</SomeInfoId> 
       </GetSomeInfo>
    </soap:Body>
</soapenv:Envelope>

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

更多有关信息可参考 SOAP Web Services Tutorial

Context Propagation

Context propagation,我在这里翻译成上下文传递,它允许开发者将信息与应用程序相关联,在每一个请求中携带上下文信息。上下文传递的常见用例是将信息 从外界传递到应用程序来取代信息整合到应用程序的一部分 ,它的优势是保持应用程序本身干净,无需多余的API。上下文传递也通常被称作Work Areas、Work Contexts、和Application Transactions。

上下文传递经常用于应用程序的诊断和监控、应用程序的事务处理和负载均衡等。

可以使用如下例子创建上下文传递的应用:

服务端:

package examples.workarea;
// omit...
import weblogic.workarea.WorkContextMap;
import weblogic.workarea.WorkContext;
// omit...
@WebService(name="WorkAreaPortType", 
            serviceName="WorkAreaService",
             targetNamespace="http://example.org")
 @WLHttpTransport(contextPath="workarea", 
                 serviceUri="WorkAreaService",
                  portName="WorkAreaPort")
public class WorkAreaImpl {
    public final static String SESSION_ID = "session_id_key";
   @WebMethod()
    public String sayHello(String message) {
    try {
         WorkContextMap map = (WorkContextMap) new InitialContext().lookup("java:comp/WorkContextMap");
         WorkContext localwc = map.get(SESSION_ID);
         System.out.println("local context: " + localwc);
        System.out.println("sayHello: " + message);
         return "Here is the message: '" + message + "'";
        } catch (Throwable t) {
         return "error";
        }
    }
}

客户端:

package examples.workarea.client;
// omit...
import weblogic.workarea.WorkContextMap;
import weblogic.workarea.WorkContext;
import weblogic.workarea.PrimitiveContextFactory;
import weblogic.workarea.PropagationMode;
import weblogic.workarea.PropertyReadOnlyException;
// omit...
public class Main {
   public final static String SESSION_ID= "session_id_key";
   public static void main(String[] args)
    throws ServiceException, RemoteException, NamingException, PropertyReadOnlyException{
      WorkAreaService service = new WorkAreaService_Impl(args[0] + "?WSDL");
      WorkAreaPortType port = service.getWorkAreaPort();
      WorkContextMap map = (WorkContextMap)new InitialContext().lookup("java:comp/WorkContextMap");
      WorkContext stringContext = PrimitiveContextFactory.create("A String Context");
      // Put a string context
      map.put(SESSION_ID, stringContext, PropagationMode.SOAP);
      try {
        String result = null;
        result = port.sayHello("Hi there!");
        System.out.println( "Got result: " + result );
      } catch (RemoteException e) {
        throw e;
      }
  }
}

更多有关信息可参考 Developing Applications With WebLogic Server

漏洞分析

有了上面的前置知识,我们来详细分析Payload传入Weblogic中到底发生了什么。此次漏洞分析我使用了Java反编译工具JD-GUI配合IDEA远程调试。

以路由 /wls-wsat/CoordinatorPortType 为例,我们就从这个路由的定义入手。

反编译 wls-wsat.war 包,查看其中的 WEB-INF/web.xml 文件,可发现 /CoordinatorPortType 路由的定义位置:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

可以看到其对应的 servlet-classweblogic.wsee.wstx.wsat.v10.endpoint.CoordinatorPortTypePortImpl 。跟入其中,发现此接口是SOAP的实现。

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

其实现的接口如下图:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

这样我们确认了 /wls-wsat/CoordinatorPortType 是SOAP Web Service

然后使用IDEA运行远程调试,将断点放在 WLSServletAdapter.class 128行, handle() 方法,执行Payload:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

可发现请求已经到达其 HttpServletResponse 参数中。

方法调用了它的父类的 handle() 方法,父类的 handle() 方法又继续调用父类 handle() 方法,调用堆栈如下:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

来到 HttpAdapter.class 152行的 handle() 方法,

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

这里主要代码为从队列中取出了一个对象并将其强制转换成 HttpAdapter.HttpToolkit

跟入队列的 take() 方法,因为队列为空,调用了 this.create()

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

Adapter.class 中可看到 create() 函数调用了 Adapter.this.createToolkit()

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

最终在 Toolkit 类中创建了 codechead

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

我们来看下 codechead 分别是什么:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

这里留意 codechead 中的 tube ,稍后会用到。

然后回到 HttpAdapter.class ,调用 tk.handle(connection) ,随后使用刚才的 codec 解码器解码数据包,其调用了 xmlSoapCodec.decode() 方法:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

然后在 StreamSOAPCodec.class 中解码SOAP XML:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

解析的流程忽略不说,再次回到 HttpAdapter.class 的535行:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

此处用到了刚才的 head ,调用其 process() 方法。

根据上面的分析,我们知道了 this.headWSEndpointImpl.class 的对象,其中包含一个成员变量 tubetubeWseeServerTube ,在 WSEndpointImpl.class 的299行创建了一个纤程,然后在303行调用纤程的 runSync() 方法,将 this.tube 传入。纤程中的 runSync() 这样做是为了以同步的方式实现纤程间的异步调用。参数 this.tube 定义了在纤程中要执行的操作,在这里即 WseeServerTube

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

我们跳过一些与纤程相关的操作,来到 WorkContextTube 的子类 WorkContextServerTube.class ,这个类可以看出是用来处理上下文传递(Context Propagation)信息的,来到43行的 readHeaderOld ,顾名思义,是用来读取SOAP中的Header的。

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析 跟入方法,发现此时 var4 正是真正要执行的Payload:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

到112行new了一个 WorkContextXmlInputAdapter 类的对象,补丁就在这个类中。113行调用 this.receive() ,继续跟入:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

WorkContextLocalMap.class 中165行, receiveRequest() 方法,将输入的上下文作为参数调用了 WorkContextEntryImpl.readEntry() 方法, readEntry() 方法又调用 WorkContextXmlInputAdapter.classreadUTF()readUTF() 调用了 this.xmlDecoder.readObject() ,完成了第一次反序列化。

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析 CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

反序列化后反射出Payload中的类的实例,具体反射过程不再跟踪,可以关注 Statement.class 中的 invokeInternal() 。反射后,调用其中的 readObject() ,完成第二次反序列化,触发命令执行:

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

调用过程

此漏洞经历了两次反序列化,整个调用堆栈非常长。类似漏洞的调用堆栈网上已经有很多,可参考 Weblogic XMLDecoder RCE分析

在这里我觉得画一个简单的流程图去描述其调用过程会更清晰一些。

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

补丁分析

刚刚在漏洞分析中已经提到了补丁所在位置(WorkContextXmlInputAdapter.class),这个漏洞根本上也是补丁的绕过。我们用刚刚发布的4月份CPU和针对这个漏洞的新的补丁包作对比,发现只多了一个判断分支(左边为4月份CPU中已存在的补丁,右边为新的补丁):

CVE-2019-2725 Weblogic多个组件反序列化远程代码执行漏洞分析

从漏洞上看,在调用 WorkContextXmlInputAdapter 类构造方法时,调用 validate() 方法来校验XML中的每一个标签名。如果包含可能被恶意利用的标签名则抛出错误。是黑名单修补的方式。

修复建议

  • Oracle官方已推出安全更新,请参考以下官方安全通告下载并安装最新补丁:

https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html

  • 如果明确不使用wls-wsat.war和bea_wls9_async_response.war,建议删除并重启WebLogic。
  • 通过访问策略控制禁止 /_async/*/wls-wsat/* 路径的URL访问。

参考

  • http://www.cnvd.org.cn/webinfo/show/4989
  • https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html
  • https://www.guru99.com/soap-simple-object-access-protocol.html
  • https://docs.oracle.com/cd/E13222_01/wls/docs100/programming/context.html#wp1058673

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Information

The Information

James Gleick / Vintage / 2012-3-6 / USD 16.95

James Gleick, the author of the best sellers Chaos and Genius, now brings us a work just as astonishing and masterly: a revelatory chronicle and meditation that shows how information has become th......一起来看看 《The Information》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具