技术社区
安全培训
技术社群
积分商城
先知平台
漏洞库
历史记录
清空历史记录
相关的动态
相关的文章
相关的用户
相关的圈子
相关的话题
注册
登录
Java反序列化CC1链子之国内国外版本总结
空城亡灵
WEB安全
584浏览 · 2025-04-10 08:29
返回文档
环境配置
漏洞存在在JDK8U71以下的JDK版本中
commons-collections-3.2.1源码
在pom.xml中添加
如图所示
JDK版本
使用的是JDK8u65
下载地址:
如图所示
CC1(国内版)
链子源头
按 Clrt + alt + B ,如图点击来到这里
在commons-collections-3.2.1源码中的 InvokerTransformer类继承了Transformer接口,我们进去来到这里看
可以看到这是一个很经典的反射调用执行方法,通过InvokerTransformer有参构造,然后调用Transform方法,从而可以构造任意命令执行。
代码演示
原理
代码构造:一一对应
最后有参构造的InvokerTransformer方法整理好之后再调用transform方法
因为input.getClass()的意思获取类,所以我们只需要在 transform方法中传递一个能够调用系统命令执行的类就可以了
运行之后可以看见成功弹出计算器
初步构造链
从而得出构造链:
向上寻找链子
我们只需要寻找谁调用transform方法,就可以知道下一条链子了
最终在这里可以看见 TransformedMap中的checkSetValue方法调用了
但是由于checkSetValue方法是收保护的类,所以我们不能直接调用这个方法
所以直接谁寻找调用checkSetValue方法即可
在这里可以看到调用方法,双击进去
来到最顶部可以发现AbstractInputCheckedMapDecorator是抽象类
返回关键方法查看可以setValue是公共方法,所以在这里我们可以进行利用。但是由于setValue哈需要parent参数,所以会用到上面那个方法的键值
链子构造
原理
由于第一次 transform 寻找调用的方法在 TransformedMap类中的checkSetValue方法
可以看见调用这个方法还需要 valueTransformer 参数
恰好 TransformedMap 类中的 decorate方法 刚好就构造了valueTransformercabs参数,所以我们需要调用TransformedMap类的decorate方法
从而刚好满足这三种条件,hashMap是为了满足decorateMap方法中的第一个参数。
所以当调用上一层链子调用checkSetValue方法的时候相当于
那是因为 TransformedMap.decorate的构造参数是 valueTransformer,我们使用了invokerTransformer放到参数中去,所以当 checkSetValue方法调用的时候就会变成 invokerTransformer.transform(value)
可控的value
查看调用checkSetValue方法,可以看见这里有一个 setValue,相当于设置value参数,我们可以将自己精心构造的自定义value放入进去就相当于,第一个链子的命令执行
可以看见MapEntry方法中有 parent参数
所以我们可以通过for函数进行设置键值
最后执行构造链代码,可以看见命令执行成功,弹出计算器
构造链拼接
最终链
继续按原来的套路寻找向上调用的方法
可以看见这个方法在readObject中,readObject有一个好处就是当执行反序列化的时候自动执行readObject方法
构造链
所以我们现在只需要构造AnnotationInvocationHandler类即可,最终执行序列化与反序列化,就能够任意命令执行。
原理
至于为什么要加载Target.class
可以看见readObject中有两个if判断,他会判断成员中是否有内容,可以看见Target类中有value
由于它是键名检测,所以前面的 hashMap中就构造好了 "value"
CC1最终exp代码
原理
从而构造原理我们写出以下EXP,但是可以发现少了任意命令执行的类,所以不可以执行成功
反射与Transformer[]
按Ctrl+Alt+B来到 ChainedTransformer方法中
●
我们可以看见这个ChainedTransformer方法可以整合 transformers,成为一个数组。
●
然后transformer会将数组中的 transformers全部会变成 iTransformers[i].transform(object)
●
这就是我们前面很熟悉的命令执行了
所以我们可以整理这个语句
在来到 ConstantTransformer构造方法中
可以看见这个也是很熟悉的
经过代码对比,很明显知道
所以我们可以构造代码为以下:
最终exp
从而构造最终的国内版本的CC1链EXP代码:
运行代码可以看见成功弹出计算器
CC1(LazyMap国外版)
可以看见国内版对比国外版从这里开始就不一样了
地址:
寻找LazyMap.get()
按原来的方法继续构造代码
可以看见能够弹出计算器
查看调用 transform方法的来源
最终我们在这里找到了
可以看见这个get方法执行了transfrom方法,但是我们需要factory参数
构造链代码
我们可以看到 LazyMap类中的 decorate构造方法有 factory参数
我们可以利用这个方法从而构造代码:
构造代码与原来的代码进行拼接:
运行代码可以看见计算器成功执行了
动态代理&AnnotationInvocationHandler类
AnnotationInvocationHandler类
我们来到AnnotationInvocationHandler类中invoke方法,可以看见这里调用了get方法,其中memberValues参数是可控的
Ctrl+左键点击 memberValues 可以看见来到 AnnotationInvocationHandler构造类的方法中
所以我们可以构造自己想要的 Map.class 类型放入 memberValues参数类型中,然后就可以执行想要的get方法了。
动态代理
在java中如果继承了 InvocationHandler类,就可以实现动态代理。我们可以利用动态代理来实现get方法的调用。
从而构造代码:
构造方法参数类型
就是参数对应就可以了
最后构造方法加载动态代理类
最终exp代码
从而构造最终exp代码
运行之后可以看见计算器成功弹出
总结
CC1的国内外半的前半链子一样,就后面不一样。一个是方法调用任意命令执行,一个是动态代理类调用方法任意命令执行。
2
人收藏
0
人喜欢
转载
分享
0
条评论
某人
表情
可输入
255
字
评论
发布投稿
热门文章
1
契约锁电子签章系统 pdfverifier 远程代码执行漏洞分析(补丁包逆向分析)
2
COFF文件解析 | CoffLdr
3
Java内存马篇——WebSocket内存马及GodZilla二开
4
从零掌握java内存马大全(基于LearnJavaMemshellFromZero复现重组)
5
突破网络限制,Merlin Agent助你轻松搭建跳板网络!
近期热点
一周
月份
季度
1
契约锁电子签章系统 pdfverifier 远程代码执行漏洞分析(补丁包逆向分析)
2
COFF文件解析 | CoffLdr
3
Java内存马篇——WebSocket内存马及GodZilla二开
4
从零掌握java内存马大全(基于LearnJavaMemshellFromZero复现重组)
5
突破网络限制,Merlin Agent助你轻松搭建跳板网络!
暂无相关信息
暂无相关信息
优秀作者
1
T0daySeeker
贡献值:41700
2
一天
贡献值:24800
3
Yale
贡献值:24000
4
1674701160110592
贡献值:21800
5
1174735059082055
贡献值:16000
6
手术刀
贡献值:14000
7
Loora1N
贡献值:13000
8
bkbqwq
贡献值:12800
9
lufei
贡献值:11000
10
xsran
贡献值:10600
目录
环境配置
commons-collections-3.2.1源码
JDK版本
CC1(国内版)
链子源头
代码演示
原理
初步构造链
向上寻找链子
链子构造
原理
可控的value
构造链拼接
最终链
构造链
原理
CC1最终exp代码
原理
反射与Transformer[]
最终exp
CC1(LazyMap国外版)
寻找LazyMap.get()
构造链代码
动态代理&AnnotationInvocationHandler类
AnnotationInvocationHandler类
动态代理
最终exp代码
总结
转载
标题
作者:
你好
http://www.a.com/asdsabdas
文章
转载
自
复制到剪贴板