freeBuf
主站

分类

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

特色

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

点我创作

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

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

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

FreeBuf+小程序

FreeBuf+小程序

关于我学渗透的那档子事之Java反序列化-CC1链-1
2022-01-16 03:35:34

前言

上篇文章主要说一下CB链的利用流程,这次继续分享各位师傅都玩烂的CC1链,这个链子我之前看了一些分析文章,大部分都是分析yso的cc1链,我看部分文章还有CC1链的另一种利用方式,虽然关键的利用点都一样,但我的学习目的也是打基础,所以能多看就多看,CC1链在利用链里还是至关重要的,之后的链子其实也是不断拆解拼接。我这里是分成两篇文章来分析两种利用方式,话不多说,我们开始分析。

一、利用链流程

老规矩,画了一张流程图,供大家参考。如图所示,这里我将从下往上分为三部分来讲解利用链流程

Transformer接口->制作链式调用恶意方法
InvokerTransformer/任意调用
ConstantTransformer/获取对象
ChainedTransformer/封装链式
TransformedMap->套娃触发ChainedTransformer.transform
AnnotationInvocationHandler->readObject触发TransformedMap

二、Transformer接口

这里需要说Transformer三个实现类,InvokerTransformer、ConstantTransformer、ChainedTransformer。

我不太想脱离分析流程按照顺序讲解三个类的原理在拼接。我为了更好的梳理思路,我们进行potato链式讲解(自定义)。

我们首先来看一下Transformer接口。

1642262909_61e2f17dcef23c4f053be.png!small?1642262943327

1642262889_61e2f16967ec86d8abf5f.png!small?1642262922533

接口没什么特别的,做了个transform方法。我们看一下接口的实现类。这个InvokerTransformer就是我们这条利用链的触发点,我们进入这个类看一看。

1.InvokerTransformer

首先我们跟进transform方法,我们可以看到这个方法将传入的对象反射方法,然后执行方法,这就是个任意方法调用了。

1642263335_61e2f32795c3c6f6f03f2.png!small?1642263370871

我们看上图可以知道,transform可以进行任意方法调用,我们看一下iMethodName、iParamTypes、iArgs是怎么赋值的,我们跟进构造函数。

1642263800_61e2f4f8cc4f472c7957b.png!small?1642263832985

OK,参数全部可控,这样我们就可以进行直接写个任意方法执行了。

Runtime类分析

我想了想,还是说一嘴Runtime的问题,师傅们别嫌我啰嗦哈。

首先我们知道我们一般执行命令是通过Runtime.getRuntime().exec("command");执行命令的,而Runtime是一个单例模式,我们是没办法直接创建的,所以我们都是通过getRuntime去获取然后执行exec方法。

1642264649_61e2f8495254e4c043813.png!small?1642264682004所以我们这里想要实现InvokerTranformer,通过getRuntime获取就可以了。

1642264812_61e2f8eceb7b53a761383.png!small?1642264847621

我们知道Runtime是无法序列化的,但是InvokerTransformer可以任意执行方法,我们只需要将反射的反射通过InvokerTransformer的格式去调用就OK了,

1642266009_61e2fd9994d1b5298b42c.png!small?1642266043899

2.ChainedTransformer

我们根据上面InvokerTransformer可以看出,这个相当于InvokerTransformer一层一层的调用,也就是链式调用,所以这就引出了我们这里说的Transformer接口的第二个实现类ChainedTransformer,我们跟进去这个类看一看。

1642266462_61e2ff5e09a93bf27fc15.png!small?1642266494168

我们看到它写了个循环,应该也叫递归吧,他的transform就是一层一层的调用,然后我们在通过Runtime.class触发就可以了。我们接下来看一下它的构造函数。

chainedTransformer.transform(Runtime.class);

1642267026_61e301920e27a7c6502b2.png!small?16422670586431642267034_61e3019a67418ac3ef267.png!small?1642267066642

这里我们就明白了,我们只需要将需要执行的方法通过链式的形式写到Transformer里面就可以了,其实就是个链式调用。但是我们触发的话还需要传一个Runtime.class,当然你将传入transform(Runtime.classs)的链在放一个里面也行,还有更美观的一个方法,就是Transformer接口的第三个实现类ConstantTransformer。

3.ConstantTransformer

其实用这个实现类的目的就是将Runtime.class返回放到chainedTransformer的链子里面,其实这个不是利用链的关键。我们跟进这个类看一看吧

1642267894_61e304f64c025963014d2.png!small?1642267926598

1642267914_61e3050a830f9096266ce.png!small?1642267946720

