freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

JAVA反序列化基础-手把手调试系列-类的动态加载
potatosafe 2022-01-21 03:33:38 138681

前言

因为之前发了一些反序列化利用链子,这段时间本来把链子又写了几个的,但是怕有些小伙伴可能不理解(原谅我的菜扣脚的文笔和技术),所以准备在写一些Java反序列化基础的东西,给之后的Java链做个铺垫,这些其实也是我自己的学习笔记包括思路,其实有时候我感觉这些基础才是实打实的东西,废话不多说,直接开始。

一、课前实验

这里我写了三个加载器(不清楚这块的小伙伴也可以直接往下看,后面文章里面都有说),可以看到外面的自定义加载器和扩展类加载器都可以输出,但是启动类加载器是无法输出的。

1642704321_61e9adc16f56c303e297b.png!small?1642704328940

接下来我们使用系统类加载器加载一个我们的自定义类,这里我就用之前写的CC1吧。

1642704841_61e9afc9df4f1689a1f14.png!small?1642704847667

二、断点调试流程

我们首先打一个断点,可以看到此时我们调用的是Launcher类下的AppClassLoader下的loadclass,我们跟进Launcher

1642705078_61e9b0b619a620a984cc5.png!small?1642705085701

我们可以先看一下Launcher的结构

1642705015_61e9b077983c91c059c77.png!small?1642705022521

我们跟到AppClassloader下的loadClass,可以看到需要传入两个参数所以它会一直跳到它的父类ClassLoader下的loadClass。

我们来到了ClassLoader下的一个参数的LoadClass(),它返回了两个参数的loadClass。所以当我们最开始直接往下调试会到ClassLoader.loadClass。

继续向下,我们跳回了Launcher的AppClassLoader的loadClass,我们继续看代码最终它调用了它super的loadClass,向下调试进入

我们又回到了ClassLoader但这次走两个参数的loadClass(String name, boolean resolve)

我们看一下这里的代码,我们开始继续向下

其实从这里开始我们就是双向委派机制了,我们了解一下双向委派,这里我画了一张图,大家看图应该就能理解了,其实还是属于一个单向过程的。如果还是不清楚可以去找些资料学习一下。

我们继续向下分析,跟到findLoadedClass,这个方法主要是判断类是否已加载。我们分析一下这块。跳转进该方法,我们看到它将我们的类name传到了checkName中,继续向下。

看代码我们可以知道,如果name里有“/”、使用数值但虚拟机不支持class数组返回false,其他情况或者空name返回true,所以我们返回了true。VM.allowArraySyntax字面翻译允许数组语法,这里可能有的小伙伴在JBOSS调试的时候可能遇到过这个问题。所以这里我们稍微继续看一下,跟进VM.allowArraySyntax()。

跟到VM.allowArraySyntax()下面,我们可以看到allowArraySyntax = defaultAllowArraySyntax而defaultAllowArraySyntax = false;可以看到这里的默认值是false,这里我去查了一下资料,这个参数默认值是true,而在jdk1.6中这个参数的默认值是false。我们继续看一下这个常量都是谁调用过的吧。

这里我们可以看到saveAndRemoveProperties调用的。

我们跟到saveAndRemoveProperties方法,方法的如图的位置设置了AllowArraySyntax,也就是将传入的props配置的sun.lang.ClassLoader.allowArraySyntax赋值给allowArraySyntax。这里有注释。

// Set a boolean to determine whether ClassLoader.loadClass accepts

// array syntax.  This value is controlled by the system property

// "sun.lang.ClassLoader.allowArraySyntax".

翻译为 设置一个布尔值以确定是否使用ClassLoader.loadClass接受数组语法。此值由系统属性控制。

接下来我们看看谁调用了saveAndRemoveProperties方法。

查看调用方法,最后跟到了initializeSystemClass,这里相当于初始化sun.misc相关的环境变量在往下的东西就不看了。有点说多了,我们继续返回到findLoadedClass()

跳回findLoadedClass0,checkName(name)最终返回为true。取反之后是false所以我们就走到了findLoadedClass0,这个方法还是一个native的方法,这里就不多说了。

之后我去查了一些资料,在ClassLoader的loadClass方法中第一步是去加锁,代码里面写的很清楚,也就是为了并发安全,第二步就会调用findLoadedClass方法判断该类是否已经加载过,加载过就返回Class对象,未加载过就返回null。

好了这块其实已经明白了,我们只要知道此处类加载过就返回Class对象,未加载过就返回null。我们回到ClassLoader继续看。

返回继续看代码这里如果类没有被加载就去加载类,之后判断parent,如果父类加载器不为空,让父类加载器去加载这个类。

我们此时有递归到了ClassLoader的loadClass,这里的extclassloder也是和appclassload是一样的(他俩其实就是逻辑上的调用关系),都是没用loadclass方法,然后向上找父类就到了ClassLoader的loadClass。我们继续向下调试

这里我们可以看到外面的findLoadClass返回为空,然后我们parent返回为null,这里其实我们是无法调用启动类加载器的,因为Bootstran加载器是底层的加载器我们是无法在java里面获得的所以就为null,我们开篇的实验就是为了说明这里。所以我们继续往下走。

这里我们走到了findBootstrapClassOrNull,这里和findLoadedClass的检查方式其实是一样的,我就不多进行赘述了。

我们继续往下走,我们的c依旧为空,所以我们最后是进到了findClass这里

这里我们就进到了URLClassLoader类下的findClass。这里是因为我们的AppClassLoader和ExtClassLoader是没有findClass这个方法的,他们的直接父类是URLClassLoader。我们继续向下分析。

这里我们是属于ExtClassLoader所以我们这里是无法加载到的,所以我们跳出循环

我们又回到了ClassLoad.loadclass,此时我们是appclassloader,继续往下跟进

我们再次进入findclass,这次应该就是最后一次了

我们回到了URLClassLoader,此时我们就找到了我们的加载类,我们继续跟进。

进入URLClassLoader的defineClass,我们们又走到它他下面的defineClass,这个方法就是我们利用的地方。继续跟进去

我们这里进入了SecureClassLoader下的defineClass,这一套又一套的,继续跟吧

这时我们又回到了ClassLoader的defineClass,这里可以看到我们调用的了defineClass1,此处就是关键,我们看一下这个方法

我们看到又是个native,这里应该是个本地接口和C应该是有关系了,到这块就不看了有兴趣的师傅可以继续往下看一看吧。

之后就是一层一层把C返回来就Ok了

可爱小尾巴~~~

我只是个基础很差 技术很菜 脚本小子里面的小菜鸡,文章里面有什么写的不对的地方,望师傅们多加指正,我肯定狂奔加小跑的学。这个类加载其实在Java反序列化中都是很常用的东西关于动态加载利用的CC链或者CB链还有一些通过自定义加载类打利用等等。年前争取在发几篇文章,前几年净瞎打实战了,好好学学这些基础,争取能看到师傅们的脚印。

# web安全 # java # 代码审计 # java反序列化 # 基础知识
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 potatosafe 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
potatosafe LV.4
这家伙太懒了,还未填写个人描述!
  • 19 文章数
  • 86 关注者
擅长捉弄的内存马同学:Valve内存马
2022-11-02
名侦探土豆:Fastjson反序列化漏洞-TemplateImpt链
2022-03-13
名侦探土豆:Fastjson反序列化漏洞-JdbcRowSetImpl链
2022-03-13
文章目录