
Analisi tecnica approfondita di CVE-2023-46604, una vulnerabilità RCE nel protocollo OpenWire di Apache ActiveMQ, inclusa la struttura dei pacchetti e il meccanismo di sfruttamento.
ActiveMQ è un broker che include client che supportano JMS e consente la comunicazione tra sistemi che utilizzano non solo Java ma anche vari linguaggi. Inoltre, tramite funzionalità di clustering, DB e FileSystem, mantiene coerenza e persistenza tra i sistemi ed è un server open source per la messaggistica e i pattern di integrazione.
OpenWire è un protocollo di messaggistica binario utilizzato in Apache ActiveMQ. È progettato per un trasferimento dati efficiente tra il broker (ActiveMQ) e il client.
CVE-2023-46604 è una vulnerabilità nel protocollo OpenWire (nel processo di Marshal) di ActiveMQ: un attaccante remoto con accesso di rete a un broker o client OpenWire basato su Java può manipolare i tipi di classe serializzati nel protocollo OpenWire per eseguire comandi shell arbitrari, inducendo il client o il broker (rispettivamente) a istanziare qualsiasi classe presente nel classpath. È una delle tecniche di attacco distintive del gruppo APT Andariel.
CVE-2023-46604 procede manipolando le chiamate XML o inserendo dati dannosi durante lo scambio di dati tramite il protocollo OpenWire, in modo da eseguire comandi remoti. Il protocollo OpenWire gestisce fondamentalmente la serializzazione e la trasmissione dei dati; la vulnerabilità sfrutta il fatto che, in questo processo di serializzazione, vengono consentiti tipi di classe dannosi.
[Figura] POC
[Figura] XML
패킷 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 | ]
+----------+ [ +-------+----------------+ ]
[============================]
[Figura 1] Controllo del pacchetto OpenWire in WireShark
[Figura 2] Significato dell'Header del pacchetto
패킷 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와 같은 유형
La [Figura 2] aggiunge una descrizione della forma di ciascuna voce dell'header e del codice specificato, per facilitare la comprensione dell'header del pacchetto sopra. Ora che abbiamo visto l'Header, vediamo come il contenuto del Body passa attraverso il codice.
[Figura 3] Significato del Body del pacchetto
패킷 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, 세번째 함수에서 사이즈 체크 위한
La [Figura 3] mostra come agiscono i valori impostati nel Body del pacchetto. Infine, tramite la [Figura 4], i dati serializzati vengono utilizzati per caricare e istanziare la classe.
[Figura 4] Esecuzione di RCE tramite createThrowable
[Figura 5] Esempio di esecuzione della calcolatrice tramite RCE
[Figura 5] Git Diff (5.17.2 -> 5.17.6)
[Figura 5] validate Function
A differenza di altre analisi, il motivo per cui abbiamo analizzato i pacchetti di attacco per questa vulnerabilità è stato capire e studiare come l'attacco viene effettivamente eseguito.
Esaminando attentamente la struttura e il flusso dei pacchetti, siamo riusciti a comprendere chiaramente le modalità specifiche e il meccanismo di funzionamento che l'attaccante utilizza per compromettere il sistema.