LOL投注平台




快速导航
KTC business

JAVA反序列化

LOL投注平台 Date:2020-01-28 07:49

这是个人学习java反序列化的第一篇利用链的文章,就好像P牛说的不知道为什么网上讲到java反序列化学习,上来就是cc链,你知道这个链它有多复杂么.jpg。萌新也是理所当然的踩了这个坑,然后…..在一路质疑自己智商和我不服的情况下趟了过去。

在此文中是以一个只了解java反射机制和反序列化利用点(readObject)的视角去一点点复现推导了commons-collections、jdk1.7的poc的构造。

如果你具备了反射机制和反序列化基本原理的知识,同时想学习cc链的话,个人感觉是这篇文是再适合不过了。

了解反射机制的话,我们会发现若存在一个固有的反射机制时,输入可控,就可能形成任意函数调用的情况,具有极大的危害。但实际上真的有存在这种情况:这就是commons-collections-3.1 jar包,cve编号:cve-2015-4852

客户端构造payload(有效载荷),并进行一层层的封装,完成最后的exp(exploit-利用代码)

exp发送到服务端,进入一个服务端自主复写(也可能是也有组件复写)的readobject函数,它会反序列化恢复我们构造的exp去形成一个恶意的数据格式exp_1(剥去第一层)

这个恶意数据exp_1在接下来的处理流程(可能是在自主复写的readobject中、也可能是在外面的逻辑中),会执行一个exp_1这个恶意数据类的一个方法,在方法中会根据exp_1的内容进行函处理,从而一层层地剥去(或者说变形、解析)我们exp_1变成exp_2、exp_3……

最后在一个可执行任意命令的函数中执行最后的payload,完成远程代码执行。

payload:需要让服务端执行的语句:比如说弹计算器还是执行远程访问等;我把它称为:payload

反序列化利用链:服务端中存在的反序列化利用链,会一层层拨开我们的exp,最后执行payload。(在此篇中就是commons-collections利用链)

readObject复写利用点:服务端中存在的可以与我们漏洞链相接的并且可以从外部访问的readObject函数复写点;我把它称为readObject复写利用点(自创名称…)

Java commons-collections是JDK 1.2中的一个主要新增部分。它添加了许多强大的数据结构,可以加速大多数重要Java应用程序的开发。从那时起,它已经成为Java中公认的集合处理标准。

Apache Commons Collections是一个扩展了Java标准库里的Collection结构的第三方基础库,它提供了很多强有力的数据结构类型并且实现了各种集合工具类。作为Apache开源项目的重要组件,Commons Collections被广泛应用于各种Java应用的开发。它是一个基础数据结构包,同时封装了很多功能,其中我们需要关注一个功能:

Commons Collections实现了一个TransformedMap类,该类是对Java标准数据结构Map接口的一个扩展。该类可以在一个元素被加入到集合内时,自动对该元素进行特定的修饰变换,具体的变换逻辑由Transformer类定义,Transformer在TransformedMap实例化时作为参数传入。

由于没有找到漏洞版本3.1的api说明,我们可以参考3.2.2的api文档

我们将通过调试POC得到漏洞利用链的调用栈,顺便介绍一下各个类,再通过分析调用栈的函数,反推出POC来探究其中的利用原理。

明显的反射机制,可见InvokerTransformer就是我们的触发任意代码执行处,我们看看源码中的文件描述:先看看我们需要关注的InvokerTransformer类的描述(在jar包中是找不到描述信息的,可以通过下载官方源码得到):

我们可以这里有经典的反射机制调用,在细节分析前我们先整理一下调用栈,但不需要很理解。

因为漏洞函数最后是通过反射机制调用任意这个语句先转化成反射机制如下(后面需要用到):

通过构造的反射机制以及以上代码进行填空,可以得出当变量等于以下值时,可形成命令执行:

我们就可以构建以下测试代码直接调用InvokerTransformer通过反射执行任意命令:下面开始试一下:

我们会发现如果我们要直接利用这个反射机制作为漏洞的话,需要服务端的开发人员:

实际上…..只有开发人员是自己人的情况下才满足条件吧……所以我们面临一些问题:

并且在代码正常操作中会调用这个类中的一个可触发漏洞地函数(当然这个函数最后会进入我们InvokerTransformer类的transform函数,从而形成命令执行)

如果这个反序列化的类和这个类触发命令执行的方法可以在一个readObject复写函数中恰好触发,就对于服务端上下文语句没有要求了!

