经过一段时间的琢磨与反思,以及重读了大量之前看不懂的反序列化文章,目前为止算是对java反序列化这块有了一个阶段性的小理解。

目前为止,发送的所有java反序列化的漏洞中。主要需要两个触发条件:

1、反序列化的攻击入口

2、反序列化的pop攻击链

这两个条件缺一不可。网上大量分析gadgets的文章方法,让人误以为有攻击链就可以反序列化。其实这块是有一定的误导性的。在我最初研究反序列化的时候,我觉得攻击链是最重要的。其实不然,反序列化的攻击入口才是至关重要的。因为现阶段的java环境加上java所在的金融、保险等大型项目中,往往组件jar包和jdk版本是更新最缓慢的,因为这块需要测试大量的兼容性,对大型java项目来说,攻击链基本上一定存在,除非该java程序最近才被开发、部署,且开发人员喜欢用最新的版本软件包。

0X01攻击入口

目前其实在白盒过程中要比较快的查找攻击入口的话。可以全局搜索是否有以下这类方法函数:

ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject

通过搜到到这些函数方法所在位置,再反向追踪是否可控输入流,如果可控,那么恭喜,反序列化的第一步已经完成。

拿我前几篇的文章来讲,XMLDecoder.readObject这块函数其实可以当做入口来看,至于为啥可以执行命令,你就当他当做system()函数来看,如果要更加深层的知道为啥可以执行命令,就可以跟下去,不过跟下去的话,属于更加底层的研究。

我们做安全其实可以分好几个攻击层次。

1、攻击普通开发者(这里的普通开发者可以指敏捷开发人员,大部分使用框架,或者现有函数库来使用,极大的加快了开发速度,但是对于框架具体底层功能实现可能不会特意去了解,大部分通过开发手册和api接口即可了解表层意义上的功能实现)

2、框架、底层库开发者(这类开发人员往往开发不是为了某个特定的东西,往往是为了帮助大量普通开发者更快、更短的代码实现一个功能,减少普通开发者的代码量,降低程序开发门槛)

3、系统层函数开发者(这类的开发者衔接的是高级面向对象的语言与底层汇编,甚至指令集之间的库函数)

随着攻击层次的加高,我们的攻击范围也会越广。

在这三个层次里,往往攻击入口点在1和2都会出现,更多的是出现在1层,而gadget在1和2也会出现,但是往往出现更多的在2层。

拿weblogic的xml反序列化来讲,把oracle的开发人员当做普通的拿现有开源框架库基础上开发的人员来看的话,他们造成反序列化的攻击入口点就在1层面,序列化的gadget在2层面。

在cve-2019-2725中,_async目录下的其实就是一个攻击入口,因为攻击入口和wls-wsat相似,所以后续分析和10271很像。

但是由于有10271补丁在,所以在2725中需要利用未在黑名单里的标签来绕过补丁。

0X02POP攻击链

java的pop攻击链不是说寻找难度不大,而是在现有yso工具在的情况下,对已有的漏洞利用来说,已经方便了很多。但是寻找一个新的pop链还是很困难的。

CommonsCollections1的gadget来说吧,因为网上这个的分析文章最多,所以也是我了解的比较熟悉的一个gadget。

这个漏洞的最关键地方是org.apache.commons.collections.functors.InvokerTransformer类下面的transform函数

public Object transform(Object input) {
        if (input == null) {
            return null;
        } else {
            try {
                Class cls = input.getClass();
                Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
                return method.invoke(input, this.iArgs);
            } catch (NoSuchMethodException var5) {
                throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' does not exist");
            } catch (IllegalAccessException var6) {
                throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
            } catch (InvocationTargetException var7) {
                throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' threw an exception", var7);
            }
        }
    }

然后更关键的地方是

 Class cls = input.getClass();
 Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
 return method.invoke(input, this.iArgs);

为啥这块危险呢,首先这个地方利用了java的反射机制,如果你不了解,你可以直接死记硬背或者理解成这样子写就是有一定问题的,等同于system(xxx),而xxx根据transform的形参来看,也就是input是我们可控的。且之间没有任何过滤。

this.iMethodName, this.iParamTypes

    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
        this.iMethodName = methodName;
        this.iParamTypes = paramTypes;
        this.iArgs = args;
    }

这两个读一下InvokerTransformer类的实现代码,发现初始化InvokerTransformer的时候,这两个也可控。所以这块是有可能成为POP链的。

public class InvokerTransformer implements Transformer, Serializable {

根据类的接口来看,这个类是可以序列化的,所以条件都达成。

但是这个类没有readObject的方法,所以payload还需要一个能触发这个反序列化类的地方。

根据对yso的源码查看,我发现CommonsCollections系列的readObject都是在sun.reflect.annotation.AnnotationInvocationHandler里触发readObject。

至于这个类,是在gadget.java里写死的。

public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";

在CommonsCollections1里

final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);

但是目前的构造还需要依赖于触发Map中某一项去调用setValue(),我们需要想办法通过readObject()直接触发
我们观察到java运行库中有这样一个类AnnotationInvocationHandler,这个类有一个成员变量memberValues是Map类型,如下所示
\openjdk\jdk\src\share\classes\sun\reflect\annotation\AnnotationInvocationHandler.java

