XMLDecoder剖析流程剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

XMLDecoder剖析流程剖析

申博_新闻事件 申博 87次浏览 未收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

媒介

经过了Weblogic的几个XMLDecoder相干的CVE(CVE-2017-3506、CVE-2017-10352、CVE-2019-2725),好好看了一下XMLDecoder的剖析流程。

本文以jdk7版本的XMLDecoder举行剖析,jdk6的XMLDecoder流程都写在了一个类内里(com.sun.beans.ObjectHandler)

此处只剖析XMLDecoder的剖析流程,细致Weblogic的破绽请看别的几位师傅写的Paper。

WebLogic RCE(CVE-2019-2725)破绽之旅-Badcode

Weblogic CVE-2019-2725 剖析申报-廖新喜

不喜欢看代码的可以或许看官方关于XMLDecoder的文档:
Long Term Persistence of JavaBeans Components: XML Schema

XMLDecoder的几个症结类

XMLDecoder的团体剖析历程是基于Java自带的SAX XML剖析举行的。

以下一切类都在com.sun.beans.decoder包中

DocumentHandler

DocumentHandler继承自DefaultHandler,DefaultHandler是运用SAX举行XML剖析的默许Handler,以是Weblogic在对XML对象举行validate的时刻也运用了SAX,包管历程的一致性。

DefaultHandler完成了EntityResolver, DTDHandler, ContentHandler, ErrorHandler四个接口。

DocumentHandler重要改写了ContentHandler中的几个接口,究竟结果重若是针对内容举行剖析的,别的的保存默许就好。

ElementHandler及相干继承类

XMLDecoder对每种支撑的标签都完成了一个继承与ElementHandler的类,细致可以或许在DocumentHandler的组织函数中看到:

XMLDecoder剖析流程剖析

以是XMLDecoder只能运用如上标签。

个中继承干系与函数重写干系以下(很大,可以或许看大图或许本身用idea天生再看):

XMLDecoder剖析流程剖析

如上的继承干系也是object标签可以或许用void标签替换用的缘由,背面详说。

ValueObject及其相干继承类

ValueObject是一个包装类接口,包裹了现实剖析历程当中发生的对象(包罗null)

继承干系:

XMLDecoder剖析流程剖析

一样平常的对像由ValueObjectImpl举行包裹,而null\true\false(非boolean标签)则直接由本身Handler举行代表,完成相干接口。

XMLDecoder历程当中的几个症结函数

DocumentHandler的XML剖析相干函数的细致内容可以或许参考Java Sax的ContentHandler的文档。

ElementHandler相干函数可以或许参考ElementHandler的文档)。

DocumentHandler建立各个标签对应的ElementHandler并举行挪用。

startElement

处置惩罚最先标签,包罗属性的增添
DocumentHandler:。XML剖析处置惩罚历程当中参数包罗定名空间URL、标署名、完整标署名、属性列表。依据完整标署名建立对应的ElementHandler并增添相干属性,继承挪用其startElement。

ElementHandler: 除array标签之外,都无操纵。

endElement

完毕标签处置惩罚函数
DocumentHandler: 挪用对应ElementHandler的endElement函数,并将以后ElementHandler回溯到上一级的ElementHandler。

ElementHandler: 没看有重写的,都是挪用抽象类ElementHandler的endElement函数,推断是不是须要向parent写入参数和是不是须要注册标签对象ID。

characters

DocumentHandler: 标签包裹的文本内容处置惩罚函数,好比处置惩罚<string>java.lang.ProcessBuilder</string>包裹的文本内容就会从这个函数走。函数中终究挪用了对应ElementHandler的addCharacter函数。

addCharacter

ElementHandler: ElementHandler里的addCharacter只接收接种空缺字符(空格\n\t\r),其他的会抛非常,而StringElementHandler中则举行了重写,会纪录完整的字符串值。

addAttribute

ElementHandler: 增添属性,每种标签支撑的响应的属性,涌现其他属性会报错。

getContextBean

ElementHandler: 猎取操纵对象,好比method标签在实行要领时,要从猎取上级object/void/new标签Handler所建立的对象。该要领一样平常会触发上一级的getValueObject要领。

getValueObject

ElementHandler: 猎取以后标签所发生的对象对应的ValueObject实例。细致完成须要看每一个ElementHandler类。

isArgument

ElementHandler: 推断是不是为上一级标签Handler的参数。

addArgument

ElementHandler: 为以后级标签Handler增添参数。

XMLDecoder相干的别的

两个成员变量,在类的实例化之前,经由过程对parent的挪用举行增添参数。

parent

最外层标签的ElementHandler的parent为null,然后依次为上一级标签对应的ElementHandler。

owner

ElementHandler: 流动owner为所属DocumentHandler对象。

DocumentHandler: owner流动为所属XMLDecoder对象。

简易版剖析流程图

PPT画的:-D
由于空间题目,省略DocumentHandler的endElement->ElementHandler的endElement挪用。

XMLDecoder剖析流程剖析

随着破绽来波跟踪(Weblogic)

来一份简朴的代码:

public static void main(String[] args) throws FileNotFoundException {
    String filename = "1.xml";
    XMLDecoder XD =new XMLDecoder(new FileInputStream(filename));
    Object o = XD.readObject();
    System.out.println(o);
}

Level1:甚么过滤都没有

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

起首看下DocumentHandler的startElement:

混淆IDA F5的一个小技巧-x86

平级函数的修改 源码、编译 测试程序源码如下: vuln只是命名习惯了…并不是指漏洞函数 #include
#include
#include

