Java反序列化漏洞大家应该都非常熟悉了,想必大家手里都有各种各样的利用这类漏洞的工具。其被称为是2015年被低估的“破坏之王”可见其影响之大。Java反序列化漏洞的成因和PHP反序列化漏洞的成因差不多,都是由于程序接收不可信的序列化数据后直接将其反序列化导致的。这又印证了那句老话:一切的输入都是有害的。
Java中可以将对象序列化为字节流来方便对象的传输。在Java中很多地方都会用到对象序列化这种技术,我想这大概是Java反序列漏洞危害那么大的一个原因之一吧。在Java中有很多的看似与序列化没关系的东西都使用了序列化。比如一下的一些流行的协议,他们都是基于Java序列化的。
这样也就暴露很多潜在的攻击面。Java中只有实现了java.io.Serializable 或者 java.io.Externalizable接口的类才能被序列化和反序列化.能够被反序列的类通过使用 java.io.ObjectOutputStream 将对象转换为字节流,在通过使用 java.io.ObjectInputStream 将字节流反序列化为对象。而漏洞就发生在将输入的字节流反序列化为对象这一步。和 PHP 的反序列漏洞利用基本一致。我们能控制的有对象的属性,在Java反序列对象的过程中有一些 魔术方法会被调用比如 readObject() readResolve()等。如果某个可被反序列化的类实现了上述的某个方法,我们就有可能可以做到一些有趣的事情。下面来一个简单的Demo加深下理解。假设存在下面这样一个可被反序列化的类,同时该类在程序当前类路径中。
可以看到该类实现了 readObject 方法,在该方法中又调用了Runtime.getRuntime().exec(command) 来执行一条系统命令,其参数为类的一个属性值,而属性值是我们可控的所以我们就能实现一个代码执行了。当然现实中并没有这么直接,而是需要许多条件的,需要利用一些gadgets构造POP链实现一些有趣的事.如果目标应用使用了一些具有漏洞的库那就很简单了,直接上神奇Ysoserial生成payload发送给应用反序列化可以干掉它喽。就像这样
Java消息服务(Java Message Service)
Java 消息服务(Java Message Service,JMS)应用程序接口是一个Java 平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。下面来看看支持JMS的产品。
可以看到JMS这个东西还是很受欢迎的。下面看看JMS的一个基础的运行流程是怎么样的。
其中主要的组成部分有一些几点。
下面看看怎样使用API来发送和接收JMS消息
发送消息:
接收消息
前面提到过,在Java中有很多东西都是基于序列化的,JMS也是如此.我们先来看看JMS 消息的结构.
Message主要由三部分组成,分别是Header,Properties和Body, 解释如下:
Header: 消息头,所有类型的这部分格式都是一样的
Properties: 属性,按类型可以分为应用设置的属性,标准属性和消息中间件定义的属性
Body: 消息正文,指我们具体需要消息传输的内容。
JMS 消息的类型有很多,具体为
在这么多的类型中,有一种类型的消息,促成了攻击。他就是: javax.jms.ObjectMessage ,我们来看看官网是怎么介绍它的。
可以看到这个消息内部有一个可以序列化的对象,这就有趣了。下面接着看看ObjectMessage消息是怎样定义的
它有一个 getObject 方法,这个方法会将输入的消息反序列化。现在可反序列化的点已经找到,下面就是找找怎么样实现利用了。
漏洞挖掘
针对这种漏洞的挖掘思路很简单:找到接收不可信 ObjectMessage 的地方 之后分析程序所使用的一些库,看看能不能找到一些gadgets来构造一个 POP链,实现一个漏洞利用。实际上基本所有实现了ObjectMessage的组件中,都不会对输入的消息进行身份验证,直接拿去反序列化了。下面看看最近在这方面出现的漏洞。
下面是其中一个漏洞概要的截图。
可见这类漏洞发送的罪魁祸首就是 getObject 函数接收了不可信的输入。
漏洞利用
漏洞原理搞清楚了,进行利用就非常简单了。漏洞的本质就是接收不可信数据进行反序列化。那么我们就把发送包含payload对象序列化之后的数据的ObjectMessage发送到有漏洞的程序那就ok了。
整个一个漏洞利用的流程可以用下图来形象的解释。
攻击者假装为JMS 生产者向Broker提交一个带有恶意payload的ObjectMessage之后 Broker把消息分发给 JMS消费者,其拿个这样一个消息后对其中的序列化对象部分进行反序列化,触发漏洞,然后实现代码执行。而往往JMS消费者不会只有一个,所以现实中的情况会是这样。
有趣...
在实际构造exploit时并没有上面讲的那么轻松,一个成功的exploit 所要考虑的东西还是挺多的,比如:
1.jre的版本
2.应用程序所使用的库.
3.哪些库会在程序运行时的类路径中
4.是否开启 Java Security Manager
........
单纯的手工白盒分析是非常麻烦的,于是有了下面这个黑盒自动化工具来帮助我们.
JMET(Java Message Exploitation Tool)
下载地址:https://github.com/matthiaskaiser/jmet
工具支持的应用:
实战
目标:
看看目前了解到的的信息
1.一个网络管理软件
2.运行在 Jboss 5上.
3.使用了HornetQ的 JMS实现方式
4.审计方式为 本地或者 LDAP
5.十分依赖 JMS
下面来看看JMS的攻击面:
可以看到实现了很多MessageLister 来监听消息,其中使用了TextMessage 和 ObjectMessage.下面看一个有漏洞的实现
这里调用了ObjectMessage.getObject(),那么上JMET,由于JBOSS’ HornetQ需要登录,这里提供了账号和密码.
然后服务器上就弹了一堆的计算器.
说明该程序存在漏洞
总结
1.和其他的依赖于Java序列化机制的东西一样,JMS也会受到反序列化漏洞的影响.
2.所有发现的有漏洞的JMS应用都缺少对数据输入的验证.