
Analyse technique approfondie de CVE-2023-46604, une vulnérabilité RCE dans le protocole OpenWire d'Apache ActiveMQ, incluant la décomposition de la structure des paquets et le mécanisme d'exploitation.
ActiveMQ는 JMS를 지원하는 클라이언트를 포함하는 브로커, 자바 뿐만 아니라 다양한 언어를 이용하는 시스템 간 의 통신을 할 수 있게해준다. 또한 클러스터링 기능 및 DB 그리고 FileSystem을 통해 각 시스템간의 일관성 및 지속성을 유지 시켜주는 오픈 소스 메세징 그리고 통합 패턴 서버 입니다. 가. OpenWire는 Apache ActiveMQ에서 사용되는 이진 메시징 프로토콜 입니다. 브로커(ActiveMQ)와 클라이언트 간의 효율적인 데이터 전송을 위해 설계 되었습니다.
CVE-2023-46604는 ActiveMQ에서 OpenWire 프로토콜(Marshal과정에) 취약성은 Java 기반 OpenWire 브로커 또는 클라이언트에 대한 네트워크 액세스 권한이 있는 원격 공격자가 OpenWire 프로토콜에서 직렬화된 클래스 유형을 조작하여 임의의 셸 명령을 실행하여 클라이언트 또는 브로커(각각)가 클래스 경로에 있는 모든 클래스를 인스턴스화 하도록 할 수 있으며 APT 그룹 Andariel의 대표적으로 사용한 공격 방식 중 하나 입니다.
ActiveMQ est un serveur de messagerie open source et de modèles d'intégration qui prend en charge les clients JMS, permettant la communication entre des systèmes utilisant non seulement Java mais aussi divers langages. Il assure également la cohérence et la persistance entre les systèmes via les fonctionnalités de clustering, la base de données et le système de fichiers.
OpenWire est un protocole de messagerie binaire utilisé par Apache ActiveMQ. Il est conçu pour un transfert de données efficace entre le courtier (ActiveMQ) et les clients.
CVE-2023-46604 est une vulnérabilité dans le protocole OpenWire (lors du marshalling) dans ActiveMQ. Un attaquant distant disposant d'un accès réseau à un courtier ou un client OpenWire basé sur Java peut manipuler les types de classes sérialisées dans le protocole OpenWire pour exécuter des commandes shell arbitraires, permettant au client ou au courtier (respectivement) d'instancier n'importe quelle classe se trouvant sur le classpath. C'est l'une des méthodes d'attaque couramment utilisées par le groupe APT Andariel.
CVE-2023-46604는 OpenWire 프로토콜을 통해 데이터를 주고받는 과정에서 XML 호출을 조작하거나 악성 데이터를 삽입하여 원격 명령을 실행하는 식으로 진행 됩니다. OpenWire 프로토콜은 기본적으로 데이터 직렬화 및 전송을 처리하는데, 취약점은 이 직렬화 과정에서 악의적인 클래스 유형이 허용되는 점을 악용합니다.
[Figure] POC
[Figure] XML
Nous allons examiner l'analyse des paquets envoyés via le protocole OpenWire dans ActiveMQ 5.17.3. Tout d'abord, il est nécessaire de connaître la structure du paquet avant l'analyse.패킷 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 | ..... |
+--------------------------------------------------------------------------------------+
패킷 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와 같은 유형
[Figure 2] ajoute une explication sur la forme de chaque élément d'en-tête et le code spécifié pour faciliter la compréhension de l'en-tête du paquet ci-dessus. Maintenant que nous avons examiné l'en-tête, voyons comment le corps traverse le code.
[Figure 3] Signification du corps du paquet
패킷 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, 세번째 함수에서 사이즈 체크 위한
[Figure 3] montre comment les valeurs définies dans le corps du paquet agissent. Finalement, via [Figure 4], les données sérialisées chargent et instancient la classe.
[Figure 4] Exécution de RCE via createThrowable
[Figure 5] Exemple d'exécution de la calculatrice RCE
[Figure 5] Git Diff (5.17.2 -> 5.17.6)
[Figure 5] Fonction validate
다른 분석과 달리 해당 취약점에서 공격 패킷을 분석한 이유는 공격이 실제로 어떻게 실행되는지 이해 및 공부하기 위해서였습니다.
패킷의 구조와 흐름을 면밀히 살펴봄으로써, 공격자가 시스템을 침해하기 위해 사용하는 구체적인 방식과 그 동작 메커니즘을 명확히 파악할 수 있었습니다.
Contrairement à d'autres analyses, la raison pour laquelle nous avons analysé les paquets d'attaque dans cette vulnérabilité était de comprendre et d'étudier comment l'attaque est réellement exécutée.
En examinant attentivement la structure et le flux des paquets, nous avons pu clairement comprendre la méthode spécifique utilisée par l'attaquant pour compromettre le système ainsi que son mécanisme de fonctionnement.
(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
(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
OpenWire 패킷 Body 형식
[=If not-null is 1===========]
+----------+ [ +-------+----------------+ ]
| not-null | [ | size | encoded-string | ]
+----------+ [ +-------+----------------+ ]
| byte | [ | short | size octects | ]
+----------+ [ +-------+----------------+ ]
[============================]
[Figure 1] Vérification du paquet OpenWire dans Wireshark
[Figure 2] Signification de l'en-tête du paquet