告别脚本小子系列丨JAVA安全(6)——反序列化利用链(上)

本文聚焦Java反序列化利用链,先介绍反序列化环境准备,借助ysoserial工具。接着详细分析URLDNS利用链和CC链中的Transform链,阐述其原理、特点及避免DNS请求的方法。此外,还提及网络安全行业特点及学习资源,如路线图、视频教程等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x01 前言

我们通常把反序列化漏洞和反序列化利用链分开来看,有反序列化漏洞不一定有反序列化利用链(经常用shiro反序列化工具的人一定遇到过一种场景就是找到了key,但是找不到gadget,这也就是在这种场景下没有可利用的反序列化利用链)。如果我们向某个漏洞提交平台提交一个反序列化漏洞,但是不给反序列化利用链,那么平台大概率是不会接受这种漏洞的。

反序列化利用链是整个反序列化利用过程中最关键的一环,通常反序列化利用链需要借助常用的第三方jar包,其中最有名的就是CommonCollections利用链(简称CC链)。

1

告别脚本小子系列丨JAVA安全(1)——JAVA本地调试和远程调试技巧

2

告别脚本小子系列丨JAVA安全(2)——JAVA反编译技巧

3

告别脚本小子系列丨JAVA安全(3)——JAVA反射机制

4

告别脚本小子系列丨JAVA安全(4)——ClassLoader机制与冰蝎Webshell分析

5

告别脚本小子系列丨JAVA安全(5)——序列化与反序列化

**0x02 ** 反序列化环境准备

为了更方便初学者来学习反序列化利用链,我们首先要准备当前需要的实验环境。学习反序列化利用链最好的办法是参考ysoserial(https://github.com/frohoff/ysoserial),ysoserial是一个开源的集成化反序列化利用链工具,可以快速生成反序列化利用链payload。

如果是不追求细节的小伙伴,可以直接按照参照ysoserial使用文档来生成payload,如下图所示。本文的主要目的是教会小伙伴们告别脚本小子,所以就不直接使用编译好的jar包,但是我们后面很多利用代码会参考ysoserial中的代码,ysoserial中关于反序列化利用链的代码都在ysoserial.payloads包中。我们的目的是不通过ysoserial框架,自己实现相应的反序列化利用链。我们搭建反序列化测试的基础环境,新建maven项目,添加项目依赖的jar包。为了模拟序列化和反序列化的过程,编写两个公用的静态方法,这两个方法将在后面的反序列化利用链中被多次使用。其中searialize方法的作用是把对象obj序列化之后保存到文件filename中,unserialize方法的作用是把文件filename中的数据读出来反序列化为对象。通过读写文件来模拟序列化和反序列化的过程是最直观的实现方式,但是在实际环境中,我们遇到的都是基于POST输入的字符输入流来进行反序列化,如下图所示。本地读写文件的反序列化和基于POST输入字符的反序列化是完全没有区别的,所以我们后面在研究反序列化利用链的时候都是通过本地文件读写的方式来实现,而不会准备专门的WEB漏洞环境。

某系统反序列化漏洞实例

0x03 反序列化利用链

0x3.1 URLDNS利用链

URLDNS链是JAVA众多利用链中最简单的一条利用链,非常适合初学者研究学习,具有下面的特点:

1)利用链只依赖jdk本身提供的类,不依赖其他第三方类,所以具有很高的通用性,可以用于判断目标是否存在反序列化漏洞。

2)利用链本身只能执行域名解析的操作,不能执行系统命令或者其他恶意操作。如果向漏洞提交平台提交反序列化漏洞,但是利用链是URLDNS的利用链,那么漏洞提交平台可能会拒绝这个漏洞。

Ysoserial中关于URLDNS链的主要代码如下图3.1.1,图3.1.2所示。这里面有一个很关键的点是使用了自定义的SilentURLStreamHandler类,为什么要使用这个自定义的类,我将在后面说明原因。

图3.1.1
生成URLDNS利用链对象

图3.1.2 自定义SilentURLStreamHandler类

我们先把ysoserial的代码搬运到本地,做一名合格的搬运工。直接搬运过来之后运行payload可以查看到DNSLOG的日志,证明搬运工没有问题了。搬运过来之后需要去掉ysoserial中的反射调用,我们这里没有Reflections类,所以自己写关于反射调用的代码,如图3.1.3所示,运行结果如图3.1.4所示

图3.1.3
本地引用URLDNS利用链

图3.1.4 运行之后可以在DNSLOG查看DNS请求日志

为了理清楚利用链的整个流程,我们在java.net.
URLStreamHandler类的getHostAddress方法中下断点调试一下,如图3.1.5所示。

图3.1.5 下断点调试URLDNS利用链

运行整个payload,根据debug查看栈调用情况,如图3.1.6所示。其中最关键的红色的框中的部分,可以看出整个利用链非常简单。

图3.1.6 URLDNS利用链的栈调用情况

首先反序列化入口是在HashMap的readObject,在这个方法中会调用本类的hash方法,如图3.1.7所示。

图3.1.7 在HashMap的readObject方法中调用HashMap的hash方法

继续跟进hash方法,在这个方法中会调用key的hashCode方法。Key对应的值是java.net.URL类的对象,如图3.1.8所示。

图3.1.8 通过hash方法调用URL类的hashCode方法

继续跟进会调用java.net.URL类的hashCode方法,会调用handler字段的hashCode方法。而handler定义来自于URLStreamHandler类,所以会调用URLStreamHandler类的handler方法,如图3.1.9所示。

图3.1.9 URL类的hashCode方法调用URLStreamHandler类的hashCode方法

继续跟进java.net.URLStreamHandler类的hashCode方法,如图3.1.10所示。这里可以看出里面就直接调用了getHostAddress方法,该方法执行之后会进行域名到IP地址的解析请求。

图3.1.10 最终调用了域名解析相关的方法getHostAddress方法

到这里已经看完了整个调用栈的流程,但是还是没有找到任何理由必须要用自定义的SilentURLStreamHandler类。为了理清楚原因,我们对原来的payload进行修改,去除自定义的SilentURLStreamHandler类,如图3.1.11所示。

图3.1.11 修改后的URLDNS利用链

还是在java.net.
URLStreamHandler类的getHostAddress方法中下断点。可以看到整个栈调用情况如图3.1.12所示。可以看出触发getHostAddress方法的入口点是从generalURLDNS2这个方法,而不是unserialize方法,也就是在生成序列化对象的时候就已经触发了域名解析的请求。由于JAVA内部对DNS请求存在缓存机制,那么在反序列化的时候会优先从DNS缓存中查找域名解析记录,那么反序列化的时候就收不到正确的DNS请求数据。

图3.1.12 修改后的URLDNS利用链

我们跟一下在生成payload时候触发getHostAddress的流程,其中最关键的是执行HashMap中的put方法,如图3.1.13所示。

图3.1.13 URLDNS利用链生成对象时调用HashMap的put方法

跟踪put方法的定义,如图3.1.14所示。里面会调用hash方法

图3.1.14 HashMap的put方法会调用本类的hash方法

剩下的流程和上面分析调用栈一样,最终会导致触发执行getHostAddress方法。为了避免在生成payload的时候触发DNS请求,影响反序列化时DNS请求的执行。有两种解决办法。

1)第一种就是像ysoserial代码中的方式一样,定义一个类继承自URLStreamHandler,并且在类中重写getHostAddress等方法,使得在序列化的时候不会执行getHostAddress方法。

2)第二种办法是通过通过java.net.URL类中的hashCode方法中的逻辑来避免执行后续的getHostAddress方法。

第一种方法在ysoserial的代码中已经写很清楚了,这里主要再说一下第二种方式。在整个利用链中一个很重要的步骤是会调用java.net.URL类中的hashCode方法。如图3.1.14所示。