这边假如像预期这样,是对服务端上下文没有要求,因为只要执行readObject就肯定会命令执行,不需要其他上下文条件。

下面我们需要关注ChainedTransformer这个类,首先看一下这个类的描述:

那么我们知道可以自定义iTransformers的内容,我们已有条件如下:

这里我们需要注意到input.getClass这个方法使用上的一些区别:

但是很遗憾的告诉以为快要成功的你,成功的本地测试加上序列化、反序列化过程之后就会失败。因为Runtime类的定义没有继承Serializable类,所以是不支持反序列化的。

既然我们没法在客户端序列化写入Runtime的实例,那就让服务端执行我们的命令生成一个Runtime实例呗?我们知道Runtime的实例是通过Runtime.getRuntime来获取的,而InvokerTransformer里面的反射机制可以执行任意函数。同时,我们已经成功执行过Runtime类里面的exec函数。讲道理肯定是没问题的.

在这里,之前自己陷入了一个很傻逼的问题,即:InvokerTransformer类transform方法中return method.invoke这个语句invoke调用到底return了啥?因为在这里形成了一个调用return的结果,再调用的链。为什么就可以上一个输出作为下一个输入时,可以成功调用了呢?一开始以为invoke会统一返回一个对象作为下一个输入什么的,并且在调试的时候每次invoke的结果都不一样,源码看的头晕。实际上是钻了死胡同:invoke的return是根据被调用的函数return啥,invoke就return啥。就好比我invoke一个我自定义的方法a,在a中,我return了字符串1。那么就是invoke的结果就是字符串1。看以上的过程就是第一次Runtime.getRuntime的结果输入了下一个InvokerTransformer

这里我们需要注意到input.getClass这个方法使用上的一些区别:

那么我们好像陷入了一个死胡同:得到Runtime类实例才能调用exec方法。而得到Runtime类实例作为input,才能得到Runtime class,才能找到getRuntime方法,得到Runtime类实例………

那么我们通过直接调用Runtime.getRuntime方法好像是行不通了,有没有其他方法呢?

通过反射机制获取反射机制中的getMethod类,由于getMethod类是存在Class类中,就符合开头Class类的限制

在哪个类中调用getMethod去获取方法,实际上是由invoke函数里面的的第一个参数obj决定的

再通过反射机制获取反射机制中的invoke类,执行上面获取的getRuntime函数

invoke调用getRuntime函数,获取Runtime类的实例这里在使用反射机制调用getRuntime静态类时,invoke里面第一个参数obj其实可以任意改为null,或者其他类,而不一定要是Runtime类

还差执行获取到的getRuntime,下一个input是上一个执行接口,继续对照

总体上来说:利用了反射机制调用反射机制的函数,绕过了开头cls只能为java.lang.Class的限制,根据具体环境input环环相扣,特么竟然恰好就通了….非常的微妙….

转变的类型是一个数据转化链数据格式,很明显服务端不可能存在这种代码,利用价值不足,接下来我们需要继续延长这个漏洞链。

由于我们得到的是ChainedTransformer,一个转换链,TransformedMap类提供将map和转换链绑定的构造函数,只需要添加数据至map中就会自动调用这个转换链执行payload。

这样我们就可以把触发条件从显性的调用转换链的transform函数延伸到修改map的值。很明显后者是一个常规操作,极有可能被触发。

上面的漏洞触发条件仍然不够完美,需要服务端把我们传入的序列化内容反序列化为map,并对值进行修改。之前也说过完美的反序列化漏洞还需要一个readobject复写点,使只要服务端执行了readObject函数就等于命令执行。

虽然相对于这个类具体做什么,实在是没有精力去搞清楚了,但是它最终对于我们传入构造函数的map进行遍历赋值。这样就弥补了我们之前反序列化需要服务端存在一些条件的不足,形成完美反序列化攻击。

至此我们就完成common-collection 3.1版本 jdk1.7版本下的POC复现和利用链分析。当然还有common-collection 不同组件版本,不同环境下poc和利用链均有不同,在ysoserial下就有7,8中利用方式。还可以通过rmi模式进行利用等。

但是由于这篇博客写的太长了,思路也一直断断续续,其他内容之后再陆续学习分析吧~

封面号文章仅代表作者本人观点,不代表封面号平台的观点,与封面号立场无关,文责作者自负。如因文章内容、版权等问题,请联系封面新闻。



相关阅读:LOL投注平台

 l