Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2023-46604 PoC — Apache ActiveMQ, Apache ActiveMQ Legacy OpenWire Module: Unbounded deserialization causes ActiveMQ to be vulnerable to a

Source
Associated Vulnerability
Title:Apache ActiveMQ, Apache ActiveMQ Legacy OpenWire Module: Unbounded deserialization causes ActiveMQ to be vulnerable to a remote code execution (RCE) attack (CVE-2023-46604)
Description:The Java OpenWire protocol marshaller is vulnerable to Remote Code Execution. This vulnerability may allow a remote attacker with network access to either a Java-based OpenWire broker or client to run arbitrary shell commands by manipulating serialized class types in the OpenWire protocol to cause either the client or the broker (respectively) to instantiate any class on the classpath. Users are recommended to upgrade both brokers and clients to version 5.15.16, 5.16.7, 5.17.6, or 5.18.3 which fixes this issue.
Readme
# 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  


 
  
File Snapshot

[4.0K] /data/pocs/af34d5a4c4d90302099356f2f194adf58062848b └── [8.2K] README.md 0 directories, 1 file
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →