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

readme:其实所有的反序列化漏洞都是因为在反序列化过程中,执行函数存在文件读写或者命令执行等情况。

3.2.2版本之前的Apache-CommonsCollections存在该漏洞。

Java安全之反序列化漏洞分析

原创 Java面试那些事儿 2017-10-27  作者 javatiku

1.Java序列化与反序列化

序列化与反序列化对于Java程序员来说,应该不算陌生了,序列化与反序列化简单来说就是Java对象与数据之间的相互转化。那么对于完全面向对象的Java语言来说为什么要有序列化机制?实质上,序列化机制并不只局限于Java语言,序列化的本质是内存对象到数据流的一种转换,我们知道内存中的东西不具备持久性,但有些场景却需要将对象持久化保存或传输。例如缓存系统中存储了用户的Session,如果缓存系统直接下线,带系统重启后用户就需要重新登陆,为了使缓存系统内存中的Session对象一直有效,就需要有一种机制将对象从内存中保存入磁盘,并且待系统重启后还能将Session对象恢复到内存中,这个过程就是对象序列化与反序列化的过程,从而避免了用户会话的有效性受系统故障的影响。此外,在Java工程中,序列化还广泛应用于JMX,RMI,网络传输(协议包对象)等场景,可以说序列化机制赋予了内存对象持久化的机会,就像虚拟机镜像(VMware Take a snapshot),也可以将序列化机制看作是内存对象的一种镜像机制。

在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以通过ObjectInputStream与ObejctOutputStream序列化,如下我们模拟了Session对象持久化存储与从磁盘加载的过程:

结合注释,这段测试代码应该不难理解,我们可以看到Java对象序列化就依赖于ObejctOutputStream的writeObject方法,而反序列化是由ObjectInputStream的readObject方法实现的,下图是作者画的一个序列化示意图:

2.反序列化漏洞成因

2015年年底,由公共依赖库Apache Common Collections引起的Java任意命令执行漏洞的严重安全问题,使得Java反序列化漏洞逐渐进入了安全

研究人员的视野(在此之前存在,但并未被重视),而任意命令执行的成因正是前文反序列化操作的ObejctInputStream类的readObject方法触发的。

Java序列化机制虽然有默认序列化机制,但也支持用户自定义的序列化与反序列化策略。例如对象的一些成员变量没必要序列化保存或传输,就可以不序列化,或者也可以对一些敏感字段进行处理等自定义对象序列化的行为,而自定义序列化规则的方式就是重写writeObejct与readObject。当对象重写了writeObejct或readObject方法时,Java序列化与反序列化就会调用用户自定义的逻辑了,下图示例我们对Session对象重写了序列化处理函数:

OK,到目前为止一切都在程序员的掌控之中!何来的漏洞之说?呵呵,意外往往就发生在不经意之间,如果反序列化过程中提供了命令执行的机会,那么任意命令执行漏洞就产生了,如下我们在Session对象的readObject函数中增加了执行命令的代码:

此时,黑客只需要将Session对象的sessionId构造成想要执行的命令字符串,即可实现远程命令执行的功能,如下成功打开系统calc.exe进程:

好了,我们再来梳理一下上例中漏洞存在的条件与利用思路:

  • 条件:首先Session对象重写了反序列化函数readObject,并且readObject方法存在执行命令的机会。

  • 漏洞利用:正常的反序列化流程会重新生成一个正常Session对象,而恶意的序列化数据抓住了反序列化的漏洞执行命令的机会,精心构造了序列化对象,使得数据流反序列化的过程中恶意命令得以执行。

看到这里,作为程序员的你肯定哈哈大笑!对象的反序列化函数谁会这样写?当然本示例只是为了以最直观的方式演示反序列漏洞产生原因,就直接提供了一个HelloWorld级别的漏洞示例,实际上,近两年 Java Apache-CommonsCollections 造成的序列化漏洞与Spring框架的反序列化漏洞(spring-tx.jar)的成因与原理都与上例相似,只是漏洞利用的构成比较复杂而已。

3.Apache-CommonCollections REC 漏洞解析

该漏洞曝光于2015年年底,被誉为当年“最被低估了的漏洞”,利用思路一经爆出,各大Java web 厂商纷纷躺枪,受此影响的Web服务器有:WebLogic、WebSphere、JBoss、Jenkins、OpenNMS等。介于该漏洞曝光距今已经有两年之久,并且网上也有对此分析的很透彻的文章,本文就来讲一下这个可以通过精心构造触发命令执行的漏洞的要点。

该漏洞的主要问题就出现在org.apache.commons.collections.Transformer接口上,在Apache-CommonsCollections包中,有一个InvokerTransformer类实现了Transformer接口,并且InvokerTransformer这个类也很恰巧,InvokerTransformer 的transform方法提供了一个可以通过Java反射机制,调用任意Java方法的机会:

