On a recent engagement I encountered a Websphere MQ installation. After some digging around I was able to read queues, alter messages etc. IBM says this about it in the manual

If any server-connection channel definitions exist that have the MCAUSER attribute set to blank, clients can use this channel definition to connect to the queue manager with access authority determined by the user ID supplied by the client. This might be a security exposure if the system on which the queue manager is running allows unauthorized network connections. The WebSphere MQ default server-connection channel (SYSTEM.DEF.SVRCONN) has the MCAUSER attribute set to blank. To prevent unauthorized access, update the MCAUSER attribute of the default definition with a user ID that has no access to WebSphere MQ objects.1

Bad enough, right? Not so much. On to Administrative privileges!
When connecting to a Websphere MQ instance there are a number of ‘secrets’ you need to know:

  • Queue Manager name
  • A valid channel
  • In some cases a valid user

Fortunately Websphere leaks the valid name if you dump the TCP traffic while trying to authenticate using an invalid Queue Manager name. The name is specified in the “Initial Data” packet, Wireshark parses the communication just fine.

The other secrets can be tried with some of the defaults.
Default channels:

  • SYSTEM.ADMIN.SVRCONN
  • SYSTEM.DEF.SVRCONN

Default admin users:

  • mqm
  • MUSR_MQADMIN

Websphere does what?

Reading the IBM documentation it turned out you can run OS-commands. The function is called services and probably has some very valid reason for being there. Let’s abuse it.

This is the script used to test a channel/user combination for permissions to create a service. If it doesn’t show you an unauthorized exception, you’re good to go. You could script up a service to get a shell or use the IBM MQExplorer GUI application to create the attack service. We’ll do the latter. It’s worth noting I sometimes got different results using the GUI to manually try channel/user combinations, there are a number of fields in the API that contain user information and the different libraries (Python and Java) have different behaviour with regards to MCAUSER. To make it work with Python you have to run it as the local user you want to impersonate just add a normal user with one of the default usernames, Java just supplies the configured MCAUSER.

Start here for the necessary libraries (or a testing environment). I also installed the MQ Explorer.

import CMQC
import pymqi
from CMQCFC import *

queue_manager = "QM"
channel = "SYSTEM.ADMIN.SVRCONN"
host = "192.168.10.5"
port = "1414"
conn_info = "%s(%s)" % (host, port)


qmgr = pymqi.connect(queue_manager, channel, conn_info)

pcf = pymqi.PCFExecute(qmgr)

pcf.MQCMD_PING_Q_MGR()


res = pcf.MQCMD_CREATE_SERVICE({
      CMQC.MQCA_SERVICE_NAME : "testsrv",
      CMQC.MQIA_SERVICE_TYPE : CMQC.MQSVC_TYPE_COMMAND,
      CMQC.MQIA_SERVICE_CONTROL : CMQC.MQSVC_CONTROL_MANUAL,
      MQIACF_REPLACE : MQRP_NO,
      CMQC.MQCA_SERVICE_STOP_ARGS : "",
      CMQC.MQCA_SERVICE_STOP_COMMAND : "",
      CMQC.MQCA_SERVICE_START_COMMAND : "",
      CMQC.MQCA_SERVICE_START_ARGS : "",
      CMQC.MQCA_STDERR_DESTINATION : "",
      CMQC.MQCA_STDOUT_DESTINATION : "",
                                })


print res

qmgr.disconnect()

Popping the shell

So you found a server with a channel you can connect to and a username (or absence thereof) allowing you administrative access. Using the GUI (MQ Explorer) I had some trouble inserting the normal commands you would try, an issue with escaping spaces perhaps. There is also the problem of seeing command output. If firewall rules allow, the best option is to host a reverse shell on a SMB share and just redirect stdout and stderr to that share aswell.

Service configuration

Mitigation

You can protect against these attacks just fine just read the IBM Manual :) Options range from implementing two-way SSL to implementing password backends. The defaults are insecure though as shown above.