关联漏洞
标题:
Apache ActiveMQ 代码问题漏洞
(CVE-2023-46604)
描述:Apache ActiveMQ是美国阿帕奇(Apache)基金会的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。 Apache ActiveMQ 5.15.16之前、5.16.7之前、5.17.6之前或5.18.3之前版本存在代码问题漏洞,该漏洞源于允许具有代理网络访问权限的远程攻击者通过操纵 OpenWire 协议中的序列化类类型来运行任意 shell 命令。
介绍
# CVE-2023-46604
## 01. Apache ActiveMQ & OpenWire
- ### 1) Apache ActiveMQ와 OpenWire 개요
ActiveMQ는 JMS를 지원하는 클라이언트를 포함하는 브로커, 자바 뿐만 아니라 다양한 언어를 이용하는 시스템 간 의 통신을 할 수 있게해준다. 또한 클러스터링 기능 및 DB 그리고 FileSystem을 통해 각 시스템간의 일관성 및 지속성을 유지 시켜주는
오픈 소스 메세징 그리고 통합 패턴 서버 입니다.
OpenWire는 Apache ActiveMQ에서 사용되는 이진 메시징 프로토콜 입니다. 브로커(ActiveMQ)와 클라이언트 간의 효율적인 데이터 전송을 위해 설계 되었습니다.
CVE-2023-46604는 ActiveMQ에서 OpenWire 프로토콜(Marshal과정에) 취약성은 Java 기반 OpenWire 브로커 또는 클라이언트에 대한 네트워크 액세스 권한이 있는 원격 공격자가 OpenWire 프로토콜에서 직렬화된 클래스 유형을 조작하여 임의의 셸 명령을 실행하여 클라이언트 또는 브로커(각각)가 클래스 경로에 있는 모든 클래스를 인스턴스화 하도록 할 수 있으며 APT 그룹 Andariel의 대표적으로 사용한 공격 방식 중 하나 입니다.
## 02. Apache ActiveMQ 5.17.3 환경의 OpenWire 프로토콜을 통한 취약점 분석
- ### 2.1 OpenWire 프로토콜을 통한 패킷 분석 및 공격 방식
CVE-2023-46604는 OpenWire 프로토콜을 통해 데이터를 주고받는 과정에서 XML 호출을 조작하거나 악성 데이터를 삽입하여 원격 명령을 실행하는 식으로 진행 됩니다. OpenWire 프로토콜은 기본적으로 데이터 직렬화 및 전송을 처리하는데, 취약점은 이 직렬화 과정에서 악의적인 클래스 유형이 허용되는 점을 악용합니다.
<p align="center"> <img src="https://github.com/user-attachments/assets/d35433d2-e99f-4b5a-a7b4-718d452fb3d4" alt="이미지 설명"> </p>
<p align="center">[그림] POC </p>
<p align="center"> <img src="https://github.com/user-attachments/assets/6dcfb779-306e-4f9e-995b-ab05955b11c2" alt="이미지 설명"> </p>
<p align="center">[그림] XML </p>
ActiveMQ 5.17.3 에서 OpenWire 프로토콜에 보내는 패킷의 분석을 통해 알아보도록 하겠습니다. 처음으로 패킷 분석전 패킷의 형태를 인지하고 들어가야 합니다.
```
패킷 Header
+----------------------------------------------------------------------------------+
| Packet Length | Command | Command Id | Command response required | CorrelationId |
|---------------|---------|------------|---------------------------|---------------|
| 00000066 | 1f | 00000000 | 00 | 00000000 |
+----------------------------------------------------------------------------------+
```
```
패킷 Body
+--------------------------------------------------------------------------------------+
| not-null | not-null | classname-size | classname | not-null | message-size | message |
|----------|----------|----------------|-----------|----------|--------------|---------|
| 01 | 01 | 0043 | ..... | 01 | 0012 | ..... |
+--------------------------------------------------------------------------------------+
```
```
OpenWire 패킷 Body 형식
[=If not-null is 1===========]
+----------+ [ +-------+----------------+ ]
| not-null | [ | size | encoded-string | ]
+----------+ [ +-------+----------------+ ]
| byte | [ | short | size octects | ]
+----------+ [ +-------+----------------+ ]
[============================]
```
<p align="center"> <img src="https://github.com/user-attachments/assets/091af47c-0207-4917-a059-fc5a0a514f28" alt="이미지 설명"> </p>
<p align="center">[그림 1] WireShark OpenWire 패킷 체크 </p>
[그림 1]을 보면 위에 설명한 패킷의 Header, Body 형식이 들어가있는 실제 Payload 입니다(편의를 위해 기존 POC방식 ClassPath 통한 호출이 아닌 FileSystem을 통한 호출). 해당 패킷 내용들이 어떤 작용을 하며 왜 이렇게 보내야 하는지를 코드 내에서 보다 상세히 알아 보겠습니다.
<p align="center"> <img src="https://github.com/user-attachments/assets/185a49f3-840e-46cb-982e-dcd70970001f" alt="이미지 설명"> </p>
<p align="center">[그림 2] 패킷 Header의 의미 </p>
```
패킷 Header 끊어서 파악
+----------------------------------------------------------------------------------+
| Packet Length | Command | Command Id | Command response required | CorrelationId |
|---------------|---------|------------|---------------------------|---------------|
| 00000066 | 1f | 00000000 | 00 | 00000000 |
+----------------------------------------------------------------------------------+
Packet Length : 00000066 / OpenWire 같은 프로토콜은 기본적으로 패킷을 길이를 명시.
Command : 1f / 는 ExecptionResponse(31)을 명시 하기 위한 설정 31은 16진수(hex)로 1f.
Command Id : 00000000 / 는 int 형태 4바이트 형태 임으로 16진수 표현시 00 00 00 00.
Command response required : 00 / 는 boolean 타입으로 True(01), False(00) 에서 False.
CorrelationId : Command Id와 같은 유형
```
[그림 2]는 위 패킷 헤더의 이해를 돕기 위해, 각 헤더 항목들의 형태와 지정된 코드에 대한 설명을 추가한 내용입니다. 이제 Header 알아 봤으니 Body 내용을 통해 어떻게 코드를 통과하는지 보겠습니다.
<p align="center"> <img src="https://github.com/user-attachments/assets/d718ab89-b2c4-4377-bf81-a78c2ec9dc05" alt="이미지 설명"> </p>
<p align="center">[그림 3] 패킷 Body의 의미 </p>
```
패킷 Body 내용 끊어서 파악
+--------------------------------------------------------------------------------------+
| not-null | not-null | classname-size | classname | not-null | message-size | message |
|----------|----------|----------------|-----------|----------|--------------|---------|
| 01 | 01 | 0043 | ..... | 01 | 0012 | ..... |
+--------------------------------------------------------------------------------------+
not-null (01) | / [그림 3]의 첫번째 함수에서 not-null pass
not-null (01) | classname-size (0043) | classname / [그림 3]의 두번째 함수에서 not-null pass, 세번째 함수에서 사이즈 체크 위한
not-null (01) | message-size (0012) | message / [그림 3]의 두번째 함수에서 not-null pass, 세번째 함수에서 사이즈 체크 위한
```
[그림 3]은 패킷의 Body에서 설정한 값들이 어떻게 작용하는지 보여주고 있습니다. 최종 적으로 [그림 4]를 통하여 직렬화 한 데이터를 통해 클래스 로드하고 인스턴스화 합니다.
<p align="center"> <img src="https://github.com/user-attachments/assets/1dd56cb1-04f6-4ff5-ab0d-046346f2d593" alt="이미지 설명"> </p>
<p align="center">[그림 4] createThrowable 를 통한 RCE 실행 </p>
<p align="center"> <img src="https://github.com/user-attachments/assets/ac957b48-95bf-4d86-b346-7cf7bd9c0c7c" alt="이미지 설명"> </p>
<p align="center">[그림 5] RCE 계산기 실행 예시 </p>
<p align="center"> <img src="https://github.com/user-attachments/assets/b48cb5c4-c855-41f9-a061-e4d4cc7d0223" alt="이미지 설명"> </p>
<p align="center">[그림 5] Git Diff (5.17.2 -> 5.17.6) </p>
<p align="center"> <img src="https://github.com/user-attachments/assets/0a5a487a-8378-4c54-8cf6-8bb722836af5" alt="이미지 설명"> </p>
<p align="center">[그림 5] validate Function </p>
## 03. 결론
다른 분석과 달리 해당 취약점에서 공격 패킷을 분석한 이유는 공격이 실제로 어떻게 실행되는지 이해 및 공부하기 위해서였습니다.
패킷의 구조와 흐름을 면밀히 살펴봄으로써, 공격자가 시스템을 침해하기 위해 사용하는 구체적인 방식과 그 동작 메커니즘을 명확히 파악할 수 있었습니다.
## 04. 참조
(nist) https://nvd.nist.gov/vuln/detail/cve-2023-46604
(POC) https://github.com/X1r0z/ActiveMQ-RCE/tree/main
(blog) https://attackerkb.com/topics/IHsgZDE3tS/cve-2023-46604/rapid7-analysis
文件快照
[4.0K] /data/pocs/af34d5a4c4d90302099356f2f194adf58062848b
└── [8.2K] README.md
0 directories, 1 file
备注
1. 建议优先通过来源进行访问。
2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。