相信很多漏洞利用者对 invoke非常敏感,意味着提供了方法调用的机会,再结合方法名与参数都能通过InvokerTransformer构造函数来控制,因此该类一定是漏洞挖掘者反复徘徊的点。那该如何利用?在commons-collections包中,InvokerTransformer结合ChainedTransformer就能构造一个Java类加载函数调用链,POC的作者是如下构造的:

这样构造的原因在于ChainedTransformer的transform函数会依次调用数组中InvokerTransformer的transform函数,构成一个函数调用链,下图是调试状态下,ChainedTransformer的transform方法的变量状态:

可以看到,通过ChainedTransformer.transform 的构造相当于反射调用了Runtime.getRuntime().exec(),从而触发了命令的执行。OK,那么问题来了,谁去触发调用ChainedTransformer.transform函数呢?漏洞利用者找到了包中TransformedMap.checkSetValue()方法:

这样一来,POC就可以通过构造一个TransformedMap对象,然后再想办法触发checkSetValue函数即可,而TransformedMap在Apache-CommonsCollections 这个集合库中可以通过TransformedMap.decorate修饰器方法来修饰一个Map对象,而Map对象在反序列化是只需调用MapEntiry.setValue就能触发checkSetValue函数,进而进一步触发第一步构造的ChainedTransformer.transform方法,从而实现漏洞利用的目的。

以上就是Apache-CommonsCollections RCE漏洞的利用思路,该漏洞的实质是Apache-CommonsCollections为利用者提供了一系列可以构造行命令机会。但是聪明的你一定会问,上面的漏洞触发条件并不是在反序列化函数readObject中实现的,怎么能在反序列化中触发POC的执行?好问题!思路是这样的,可以找到一个这样的对象:

  1. 该类自定义重写了 readObejct 反序列化函数。

  2. readObecjt 方法中调用了Map的checkSetValue函数,并且该Map对象还可以通过构造函数构造。

呵呵,我知道,你又开始笑了!的确利用条件比较苛刻,也难怪该漏洞在2015年初没有被重视起来,但是,无巧不成书,老外还就给你在JDK中找到了一个满足条件的的对象:sun.reflect.annotation.AnnotationInvocationHandler。好了,废话不多说,来看一下的AnnotationInvocationHandler的反序列化函数满不满足触发要求:

因为setValue函数会调用checkSetValue:

从而在sun.reflect.annotation.AnnotationInvocationHandler对象反序列化时,就满足了ChainedTransformer、TransformerMap构造的POC触发的条件,最后我们给出完整的构造Apache CommonCollections 反序列化漏洞利用POC的代码(POC来自网络):

小伙伴们看到这里可能一头雾水了,作者这里借用斗象科技在分析该漏洞时画的一幅漏洞POC构造与触发流程图,小伙伴们可以借此再来梳理一下该漏洞利用的思路:

因此,POC的触发流程为:TransformedMap->AnnotationInvocationHandler.readObject()->setValue()->checkSetValue() 最后由反序列化readObject时触发执行。的确,该漏洞的触发方法与构造思路非常精妙,就不得不佩服这位构造出POC的老外。

4.漏洞如何防范?

首先,开发者要有安全意识,应该清楚了解项目使用到的组件,以及这些组件是否存在漏洞,虽然说Apache-CommonsCollections RCE漏洞曝光将近两年时间,但使用3.2.2版本之前的Apache-CommonsCollections的web服务框架依然存在,近期曝光的Apache James 3.0.0 版本的CVE-2017-12628漏洞就是由于还在使用commons-collections-3.2.1.jar造成的。不过,安全意识对于很多开发者不是没有,而是没有接触过,作者曾在一个使用struts框架的团队待过,他们写出的代码真的是Web漏洞一箩筐啊。

此外,也可以禁用JVM执行外部命令(Runtime.exec),因为Runtime.exec对于大多数Java正常应用来说是不会用到的,但是确是黑客控制Web服务后运行命令的重要方法,因此该手段是Java Web防护常用的且有效的手段,如果从攻击者角度看这种防护效果,那就是攻击工具webshell只能文件相关操作,无法执行命令。可以通过扩展SecurityManager来禁用Runtime.exec,当触发运行时还可加入报警逻辑,启动应急响应:

5.反序列化漏洞利用的其他思考

作者认为反序列化漏洞的利用应该更为广泛,思路不应该仅仅局限于远程命令执行漏洞的利用,也存在着系统数据篡改污染的危险,造成系统业务安全问题。例如序列化对象在系统中承担了账单、金额、认证、鉴权等职责,如果可以被反序列化恶意利用,后果也非常严重。这样的威胁不亚于命令执行的威胁,并且事后难于排查,因为是内存攻击,载荷不落地。所以,反序列化对于业务安全的威胁也是我们一个值得深思的问题。

