* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the [hacktricks repo](https://github.com/carlospolop/hacktricks) and [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
</details>
## Basic information
IBM MQ is an IBM technology to manage message queues. As other **message broker** technologies, it is dedicated to receive, store, process and classify information between producers and consumers.
By default, **it exposes IBM MQ TCP port 1414**.
Sometimes, HTTP REST API can be exposed on port **9443**.
Metrics (Prometheus) could also be accessed from TCP port **9157**.
The IBM MQ TCP port 1414 can be used to manipulate messages, queues, channels, ... but **also to control the instance**.
IBM provides a large technical documentation available on [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq).
## Tools
A suggested tool for easy exploitation is **[punch-q](https://github.com/sensepost/punch-q)**, with Docker usage. The tool is actively using the Python library `pymqi`.
For a more manual approach, use the Python library **[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) are needed.
### Installing pymqi
**IBM MQ dependencies** needs to be installed and loaded:
1. Create an account (IBMid) on [https://login.ibm.com/](https://login.ibm.com/).
2. Download IBM MQ libraries from [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). For Linux x86_64 it is **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**.
6. Then, temporary add the `.so` files to LD: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, **before** running other tools using these dependencies.
Then, you can clone the project [**pymqi**](https://github.com/dsuch/pymqi): it contains interesting code snippets, constants, ... Or you can directly install the library with: `pip install pymqi`.
### Using punch-q
#### With Docker
Simply use: `sudo docker run --rm -ti leonjza/punch-q`.
#### Without Docker
Clone the project [**punch-q**](https://github.com/sensepost/punch-q) then follow the readme for installation (`pip install -r requirements.txt && python3 setup.py install`).
After, it can be used with `punch-q` command.
## Enumeration
You can try to enumerate the **queue manager name, the users, the channels and the queues** with **punch-q** or **pymqi**.
### Queue Manager
Sometimes, there is no protection against getting the Queue Manager name:
```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** is using an internal (modifiable) wordlist to find existing channels. Usage example:
"SYSTEM.AUTO.SVRCONN" might exist, but user was not authorised.
"SYSTEM.DEF.SVRCONN" might exist, but user was not authorised.
```
It happens that some IBM MQ instances accept **unauthenticated** MQ requests, so `--username / --password` is not needed. Of course, access rights can also vary.
As soon as we get one channel name (here: `DEV.ADMIN.SVRCONN`), we can enumerate all other channels.
**Do not hesitate to iterate on all identified queues.**
### Code execution
> Some details before continuing: IBM MQ can be controlled though multiple ways: MQSC, PCF, Control Command. Some general lists can be found in [IBM MQ documentation](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 what we are focused on to interact remotely with the instance. **punch-q** and furthermore **pymqi** are based on PCF interactions.
>
> You can find a list of PCF commands:
> * [From PCF documentation](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), and
> One interesting command is `MQCMD_CREATE_SERVICE` and its documentation is available [here](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms). It takes as argument a `StartCommand` pointing to a local program on the instance (example: `/bin/sh`).
>
> There is also a warning of the command in the docs: *"Attention: This command allows a user to run an arbitrary command with mqm authority. If granted rights to use this command, a malicious or careless user could define a service which damages your systems or data, for example, by deleting essential files."*
>
> *Note: always according to IBM MQ documentation (Administration Reference), there is also an HTTP endpoint at `/admin/action/qmgr/{qmgrName}/mqsc` to run the equivalent MQSC command for service creation (`DEFINE SERVICE`). This aspect is not covered yet here.*
The program '/bin/doesnotexist' is not available on the remote system.
Giving the service 0 second(s) to live...
Cleaning up service...
Done
```
**Be aware that the program launch is asynchronous. So you need a second item to leverage the exploit** ***(listener for reverse shell, file creation on different service, data exfiltration through network ...)***
**Example 2**
For easy reverse shell, **punch-q** proposes also two reverse shell payloads :
# 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()
```
If you cannot find the constant names, you can refer to the [IBM MQ documentation](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors).
> *Example for [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (Decimal = 73). It needs the parameter `MQCA_CLUSTER_NAME` (Decimal = 2029) which can be `*` (Doc: ):*