本文首发于“合天智汇”公众号 作者:Fortheone

前言

最近学习java反序列化学到了weblogic部分,weblogic之前的两个反序列化漏洞不涉及T3协议之类的,只是涉及到了XMLDecoder反序列化导致漏洞,但是网上大部分的文章都只讲到了触发XMLDecoder部分就结束了,并没有讲为什么XMLDecoder会触发反序列化导致命令执行。于是带着好奇的我就跟着调了一下XMLDecoder的反序列化过程。

xml序列化

首先了解一下java中的XMLDecoder是什么。XMLDecoder就是jdk中一个用于处理xml数据的类,先看两个例子。

这里引用一下浅蓝表哥的(强推浅蓝表哥的博客https://b1ue.cn/

import java.beans.XMLEncoder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; /**
* @author 浅蓝
* @email blue@ixsec.org
* @since 2019/4/24 12:09
*/
public class Test { public static void main(String[] args) throws IOException, InterruptedException { HashMap<Object, Object> map = new HashMap<>();
map.put("123","aaaa");
map.put("321",new ArrayList<>()); XMLEncoder xmlEncoder = new XMLEncoder(System.out);
xmlEncoder.writeObject(map);
xmlEncoder.close(); }
}

这样就把map对象变成了xml数据,再使用XMLDecoder解析一下。

/**
* @author 浅蓝
* @email blue@ixsec.org
* @since 2019/4/24 12:09
*/
public class Test { public static void main(String[] args) throws IOException, InterruptedException {
String s = "<java version=\"1.8.0_131\" class=\"java.beans.XMLDecoder\">\n" +
" <object class=\"java.util.HashMap\">\n" +
" <void method=\"put\">\n" +
" <string>123</string>\n" +
" <string>aaaa</string>\n" +
" </void>\n" +
" <void method=\"put\">\n" +
" <string>321</string>\n" +
" <object class=\"java.util.ArrayList\"/>\n" +
" </void>\n" +
" </object>\n" +
"</java>";
StringBufferInputStream stringBufferInputStream = new StringBufferInputStream(s);
XMLDecoder xmlDecoder = new XMLDecoder(stringBufferInputStream);
Object o = xmlDecoder.readObject();
System.out.println(o); }
}

就可以把之前的xml数据反序列化回map对象,那么如果对xml数据进行修改,使其变成一个执行命令的数据。比如说:

<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>

然后对其反序列化即可执行命令弹出计算器。

现在我们知道了如果使用XMLDecoder去反序列化xml数据,数据中包含的命令会被执行。接下来就对其进行分析一下。

XMLDecoder反序列化漏洞成因

一、XML数据解析前的函数处理

在readObject处打上断点开始debug

进入了parsingComplete方法,跟进。

其中使用XMLDecoder的handler属性DocumentHandler的parse方法,并且传入了我们输入的xml数据,跟进。

这里调用了SAXParserImpl类的parse方法。

然后又进了xmlReader的parse方法。

这里又调用了xmlReader父类AbstractSAXParser的parser方法。

最后进入了XML11Configuration类的parse方法。

二、XML数据的处理

在XML11Configuration中进行了很多解析XML之前的操作,我们不去仔细研究,看到处理XML数据的函数scanDocument。跟进查看

这个函数通过迭代的方式对XML数据的标签进行解析,网上有些文章写道“解析至END_ELEMENT时跟进调试”,但是我看了一下我这里的END_ELEMENT。

里面没有函数可以跟进啊,然后搜了一些其他的文章,是因为jdk版本的问题,处理的逻辑放在了next函数里。在do while循环里跳了大概十次,就开始解析了xml的标签。

跳到XMLDocumentScannerImpl中的next方法

跳到XMLDocumentFragmentScannerImpl中的next方法,解析到endtag时会走到scanEndElement方法里。

然后就到了网上说的endElement方法里,跟进。

这一部分的解析可以参考下图:

也就是说解析时会按照标签一个一个解析。

这里调用了DocumentHandler的endElement方法。接下来就是很重要的部分

这里的handler是StringElementHandler,但是这个类没有重写endElement方法,所以调用的是父类ElementHandler的endElement方法,其中调用了getValueObject来获取标签中的value值,这里的标签是string标签,所以获取到的值是calc。

然后将其添加到其父类标签VoidElementHandler的Argument属性中。

然后将handler指向其父类VoidElementHandler。

继续解析到void标签,此时的handler就是VoidElementHandler,接着调用getValueObject。但是因为没有重写该方法,所以调用父类NewElementHandler的getValueObject。

继续跟进发现实现了反射调用invoke方法,也就是执行了set方法。接着再解析Array标签,按照上面的步骤解析,就完成了这一部分参数的解析。

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

那么再按照上面的步骤解析object标签,然后调用new 方法实例化 ProcessBuilder类。

然后解析到void标签获取到start方法,然后通过调用start方法实现了命令执行,弹出计算器。

也就相当于最后拼接了 new java.lang.ProcessBuilder(new String[]{"calc"}).start();

文章有说的不对的地方请师傅们指点,刚开始学java,大佬们轻喷。。。

参考文章

https://b1ue.cn/archives/239.html

https://zhuanlan.zhihu.com/p/108754274

https://blog.csdn.net/SKI_12/article/details/85058040

相关实验

Java反序列漏洞

https://sourl.cn/23ajig

(本实验通过Apache Commons Collections 3为例,分析并复现JAVA反序列化漏洞。)

java反序列化——XMLDecoder反序列化漏洞的更多相关文章

  1. WebLogic XMLDecoder反序列化漏洞复现

    WebLogic XMLDecoder反序列化漏洞复现 参考链接: https://bbs.ichunqiu.com/thread-31171-1-1.html git clone https://g ...

  2. weblogic系列漏洞整理 -- 4. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271、CVE-2017-3506)

    目录 四. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271) 0. 漏洞分析 1. 利用过程 2. 修复建议 一.weblogic安装 http://www.cnb ...

  3. WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)复现

    WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)                                                -----by  ba ...

  4. Weblogic 'wls-wsat' XMLDecoder 反序列化_CVE-2017-10271漏洞复现

    Weblogic 'wls-wsat' XMLDecoder 反序列化_CVE-2017-10271漏洞复现 一.漏洞概述  WebLogic的 WLS Security组件对外提供webservic ...

  5. jdk紧急漏洞,XMLDecoder反序列化攻击

    昨天在公司发现了一个jdk中的XMLDecoder反序列化的漏洞,看起来很危险!下面通过两个示例来看看这个漏洞的危害! 示例1:利用XmlDecoder删除本地文件 首先来看这个xmldecoder. ...

  6. ref:Java安全之反序列化漏洞分析(简单-朴实)

    ref:https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247484200&idx=1&sn=8f3201f44e ...

  7. JBOSSAS 5.x/6.x 反序列化命令执行漏洞(CVE-2017-12149)

    本文主要记录一下JBOSSAS 5.x/6.x 反序列化命令执行漏洞的测试过程 仅供学习 文中利用到漏洞环境由phith0n维护: JBoss 5.x/6.x 反序列化漏洞(CVE-2017-1214 ...

  8. JAVA序列化和反序列化XML

    package com.lss.utils; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.Bu ...

  9. weblogic 反序列化补丁绕过漏洞的一个批量检测shell脚本(CVE-2017-3248 )

    ~ 以下内容,仅供学习参考 ~ weblogic 反序列化补丁绕过漏洞已经出了两个月了,balabala ~~~ 废话不说,拿到该漏洞的利用工具weblogic.jar,但只能一个个检测ip和端口,效 ...

随机推荐

  1. findViewByid一定要放在setContentView(R.layout.a..)之后

    findViewByid一定要放在setContentView(R.layout.a..)之后否则还没布局,根本找不到这些控件setContentView(R.layout.activity_inpu ...

  2. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概览

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的基本特性. 恩智浦半导体于2017年开始推出的i.MX RT系列重新定义了MCU,其第一款芯片i. ...

  3. Linux图形界面与命令行界面以及用户之间的转换

    刚刚不小心进入了命令行界面,,,,,, ALT SHIFE F5 咋回去的呢 sudo startx 但是回去以后默认是root ,,,,,, 所以切换用户 su username//用户名 就可以切 ...

  4. Laravel 配置 SqlDebug 服务,进行实时监听打印 SQL

    0:释义 什么是服务容器 简而言之,Laravel 服务容器 是一个用于存储绑定组件的盒子,它还会为应用提供所需的服务. Laravel 服务容器是用于管理类的依赖和执行依赖注入的工具,By Lara ...

  5. spring 循环依赖的一次 理解

    前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...

  6. Sqlite3 实现学生信息增删改查

    import sqlite3 conn = sqlite3.connect('studentsdb.db') # 连接数据库 cursor = conn.cursor( ) # 创建数据表 def c ...

  7. FGPA_Microblaze UART 中断

    由于底层所给函数发送与接收都采用中断,所用库函数比较复杂 ,有些更改涉及底层函数,因此结合网上论坛 .百度文库调试了串口中断接收程序.通过串口调试助手发送数据 ,以“发送新行”结束 . 硬件外设波特兰 ...

  8. PHP get_resource_type() 函数

    get_resource_type() 返回资源(resource)类型. 版本要求:PHP 4 >= 4.0.2, PHP 5, PHP 7高佣联盟 www.cgewang.com 语法 st ...

  9. PHP开发者该知道的多进程消费队列

    引言 最近开发一个小功能,用到了队列mcq,启动一个进程消费队列数据,后边发现一个进程处理不过来了,又加了一个进程,过了段时间又处理不过来了… 这种方式每次都要修改crontab,如果进程挂掉了,不会 ...

  10. 笨办法学python3代码练习ex23.py 字符串字节串字符编码

    首先简单说一下字符编码的问题.平常遇到比较多的就是ASCII码(全称:美国信息交换标准码).ASCII码使用一个字节(8位)来表示一些常见的数字.英文字母以及一些控制字符.英语用128个符号编码就够了 ...