对了,有兴趣的从代码层面研究一把的小伙伴可以去公众号配套的代码仓库去下载。

ref:Java安全之反序列化漏洞分析(简单-朴实)的更多相关文章

  1. Java安全之Fastjson反序列化漏洞分析

    Java安全之Fastjson反序列化漏洞分析 首发:先知论坛 0x00 前言 在前面的RMI和JNDI注入学习里面为本次的Fastjson打了一个比较好的基础.利于后面的漏洞分析. 0x01 Fas ...

  2. Java反序列化漏洞分析

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

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

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

  4. Java安全之Shiro 550反序列化漏洞分析

    Java安全之Shiro 550反序列化漏洞分析 首发自安全客:Java安全之Shiro 550反序列化漏洞分析 0x00 前言 在近些时间基本都能在一些渗透或者是攻防演练中看到Shiro的身影,也是 ...

  5. Java安全之Cas反序列化漏洞分析

    Java安全之Cas反序列化漏洞分析 0x00 前言 某次项目中遇到Cas,以前没接触过,借此机会学习一波. 0x01 Cas 简介 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用 ...

  6. Fastjson反序列化漏洞分析 1.2.22-1.2.24

    Fastjson反序列化漏洞分析 1.2.22-1.2.24 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两 ...

  7. Fastjson 1.2.22-24 反序列化漏洞分析

    目录 0x00 废话 0x01 简单介绍 FastJson的简单使用 0x02 原理分析 分析POC 调试分析 0x03 复现过程 0x04 参考文章 0x00 废话 balabala 开始 0x01 ...

  8. Java安全之XStream 漏洞分析

    Java安全之XStream 漏洞分析 0x00 前言 好久没写漏洞分析文章了,最近感觉在审代码的时候,XStream 组件出现的频率比较高,借此来学习一波XStream的漏洞分析. 0x01 XSt ...

  9. Fastjson 1.2.22-24 反序列化漏洞分析(2)

    Fastjson 1.2.22-24 反序列化漏洞分析(2) 1.环境搭建 我们以ubuntu作为被攻击的服务器,本机电脑作为攻击者 本机地址:192.168.202.1 ubuntu地址:192.1 ...

随机推荐

  1. REST式的web服务

    “REST”是罗伊·菲尔丁(Roy Fielding)在他的博士论文中创造的缩写.菲尔丁论文的第5章勾画出了被称为REST风格或REST式的Web服务的知道原则.他是HTTP1.1规范的主要作者和Ap ...

  2. 驱动学习5: zynq实现点亮led

    驱动代码: #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #i ...

  3. CSS盒子知识

    此随笔写于学习完CSS盒子之后,所遇到的问题和感悟记录. 1.IE盒子: IE盒子的特性:对于IE浏览器来说width不是内容宽度.而是内容+外边距+边框的内容总和. 也就是说当盒子增加10px;那么 ...

  4. Asp.Net MVC 自定义登录过滤器

    1.新建类BaseController用于统一所有控制器继承扩展,方便扩展登录等过滤器.示例如下: using CloudWave.JustBeHere.JBH_H5.Controllers.Attr ...

  5. NOIP模拟赛16

    NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2 期望得分:100+100+ =200+ 实际得分:100+40+70=210 T1天天寄快递 直接模拟,代码丢了...... T2天天和不 ...

  6. PHP扩展--taint检测隐藏漏洞

    简介 Taint 可以用来检测隐藏的XSS code, SQL注入, Shell注入等漏洞, 并且这些漏洞如果要用静态分析工具去排查, 将会非常困难, 比如对于如下的例子: <?php echo ...

  7. 从零搭建SSM框架(三)SSM框架整合

    整合思路 1.Dao层: Mybatis的配置文件:SqlMapConfig.xml 不需要配置任何内容,需要有文件头.文件必须存在. applicationContext-dao.xml: myba ...

  8. 【NOIP】提高组2014

    Day1 T1(暴力):大水题 #include<cstdio> ][]={ ,,,,, ,,,,, ,,,,, ,,,,, ,,,,, }; ],b[]; int main() { in ...

  9. FastDFS图片服务器java后台的简单调用

    工具类: package com.liveyc.common.fdfs; import org.apache.commons.io.FilenameUtils; import org.csource. ...

  10. Linux实用命令之git-svn

    近日发现了有一个工具,git-svn,可以打通git svn之间的鸿沟. 很适合习惯于git,却需要维护svn代码的同学. 安装 sudo apt-get install git-svn 具体使用就不 ...