因此,我们只需要使用前面构造的Map来构造AnnotationInvocationHandler,进行序列化,当触发readObject()反序列化的时候,就能实现命令执行。另外需要注意的是,想要在调用未包含的package中的构造函数,我们必须通过反射的方式,综合生成任意代码执行的payload的代码如下

中途遇到个比我写的好的。可以参考这个来看。

http://blog.0kami.cn/2019/10/24/study-java-deserialized-commonscollections3-1/

对ysoserial工具及java反序列化的一个阶段性理解【未完成】的更多相关文章

  1. 浅谈java反序列化工具ysoserial

    前言 关于java反序列化漏洞的原理分析,基本都是在分析使用Apache Commons Collections这个库,造成的反序列化问题.然而,在下载老外的ysoserial工具并仔细看看后,我发现 ...

  2. [JAVA反序列化DEMO]利用RMI进行反序列化一键启动工具

    功能: 命令行启动jar包,用户自定义启动RMI端口.默认内置Apache Commons Collections.只需一键启动即可测试java反序列化漏洞. 启动服务: [root@sevck_v3 ...

  3. Java反序列化漏洞通用利用分析

    原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...

  4. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  5. Java反序列化漏洞之殇

    ref:https://xz.aliyun.com/t/2043 小结: 3.2.2版本之前的Apache-CommonsCollections存在该漏洞(不只该包)1.漏洞触发场景 在java编写的 ...

  6. Lib之过?Java反序列化漏洞通用利用分析

    转http://blog.chaitin.com/ 1 背景 2 Java反序列化漏洞简介 3 利用Apache Commons Collections实现远程代码执行 4 漏洞利用实例 4.1 利用 ...

  7. 通过JBoss反序列化(CVE-2017-12149)浅谈Java反序列化漏洞

    前段时间学校学习J2EE,用到了jboss,顺便看了下jboss的反序列化,再浅谈下反序列化漏洞. Java序列化,简而言之就是把java对象转化为字节序列的过程.而反序列话则是再把字节序列恢复为ja ...

  8. 学习笔记 | java反序列化漏洞分析

    java反序列化漏洞是与java相关的漏洞中最常见的一种,也是网络安全工作者关注的重点.在cve中搜索关键字serialized共有174条记录,其中83条与java有关:搜索deserialized ...

  9. 25. Apache Shiro Java反序列化漏洞

    前言: 最近在审核漏洞的时候,发现尽管Apache shiro这个反序列化漏洞爆出来好久了,但是由于漏洞特征不明显,并且shiro这个组件之前很少听说,导致大厂很多服务还存在shiro反序列化的漏洞, ...

随机推荐

  1. 谷歌浏览器(Google Chrome)开发调试详细介绍

    很多Web前台开发者都喜欢这种浏览器自带的开发者工具,这对前台设计.代码调试很大帮助的. Chrome浏览器得益于其优秀的V8解释器,javascript执行速度和内存占有率表现非常优秀.对于html ...

  2. jQuery于js的区别和联系

    一.什么是jQuery jQuery 是 js 的一个库,封装了我们开发过程中常用的一些功能,方便我们调用,提高开发效率. js库是把我们常用的功能放到一个单独的文件中,我们用的时候,直接引用到页面里 ...

  3. JSON 初探

    Json是什么? JSON: JavaScript Object Notation(JavaScript 对象表示法) JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 XML 更小 ...

  4. mybatis+redis实现二级缓存

    在网上看了很多资料,发现例子都是千篇一律的相互复制.而且,使用的都是jedis的客户端..我这里使用的是redistemplate类实现. 缓存的原理..实现cache类接口,当哪个类需要缓存的时候, ...

  5. JAVA的带参数的方法

    一.带参数的方法 1.1 语法:                            <访问修饰符>  返回类型  <方法名>(<形式参数列表>) { //方法的 ...

  6. Java中堆内存和栈内存有什么区别

    本文链接:https://blog.csdn.net/wangbo1998/article/details/80379016Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基 ...

  7. electron-vue搭建项目

    原文链接 使用pdf.js插件与LODOP控件实现前端浏览器静默打印PDF文件 lodop官网地址:http://www.lodop.net/download.html 点击下载,文件里有使用手册 e ...

  8. 1632:【 例 2】[NOIP2012]同余方程

    #include<bits/stdc++.h> #define ll long long using namespace std; void Exgcd(ll a,ll b,ll & ...

  9. [BJOI2019]奥术神杖——AC自动机+DP+分数规划+二分答案

    题目链接: [BJOI2019]奥术神杖 答案是$ans=\sqrt[c]{\prod_{i=1}^{c}v_{i}}=(\prod_{i=1}^{c}v_{i})^{\frac{1}{c}}$. 这 ...

  10. 蚁群算法求解TSP问题

    一.蚁群算法简介 蚁群算法是对自然界蚂蚁的寻径方式进行模似而得出的一种仿生算法:蚂蚁在运动过程中,能够在它所经过的路径上留下信息素(pheromone)的物质进行信息传递,而且蚂蚁在运动过程中能够感知 ...