图3.1.15 java.net.URL类中的hashCode方法代码逻辑

这里有一个很重要的判断语句是,如果hashCode不等于-1,则直接返回对应hashCode的值,否则调用hashCode方法计算对应的值。这里需要特别注意的一点是这里的hashCode既是java.net.URL类的方法,也是java.net.URL类的字段。所以我们需要

1)第一次put的时候把hashCode字段设置为不是-1的值,避免运行下面的handler.hashCode(this)。

2)生成序列化对象的时候又需要把hashCode字段设置为-1,因为反序列化的时候需要运行下面的handler.hashCode(this)。

所以我们也可以通过反射修改hashCode字段的方式来避免在序列化的时候触发DNS请求,再次修改后的代码如图3.1.15所示。这里最主要的是增加了通过反射修改hashCode字段的操作。

图3.1.16 通过控制hashCode字段避免序列化时候触发DNS请求

这样之后也能达到和ysoserial代码一样的效果。也能正常触发URLDNS的请求,如图3.1.16所示。

图3.1.17
通过修改的payload触发URLDNS链的DNS请求

**0x3.2 ** CC链

CC链是最早出现的影响较大的java反序列化利用链,原作者一共给出7条利用链,但是后来有很多大牛在此基础上给出了一些改进的利用链,对初学者而言,学习CC链是属于学习JAVA反序列化利用链的重要基础。关于CC链的内容很多,限于篇幅有限,这次的文章先开头对部分CC链进行讲解,关于CC链的更多内容将在下一篇文章中详述。本次我们主要先讲关于CC链中的Transform链。在学习Transform链之前,首先需要说明JAVA中命令执行的方式。JAVA中最典型的运行操作系统命令的办法是通过Runtime类来执行,如图3.2.1所示。

图3.2.1 JAVA中执行系统命令的方式

但是在反序列化的过程中不能直接通过Runtime来执行,因为Runtime类没有继承Serializable接口,如图3.2.2所示。

图3.2.2 Runtime类没有继承Serializable接口

但是我们可以通过反射的方式来调用Runtime类执行,并且里面涉及到的全部类都继承了Serializable接口,如图3.2.3所示。这里有一个坑是,通过反射来执行方法的返回值类型一定是Object类型,需要做强制类型转换,把Objectl类型转化为Runtime类型。后续的Transform利用链基本上都是通过执行这段代码来执行系统命令的。

图3.2.3 通过反射的方式来执行Runtime类的exec方法

严格来说Transform链属于整个CC链中的Sink点,CC链基本上都是通过Transform来最终执行系统命令的。学习Tranform链是掌握CC链的基础前提,最典型的Transform链如图3.2.4所示。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图3.2.4 典型Transform链运行情况

直接运行上面的代码是可以弹出计算器的,多数CC链最终也是通过调用类似的代码来执行系统命令。为了理解Transforml链的内容,需要分开来看里面涉及到的几个类:InvokerTransformer类、ConstantTransformer类和ChainedTransformer类。在InvokerTransformer类中,最主要的是transform方法。该方法中通过反射的方式执行任意一个类的方式,如图3.2.5所示。Transform执行的方法必须是public修饰符的。

图3.2.5 通过InvokerTransformer类的transform方法执行任意public方法

InvokerTransformer类的transform方法提供了一种执行任意其他方法的路径,我们写一个简单的例子来帮助大家理解transform方法,如图3.2.6所示。定义一个类TEST,类中定义一个方法Hello,那么我们就可以通过tranform方法来执行TEST类的Hello方法。

图3.2.6 典型的transform方法调用

