36

java反序列化的研究

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwMzYxNzc1OA%3D%3D&%3Bmid=2247486574&%3Bidx=1&%3Bsn=467f1f1124ccfd4f77cd431ae7a982df
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这是  酒仙桥六号部队  的第  67   篇文章。

全文共计1639个字,预计阅读时长6分钟。

前言

游走于各类项目,你会发现政府和大型企业是很喜欢使用java去进行开发,同时也使用一些框架、java中间件、java库文件去使得开发变得简单。对于java,渗透测试过程中最常见的漏洞就是反序列化。并且一旦存在反序列化漏洞,就很容易getshell。

NneuEf.jpg!mobile

既然反序列化如此危险,那政府企业为啥么还要使用这个功能呢?难道是专门为黑客留一丝念想?

jeIrEnQ.png!mobile

实现与成因

既然是反序列化,必然会有序列化。其中序列化是将Java对象转换成字节流的过程。而反序列化是将字节流转换成Java对象的过程。初衷是为了更方便进行数据和对象的存储、网络传输。

比如很多复杂的对象构造起来比较费时,企业为了节约开支,需要将这些对象写成服务,这样就可以通过远程代理的形式,对服务进行访问,在这远程调用服务的过程,就是序列化和反序列化的操作。

再比如内存中存在大量的对象,也会让内存难以承受,就像常见的session对象,如果有数以万计的用户并发去访问,那就会同样出现数以万计的session对象,这时web应用会将一些session先序列化存储在硬盘中,等需要使用的时候,再将其反序列化,还原到内存中,节约计算机内存资源。

想必大家对反序列化的作用有了一定了解,那咱亲自写个简单程序,去试试反序列是如何实现的,同时也看看反序列化漏洞形成的成因。

e2iM3mF.jpg!mobile

java程序中XMLEncoder与XMLDecoder就是一种序列化与反序列化的操作。

首先,我们需要先创建类文件:

然后,创建xmlEncoder.java并调用类文件,此java程序是对数据进行序列化,将内容存储为xml文件,即生成bug.xml文件。

最后,创建xmlDecoder.java并调用类,此java程序是对数据进行反序列化, bug.xml文件解析到内存中,并输出显示。

这样我们就将前期代码准备完成了,现在将运行程序,体验序列化和反序列化操作:

第一步,运行xmlEncoder.java程序将会生成bug.xml文件,文件内容为:

3yqmmaE.png!mobile

第二步,运行xmlDecoder.java程序将会把bug.xml文件解析为:

mMFvaea.png!mobile

在这里,如果我们在第二步中,将第一步生成的xml文件替换掉,换成自己的文件会发生什么事情呢?

6juYzaa.jpg!mobile

这次我们自己创建一个bug.xml文件,xml中存储打开计算器的命令(实际中可以替换成反弹shell等其他命令)。使用xmlDecoder.java程序,对此xml文件进行反序列化。

bug.xml文件为:

执行xmlDecoder.java程序,发现成功弹出计算器。

AjAV7rv.png!mobile

所以,当反序列化所使用的xml文件为用户可控的时候,产生反序列化漏洞。

和上述例子相似的反序列化有很多,比如常见的weblogic中间件:CVE-2019-2725、CVE-2017-10271、CVE-2017-3506。

其中CVE-2017-10271、CVE-2017-3506漏洞的数据输入点在 /wls-wsat/* 目录下,CVE-2019-2725漏洞输入点增加了一个/_async/*。

2Eb6niR.png!mobile

除了将java类序列化为xml格式外,还可以将java类序列化为二进制和json格式。但不管序列化成什么,在将这些数据转化为类的过程中,都有可能造成反序列化漏洞。

案例

Java json 反序列漏洞最常见的还是fastjson反序列化漏洞。

在最初版的fastjson反序列化漏洞(fastjson <=1.2.24)中,fastjson在反序列化处理以@type形式传入类的时候,会默认调用该类的共有set\get\is函数,而这时通过@type传入JdbcRowSetImpl类时,类中的setAutoCommit函数会触发lookup函数对成员变量dataSourceName中的内容进行查找,这时如果dataSourceName中通过rmi的方式传入一个恶意类,那么,在反序列化的时候就会执行这个恶意类文件(此处类文件中会执行反弹shell操作),从而引发远程命令执行(jndi注入利用)。

A7NzY37.png!mobile

FBB3uqm.png!mobile

FBriqi.png!mobile

第一版的fastjson反序列化漏洞曝出之后,官方立马做了更新,迎来了一个新的函数checkAutoType() ,而这个函数的作用就是限制了传入长度,并添加了一批黑名单,在接下来的一系列漏洞利用,都在想方设法的绕过这个函数,与这个函数斗智斗勇。

ZVnEzaB.png!mobile

既然是黑名单,那总有漏网之鱼。在fastjson 1.2.45版本中,通过ibatis类进行绕过。

UzMzQfQ.png!mobile

然,也有大佬想到了别的绕过方式,当传入的类的名字是以"L"开头以";"结尾的时候会把className的首字符和最后一个字符截去。 那这时可以将我们需要的类最前边加一个L,在末尾随便在添加一个字符,即可绕过。 这种方法适用于fastjson的1.2.41版本、1.2.42版本、1.2.43版本。

aiiY3qm.png!mobile

在之后47到49的版本中,发现可以通过构造两个json的方式来绕过黑名单。

Mjmeamn.png!mobile

EvI3Mnb.png!mobile

总结

到此,我们对java反序列化的漏洞研究也告一段落,相信大家对java反序列化有一定的了解了,期待下次相遇。

QFVfyib.png!mobile

FvEJvmn.png!mobile

JvUzYf2.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK