1414 - Pentesting IBM MQ
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 des informations entre les producteurs et les consommateurs.
Par défaut, il expose le port TCP IBM MQ 1414. Parfois, une API REST HTTP peut être exposée sur le port 9443. Les métriques (Prometheus) peuvent également être consultées à partir du port TCP 9157.
Le port TCP IBM MQ 1414 peut être utilisé pour manipuler des messages, des files d'attente, des canaux, ... mais aussi pour contrôler l'instance.
IBM fournit une vaste 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 l'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, il s'agit de 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.sh
pour accepter les termes de licence.
Si vous êtes sous Kali Linux, modifiez le fichier
mqlicense.sh
: supprimez/commentez les lignes suivantes (entre les lignes 105-110) :
Installez ces packages:
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
Il suffit d'utiliser: 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
).
Ensuite, il peut être utilisé avec la commande punch-q
.
Énumération
Vous pouvez essayer d'énumérer le nom du gestionnaire de file d'attente, les utilisateurs, les canaux et les files d'attente avec punch-q ou pymqi.
Gestionnaire de file d'attente
Parfois, il n'y a aucune protection contre l'obtention du nom du gestionnaire de file d'attente:
Canaux
punch-q utilise une liste de mots internes (modifiable) pour trouver des canaux existants. Exemple d'utilisation :
Il arrive 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:
... Mais punch-q intègre également cette partie (avec plus d'informations!). Il peut être lancé avec:
Files d'attente
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 :
Exploit
Extraire
Vous pouvez cibler des files d'attente/canaux pour renifler / extraire des messages d'eux (opération non destructive). Exemples:
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 commandes programmables) est ce sur quoi nous nous concentrons pour interagir à distance avec l'instance. punch-q et en outre pymqi sont basés sur des interactions PCF.
Vous pouvez trouver une liste des commandes PCF :
Une commande intéressante est
MQCMD_CREATE_SERVICE
et sa documentation est disponible ici. Elle prend comme argument uneStartCommand
pointant vers un programme local sur l'instance (exemple :/bin/sh
).Il y a aussi un avertissement de 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 négligent pourrait définir un service qui endommage vos systèmes ou vos 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}/mqsc
pour exécuter la commande MQSC équivalente à 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
Dans les journaux d'IBM MQ, vous pouvez lire que la commande a été exécutée avec succès :
Vous pouvez également énumérer les programmes existants sur la machine (ici /bin/doesnotexist
... n'existe pas) :
Soyez conscient que le lancement du programme est asynchrone. Vous avez donc besoin d'un deuxième élément pour exploiter la faille (écouteur pour shell inversé, création de fichier sur un service différent, exfiltration de données à travers le réseau ...)
Exemple 2
Pour un shell inversé facile, punch-q propose également deux charges utiles de shell inversé :
Une avec bash
Une avec perl
Bien sûr, vous pouvez en créer une personnalisée avec la commande execute
.
Pour bash :
Pour Perl :
PCF personnalisé
Vous pouvez consulter la documentation d'IBM MQ et utiliser directement la bibliothèque python pymqi pour tester une commande PCF spécifique non implémentée dans punch-q.
Exemple :
Si vous ne trouvez pas les noms des constantes, 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: ):
Environnement de test
Si vous souhaitez tester le comportement et les exploits d'IBM MQ, vous pouvez mettre en place un environnement local basé sur Docker :
Avoir un compte sur ibm.com et cloud.ibm.com.
Créer un IBM MQ conteneurisé avec :
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 file 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 :
La vieille version des images Docker IBM MQ se trouve à l'adresse : https://hub.docker.com/r/ibmcom/mq/.
Références
Last updated