可能有的小伙伴会疑惑,我要执行Hello,为什么不直接调用,非要通过transform来调用呢?试想一下,如果我们要执行的是“Runtime.getRuntime()”这样的方法,但是整个系统中都没有任何地方直接调用了这个,那么我们是不是就可以通过transform来间接的执行这个方法呢。但是现在通过transform来执行方法还有一个很明显的不足,就是只能执行单个对象的单个方法,不能链式调用。形象一点来说明这个问题,我们可以执行”Runtime.getRuntim()”,但是我们不能执行“Runtime.getRuntime().exec(xxxx)”。我们需要找到链式调用的方式,幸运的是CommonsCollections中提供了另一个类ChainedTransformer。ChainedTransformer类中提供了链式调用transform方法的办法,如图3.2.7所示。ChainedTransformer类的构造方法是传入Transformer类型的数组,通过transform方法依次遍历数组中的每一个元素,上一步的方法调用的输出作为下一步的方法调用的输入,完美的链式调用解决办法。

图3.2.7 通过ChainedTransformer类链式调用transform方法

现在已经可以链式调用来执行命令了,但是还有一个问题没有解决,从图3.2.3中可以看出要执行命令,第一步是获取Runtime.class对象,如何通过某个类的transform对象来获取Runtime.class对象呢?这个时候就要用到CommonCollections包里面另一个类ChainedTransformer。ChainedTransformer类的transform方法很简单,就是直接返回构造函数中的iConstant字段,如图3.2.8所示。这完美地解决了我们想要Runtime.class对象的愿望。

图3.2.8 通过ChainedTransformer类获取Runtime.class对象

通过上面的分析可以知道通过Transform链已经可以达到执行操作系统命令的效果,如图3.2.4所示。目前的情况是如果反序列化的时候,可以调用ChainedTransformer类的transform方法,则可以导致命令执行,但是反序列化的时候会自动调用的是readObject方法,如何通过readObject方法来调用transform方法呢?这是下一次分享的内容,未完待续。

0x04 总结

这次主要分享的是关于反序列化利用链的知识,主要介绍了URLDNS利用链和CC链中的Transform链。这些都是属于JAVA反序列化的基础知识,后续的知识都会在此基础上进行延展。从文中可以看出反序列化利用链通常包含比较复杂的逻辑知识,就算是最简单的URLDNS链也能让初学者难受,分析反序列化利用链不能太快,理解很重要。后续还有更多关于反序列化利用链的分享,欢迎交流沟通。

参考链接

https://xz.aliyun.com/t/9873

https://github.com/frohoff/ysoserial

原文链接

/s?__biz=MzkzNjMxNDM0Mg==&mid=2247485071&idx=1&sn=830634ad6a570e08a1b5d6780175f028&chksm=c2a1d206f5d65b10f9a731195f726d2885aec965d9ba37551113b81c9afa045a4079480360d3&token=911612436&lang=zh_CN#rd)

题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

2023届全国高校毕业生预计达到1158万人,就业形势严峻;

国家网络安全宣传周公布的数据显示,到2027年我国网络安全人员缺口将达327万。

一方面是每年应届毕业生就业形势严峻,一方面是网络安全人才百万缺口。

6月9日,麦可思研究2023年版就业蓝皮书(包括《2023年中国本科生就业报告》《2023年中国高职生就业报告》)正式发布。

2022届大学毕业生月收入较高的前10个专业

本科计算机类、高职自动化类专业月收入较高。2022届本科计算机类、高职自动化类专业月收入分别为6863元、5339元。其中,本科计算机类专业起薪与2021届基本持平,高职自动化类月收入增长明显,2022届反超铁道运输类专业(5295元)排在第一位。

具体看专业,2022届本科月收入较高的专业是信息安全(7579元)。对比2018届,电子科学与技术、自动化等与人工智能相关的本科专业表现不俗,较五年前起薪涨幅均达到了19%。数据科学与大数据技术虽是近年新增专业但表现亮眼,已跻身2022届本科毕业生毕业半年后月收入较高专业前三。五年前唯一进入本科高薪榜前10的人文社科类专业——法语已退出前10之列。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。

网络安全行业特点

1、就业薪资非常高,涨薪快 2022年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

img

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。
img

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

img

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值