int func(int a) {
int num = a;
printf(“%d”,a);
getchar();
getchar();
return 1;
}

int func_wrapper(int b) {
func(b+1);
int num = b;
printf(“%d”,num);
getchar();
getchar();
getchar();
return 2;
}

int vuln(int num){
printf(“%d”,num);
return 0xff;
}

int main(int argc, char** argv) {
func_wrapper(1);
vuln(2);
return 0;
}
程序没有什么特别的,注意getchar()因为没有参数,就是用来nop掉然后开始表演的,也不会影响堆栈平衡 编译:gcc -m32 main.c -o test 编译过后IDA打开,基本是这样 因为没有开优化,所以esp的加加减减没有被合并 patch 因为x64是fastcall,前几个参数用寄存器传参;而x86则全是用栈传参 原先vuln函数显示是这样的(这两个就是”平级函数”) 目的是让它显示成vuln(v3)这种形式,以达到一些干扰的效果 我们关注这段汇编 func_wrapper的参数是1,被push到栈中 而vuln函数调用之前先收回了原先参数1的栈,又

XMLDecoder剖析流程剖析

  1. 建立对应Handler,设置owner与parent
  2. 为Handler增添属性
  3. 挪用Handler的startElement

(背面DocumentHandler的局部疏忽,直接从ElementHandler最先)
下面从object标签对应的ObjectElementHandler最先看:
进入obejct标签,object标签带有class属性,进入:

XMLDecoder剖析流程剖析

可以或许看到推断的列内外没有class标签,会挪用父类(NewElementHandler)的addAttribute要领。

XMLDecoder剖析流程剖析

给type赋值为java.lang.ProcessBuilder对应的Class对象。

中心建立array参数的局部略过,有兴致的同砚可以或许本身跟一下。

进入void标签,设置好method参数,由于继承干系,看上面那张addAttribute图就好。

退出void标签,进入elementHandler的endElement函数:

XMLDecoder剖析流程剖析

由于继承干系,挪用NewElementHandler的getValueObject函数:

XMLDecoder剖析流程剖析

继承进入进入ObjectElementHandler的带参数getValueObject函数:

XMLDecoder剖析流程剖析

此处的getContextBean会挪用上一级也就是Object标签的getValueObject来猎取操纵对象。

略过中心步调,再次进入ObjectElementHandler的getValueObject要领:

终究经由过程Expression建立了对象:

XMLDecoder剖析流程剖析

(可以或许看出此处的Expression的首个参数是来自于上面getContextBean猎取的Class对象,先记着,背面会用)

再次回到Void标签对应的getValueObject函数:
终究经由过程Expression挪用了start函数:

XMLDecoder剖析流程剖析

若是对继承干系觉得对照蒙的话,可以或许看下一节的继承干系图。

PS: 虽然ObjectElementHandler继承自NewElementHandler,然则其重写了getValueObject函数,二者是运用分歧要领建立类的实例的。
再PS: 实在不加java标签也能用,然则没法包罗多个对象了。

Level2:只过滤了object标签

把上面的object标签替换为void便可。

VoidElementHandler的继承干系:

XMLDecoder剖析流程剖析

可以或许看到只改写了isArgument,而在全部触发历程当中并没有影响,以是此处运用void标签与object标签完整没有区分。

Level3:过滤一堆

过滤了object/new/method标签,void标签只允许用index,array的class只能用byte,并限定了长度。

CNVD-2018-2725(CVE-2019-2725)最后的poc运用了UnitOfWorkChangeSet这个类,这个类的组织要领以下(从Badcode师傅的Paper里盗的图):

XMLDecoder剖析流程剖析

最后的poc重要应用UnitOfWorkChangeSet类在组织函数中,会将输入的byte数组的内容举行反序列化,以是说刚最先说是反序列化破绽。

实在这个洞是应用了存在题目的类的组织函数,由于没法用挪用method了,就取了这类对照折衷的要领。(实在照样有局部要领可以或许挪用的:-D)。

在做这个试验时须要导入weblogic 10.3.6的modules目录下com.oracle.toplink_1.1.0.0_11-1-1-6-0.jar文件。

<java>
    <class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>
            <array class="byte" length="2">
                <void index="0">
                    <byte>-84</byte>
                </void>
                <void index="0">
                    <byte>-19</byte>
                </void>
            </array>
        </void>
    </class>
</java>

由于class标签继承了继承了string标签的addCharacter函数,致使其会将标签中包裹的空缺字符(空格\r\n\t)也加入到classname中,致使找class失利,以是最少要将\<class>到\<void>之间的空缺字符删除。

PS: 实在这里不加string标签也没题目。

Level1中说到:

Expression的首个参数是来自于上面getContextBean猎取的Class对象

也就是说,若是可以或许找到替换上面object/void+class属性的要领令getContextBean可以或许猎取到Class对象,也久可以或许挪用组织函数举行对象的建立。

我们来看下此处挪用的getContextBean的完成:

XMLDecoder剖析流程剖析

Level1/2中由于Object(Void)设置了class属性,那末type是有值的,以是直接返回type。

而父类的getContextBean是挪用parent的getValueObject函数,来猎取上一级对象,以是此时我们令上一级猎取到的对象为Class便可,以是此处运用了class标签令void的上一级猎取的对象为Class对象。

由于void标签只允许运用index属性,以是此处没法运用method属性来挪用细致函数,以是只能寄希冀于组织要领,就有了上面应用UnitOfWorkChangeSet类的组织要领来应用反序列化破绽的手段。

一样可应用的类另有之前jackson rce用的FileSystemXmlApplicationContext类。


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明XMLDecoder剖析流程剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址