qtc-de / remote-method-guesser

Java RMI Vulnerability Scanner
GNU General Public License v3.0
828 stars 106 forks source link

Bad certificate #47

Closed dinosn closed 1 year ago

dinosn commented 1 year ago

Hello,

One more issue if there is time to resolve :)

The request seem to failing with an alert for bad_certificate

root@system:~/tools/rmi/remote-method-guesser# java2 -jar rmg-4.4.0-jar-with-dependencies.jar guess  system 1099
[+] Reading method candidates from internal wordlist rmg.txt
[+]     752 methods were successfully parsed.
[+] Reading method candidates from internal wordlist rmiscout.txt
[+]     2550 methods were successfully parsed.
[+]
[+] Starting Method Guessing on 3281 method signature(s).
[+]
[+]     MethodGuesser is running:
[+]         --------------------------------
[-]         Caught unexpected java.rmi.ConnectIOException during method call.
[-]         Please report this to improve rmg :)
[-]         StackTrace:
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:343)
    at de.qtc.rmg.networking.RMIEndpoint.guessingCall(RMIEndpoint.java:153)
    at de.qtc.rmg.operations.RemoteObjectClient.guessingCall(RemoteObjectClient.java:312)
    at de.qtc.rmg.operations.MethodGuesser$GuessingWorker.run(MethodGuesser.java:335)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
    at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
    at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:152)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1392)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1300)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:435)
    at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:813)
    at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
    at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1175)
    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
[-]         Cannot continue from here.
[-]         Caught unexpected java.rmi.ConnectIOException during method call.
[-]         Please report this to improve rmg :)
[-]         StackTrace:
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:343)
    at de.qtc.rmg.networking.RMIEndpoint.guessingCall(RMIEndpoint.java:153)
    at de.qtc.rmg.operations.RemoteObjectClient.guessingCall(RemoteObjectClient.java:312)
    at de.qtc.rmg.operations.MethodGuesser$GuessingWorker.run(MethodGuesser.java:335)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
    at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
    at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:152)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1392)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1300)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:435)
    at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:813)
    at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
    at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1175)
    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
[-]         Cannot continue from here.
[-]         Caught unexpected java.rmi.ConnectIOException during method call.
[-]         Caught unexpected java.rmi.ConnectIOException during method call.
[-]         Please report this to improve rmg :)
[-]         Please report this to improve rmg :)
[-]         StackTrace:
[-]         StackTrace:
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:343)
    at de.qtc.rmg.networking.RMIEndpoint.guessingCall(RMIEndpoint.java:153)
    at de.qtc.rmg.operations.RemoteObjectClient.guessingCall(RemoteObjectClient.java:312)
    at de.qtc.rmg.operations.MethodGuesser$GuessingWorker.run(MethodGuesser.java:335)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
    at sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
    at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
    at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:152)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1392)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1300)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:435)
    at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:813)
    at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
    at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1175)
    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
[-]         Cannot continue from here.
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
    javax.net.ssl.SSLException: readHandshakeRecord
    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:343)
    at de.qtc.rmg.networking.RMIEndpoint.guessingCall(RMIEndpoint.java:153)
    at de.qtc.rmg.operations.RemoteObjectClient.guessingCall(RemoteObjectClient.java:312)
    at de.qtc.rmg.operations.MethodGuesser$GuessingWorker.run(MethodGuesser.java:335)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: javax.net.ssl.SSLException: readHandshakeRecord
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1309)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:435)
    at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:813)
    at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
    at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1175)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)

Enum is able to retrieve information,

root@system:~/tools/rmi/remote-method-guesser# java2 -jar rmg-4.3.1-jar-with-dependencies.jar enum system 1099 
[+] RMI registry bound names:
[+]
[+]     - HPDM Server RMI
[+]         --> com.hp.hpdm.interf.ServiceInterf (unknown class)
[+]             Endpoint: system:40002  TLS: yes  ObjID: [-52a5d3ef:18782b753bf:-7fff, 2349307879934226592]
[+]
[+] RMI server codebase enumeration:
[+]
[+]     - The remote server does not expose any codebases.
[+]
[+] RMI server String unmarshalling enumeration:
[+]
[+]     - Server complained that object cannot be casted to java.lang.String.
[+]       --> The type java.lang.String is unmarshalled via readString().
[+]       Configuration Status: Current Default
[+]
[+] RMI server useCodebaseOnly enumeration:
[+]
[+]     - RMI registry uses readString() for unmarshalling java.lang.String.
[+]       This prevents useCodebaseOnly enumeration from remote.
[+]
[+] RMI registry localhost bypass enumeration (CVE-2019-2684):
[+]
[+]     - Registry rejected unbind call cause it was not send from localhost.
[+]       Vulnerability Status: Non Vulnerable
[+]
[+] RMI Security Manager enumeration:
[+]
[+]     - Caught Exception containing 'no security manager' during RMI call.
[+]       --> The server does not use a Security Manager.
[+]       Configuration Status: Current Default
[+]
[+] RMI server JEP290 enumeration:
[+]
[+]     - DGC rejected deserialization of java.util.HashMap (JEP290 is installed).
[+]       Vulnerability Status: Non Vulnerable
[+]
[+] RMI registry JEP290 bypass enumeration:
[+]
[+]     - RMI registry uses readString() for unmarshalling java.lang.String.
[+]       This prevents JEP 290 bypass enumeration from remote.
[+]
[+] RMI ActivationSystem enumeration:
[+]
[+]     - Caught NoSuchObjectException during activate call (activator not present).
[+]       Configuration Status: Current Default

Thank you for the great work!

Regards, Nicolas

qtc-de commented 1 year ago

Hi Nicolas,

thanks for reporting :+1:

Have you any further information that could clarify why the certificate is bad? As far as I can tell, the error shows up when rmg attempts to connect to the actual RMI endpoint. The registry itself is not TLS protected (this is the reason why the general enumeration works without any problems). However, the RMI endpoint bound to the registry is, as one can see from the following output:

[+]     - HPDM Server RMI
[+]         --> com.hp.hpdm.interf.ServiceInterf (unknown class)
[+]             Endpoint: system:40002  TLS: yes  ObjID: [-52a5d3ef:18782b753bf:-7fff, 2349307879934226592]

Unfortunately, the provided stack trace gives no indicator why the TLS certificate was considered bad. The output of something like openssl s_client -connect system 40002 could help to clarify this.

rmg generally treats all TLS certificates as trusted, but a similar issue was also reported for beanshooter some time ago. In this issue, the error message was more clear an indicated that the certificate algorithm was no longer supported. I expect a similar reason for your issue. Looking at the SSLTransport.decode method that throws the exception, one finds statements like the following:

      } catch (UnsupportedOperationException unsoe) {         // SSLv2Hello
          // Code to deliver SSLv2 error message for SSL/TLS connections.
          if (!context.sslContext.isDTLS()) {
              context.outputRecord.encodeV2NoCipher();
              if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
                  SSLLogger.finest("may be talking to SSLv2");
              }
          }

          throw context.fatal(Alert.UNEXPECTED_MESSAGE, unsoe);

So it is likely that your exception is also raised because the certificate or other TLS parameters do not match your minimal required policies. However, without knowing the certificate details, it is hard to tell :shrug:

Best, Tobias

dinosn commented 1 year ago

Hi,

Thank you for the detailed response. I will try to get access to the system to check the certificate. Regarding the minimal required policies, these are obtained from the java default setup, I haven't specified a client.policy, and on java version I'm using.

openjdk version "1.8.0_322"
OpenJDK Runtime Environment (build 1.8.0_322-b06)
OpenJDK 64-Bit Server VM (build 25.322-b06, mixed mode)

If you have a suggestion for a better configuration setup please let me know.

Regards, Nicolas

qtc-de commented 1 year ago

Hey Nicolas,

did you manage to get access to the system again?

Concerning your client policy I have no suggestions for a "better" setup, but sometimes one need to make things worse to get the job done. I often come into this situation when I'm trying to access old TLS servers. Modern openssl versions do not support their outdated crypto settings and one needs to enable them within /etc/ssl/openssl.conf file. I would not recommend to configure outdated and insecure settings by default, but sometimes one has to downgrade. In the context of Java, I did not encountered the problem yet, so I have no experience which settings to adjust :shrug:

dinosn commented 1 year ago

Hi Tobias,

Thank you for your response! I didn't had the chance to get access to that system again, I will close the ticket for now and if I get a similar result in another environment I'll make a new comment. Take care!

Regards, Nicolas