注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

wadcl的博客

不是世界太大,是我们的世界太小

 
 
 

日志

 
 

Java反序列化POC解析  

2016-03-08 18:09:27|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Java反序列化漏洞出来已经过去很长一段时间了,在各种利用工具的发布的不断推进下,漏洞的修复速度也比以往快了不少。但是作为一个java菜鸟,我看着工具的版本的更新,今天支持jboss的回显了,明天weblogic搞定了,再就是RMI又搞定了,我其实很想知道最开始的那一长串命令执行的POC是怎么被弄出来的!

 

0x01 基本知识

继承:继承是从已有的类中派生出新的类,新的类能吸收已有的数据属性和行为,并能扩展新的能力

目的:提高代码的复用性

特点:子类会自动继承父类所有的方法和属性。

 

重写:在Java中,子类可继承父类中的方法,有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖

特点:覆盖方法必须和被覆盖方法具有相同的方法名称、参数列表和返回值类型

如果直接调用方法,是在当前子类中先查找,如果子类有会调用子类的

 

 

Java实现序列化和反序列化通过实现 java.io.Serializable 接口以启用其序列化功能,未实现此接口的类将无法使其任何状态序列化或反序列化。

特点:序列化接口没有方法或字段,仅用于标识可序列化的语义

两个方法:

writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以恢复它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制

readObject 方法负责从流中读取并恢复类字段。它可以调用 in.defaultReadObject 来调用默认机制,以恢复对象的非静态和非瞬态字段

 

0x02 POC分析

Apache Commons Collections库是实现对java.util的扩展封装,灵活的处理数据,它的结构是:

 

Java反序列化POC解析 - wadcl - wadcl的博客

 


Collectionsjava库中,有一个接口Transformer,它定义了transform()方法,此方法的功能是用来将一个对象转换成另一个对象,也就是所有想要实现Transformer接口的类,都要实现transform()方法:

 

Java反序列化POC解析 - wadcl - wadcl的博客
 

InvokerTransformer就是实现了Transformer接口,以及其transform()方法,但是是通过调用java的反射机制来实现的:

Java反序列化POC解析 - wadcl - wadcl的博客
 

 


Java反射属于java的一个特点,在以往的安全漏洞中,java反射也常常用来作为实现命令执行的工具,而代码中出现java反射的代码,也往往会去看是否能够控制输入。

InvokerTransformer的源码中,通过构造函数和传参来控制这些变量:

Java反序列化POC解析 - wadcl - wadcl的博客



而系统命令如何通过java反射来实现:

Java反序列化POC解析 - wadcl - wadcl的博客
 


最后将两部分结合起来:

       //获取到Method类型,数值为:java.lang.Runtime.getRuntime()方法

       Transformer transformer1 = new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class },new Object[] { "getRuntime",new Class[0] });

       System.out.println(transformer1.transform(Runtime.class));

      

      

    //  利用反射invoke来执行getRuntime方法,获取当前运行的Runtime类实例,

       Transformer transformer2 = new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class },new Object[] { null, new Object[0] });

       System.out.println(transformer2.transform(transformer1.transform(Runtime.class)));

   

      

    //  通过获取的Runtime运行实例,来执行系统命令

       Transformer transformer3 = new InvokerTransformer("exec", new Class[] { String.class }, new Object[]{"calc.exe"});

        transformer3.transform(transformer2.transform(transformer1.transform(Runtime.class)));



POC中,利用mapsetValue方法来触发代码,我认为是考虑到transform()方法在实际的应用开发中,不常用,所以需要寻找常用的方法来间接实现这行代码,而在TransformeredMap类中:

Java反序列化POC解析 - wadcl - wadcl的博客


checkSetValue(Object value)put(Object key,Object value)方法可以实现transform方法。

PscheckSetValue(Object value)的调用与MapsetValue有关:


 

 
Java反序列化POC解析 - wadcl - wadcl的博客
 

所以在MapsetValueput方法时,可以实现我们的目的。

但是根据transformer3.transform(transformer2.transform(transformer1.transform(Runtime.class)));这行代码,又有新的问题:

1、     如何一次putserValue就实现这行代码;

2、     如何保证transform1.transform(xxx)的方法调用中,参数传递的是Runtime.class

decorate(a,b,c)中,参数类型是Transformer,于是找实现该接口的类有啥?

Java反序列化POC解析 - wadcl - wadcl的博客
 

其中ChainedTransformer类可以传入transformer数组,并执行transform方法:

Java反序列化POC解析 - wadcl - wadcl的博客
 


正好解决了transformer3.transform(transformer2.transform(transformer1.transform(Runtime.class)))的问题。

ConstantTransformer类,有能保证transform方法传入的参数为Runtime.Class

Java反序列化POC解析 - wadcl - wadcl的博客


我觉得到这里,也就差不多了,命令执行的POC就是:

Java反序列化POC解析 - wadcl - wadcl的博客
 


而对于漏洞发现者和其他的安全研究员不会满于现状,在sun.reflect.annotation.AnnotationInvocationHandler类中,有一个readObject(OIS)方法:

Java反序列化POC解析 - wadcl - wadcl的博客
 


构造函数:

Java反序列化POC解析 - wadcl - wadcl的博客
 


也就是能够控制变量memberValue,于是乎,形成了最后的POC

Java反序列化POC解析 - wadcl - wadcl的博客
 


也就是在readObject()方法,进行反序列化的时候触发命令执行

0x03 实际利用

在实际安全审计中,要控制这个漏洞,需要考虑的条件是:

l  存在接受外部输入的序列化对象的接收点

l  审计源码中对反序列化函数的调用(例如readObject()

l  直接对应用交互数据流进行抓包,查看流量中是否包含java序列化数据来判断,java序列化数据的特征为以标记(ac ed 00 05)开头

l  应用的Class Path中是否包含Apache Commons Collections

而为什么这个漏洞POC不能像当初struts2的漏洞一样,就一个工具搞定,而需要针对weblogicjboss等这些应用进行专门开发利用工具,是因为反序列化与序列化的关系,服务器负责反序列化,攻击端负责序列化,因此需要了解服务器端反序列化时的处理以及额外的编码过程等,例如下面的实例:

服务器端反序列化,有一个base64解码:

Java反序列化POC解析 - wadcl - wadcl的博客
 

 
 
 


所以在POC的构造中,需要base64编码:

Java反序列化POC解析 - wadcl - wadcl的博客


0x04 漏洞修复

Apache Commons Collections 已经在在3.2.2版本中做了修复,对这些不安全的Java类的序列化支持增加了开关,默认为关闭状态。

Java反序列化POC解析 - wadcl - wadcl的博客

Java反序列化POC解析 - wadcl - wadcl的博客


  评论这张
 
阅读(58)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017