可以这个实现类将我们传入的对象通过transform原封不动的返回了,这样我们就可以和InvokerTransformer一起封装到ChainTransformer链里面了。

至此为止我们Transformer接口分析结束,简单总结一下就是通过InvokerTransformer制作runtime类的反射,ConstantTransformer传入runtime.class制作链的触发,chainTransformer将链封装起来。

三、TransformedMap

我们现在已经封装好了利用的chainTransformer链子,接下来我们看看都谁调用了Transformer,我们定位到了TransformedMap方法。

1642268602_61e307ba42be6e48d2e86.png!small?1642268636642

我们跟进checkSetValue()方法,protected权限,我们进行跟进看看valueTransformer如何设置

1642268640_61e307e05e30d6b401c55.png!small?1642268672565

跟进TransformedMap()构造方法,protected权限,继续向上跟进

1642268677_61e30805797b4608a5ab5.png!small?1642268709688

我们可以看到decorate方法最后将valueTransformer传到下面,且参数可控。

1642268861_61e308bdb7829efcb6c01.png!small?1642268894122

根据上面的分析,我们得知valueTransformer可控,我们只需要通过调用decorate方法传入封装好的chainTransformer就ok了,我们回到刚才的checkSetValue()方法,看看都谁调用了checkSetValue()

1642269103_61e309aff364b19a3856e.png!small?1642269137234

跟进AbstractInputCheckedMapDecorator下面的静态类MapEntry的setValue()方法。我们可以看到parent为可控数据。通过传入的parent调用checkSetValue方法。1642269254_61e30a46e605180c632f2.png!small?1642269288050

这里我们需要注意一下,TransformedMap是继承于AbstractInputCheckedMapDecorator的,这里之后会用到。

1642272198_61e315c614e7d57258bd6.png!small?1642272231287

继续查看谁调用了setValue方法。最终定位到了AnnotationInvocationHandler的readobject方法。

1642269482_61e30b2a8c7b52349f37a.png!small?1642269517785

四、AnnotationInvocationHandler

上面我定位到了AnnotationInvocationHandler的readObject方法,我们跟进分析一下。

1642269710_61e30c0e0b4b7a370d5c6.png!small?1642269744574

我们可以看到readObject方法调用了setValue方法,setValue方法是通过memberValue调用的,通过memberValues.entrySet返回了映射,我们看看memberValues是怎么设置。

1642269846_61e30c96b2ae234f7e467.png!small?1642269879775

查看构造函数,可以看到我们其实是可以控制type、memberValues,memberValues是我们传入的可控Map,这下就明白了,但是这里我提示一个坑点,我们重新看一下readObject方法,

回到readObject,我们看代码可以知道他需要成员变量不为空,且这块你的键值需要对应你注释的参数,不然还是找不到。

1642269987_61e30d236025fddd07c31.png!small?1642270020837

1642270017_61e30d410a2336471b978.png!small?1642270049460

由于这个类是Default类,所以我们这块通过反射构造器传入参数,传一个有参注释和一个TransformedMap(也就是TransformedMap.decorate的chaintransformer链)

1642270323_61e30e73c111e76191781.png!small?1642270356962

接下来就清晰明了了,我们传入的TransformedMap触发了父类AbstractInputCheckedMapDecorator的setValue再触发了TransformedMap的checkSetValue,最终触发了ChainedTransformer.transform,我们跟着走一遍流程

五、断点调试利用链

首先我们传入一个有参注释和一个TransformedMap(也就是TransformedMap.decorate的chaintransformer链)

1642273096_61e319487acd9f0b51a61.png!small?1642273130206

跳转到TransformedMap的父类AbstractInputCheckedMapDecorator的setValue,触发checkSetValue1642273117_61e3195d3b8640c091176.png!small?1642273151283

接着跳转到了TransformedMap的checkSetValue,触发transform

1642273192_61e319a81e87041e52561.png!small?1642273226164

继续向下,跳转到了ChainedTransformer的transform

1642273265_61e319f1cee8c6d23857c.png!small?1642273299369

开始递归InvokerTransformer,最终触发Runtime.getRuntime().exec(command)

1642273365_61e31a55006ae7849eb8f.png!small?1642273400189

1642273404_61e31a7c643ad5247cb69.png!small?1642273440138

可爱小尾巴~~~

我只是个基础很差 技术很菜 脚本小子里面的小菜鸡,文章里面有什么写的不对的地方,望师傅们多加指正,我肯定狂奔加小跑的学。

# web安全 # 代码审计
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录