
Cacti 1.2.22 認証なしコマンドインジェクション
| フィールド | 詳細 |
|---|
| 製品 | Cacti |
| 影響を受けるバージョン | 1.2.22 |
| 脆弱性 | 認証なしOSコマンドインジェクション |
| CVE | CVE-2022-46169 |
| CWE | CWE-77 — コマンドインジェクション |
| 深刻度 | Critical |
| CVSS v3.1 | 9.8 |
| 攻撃ベクトル | ネットワーク |
| 認証 | 不要 |
| ユーザー操作 | 不要 |
| 影響 | 機密性 / 完全性 / 可用性 |
| 修正バージョン | 1.2.23 |
| 脆弱なコンポーネント | remote_agent.php |
| 追加コンポーネント | lib/functions.php |
| 主な脆弱なアクション | polldata |
公開されているCVSSベクターは以下の通りです:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
公式アドバイザリはこれを 9.8 Critical と評価しています。(GitHub)
実際には 2つのバグが連鎖しています。
ステージ1 — 認可バイパス
Cactiの remote_agent.php は通常の認証なしでリクエストを受け付けますが、リクエスト元が認可されたポーラーであるかどうかを判定しようとします。
認可フローは実質的に次のように動作します:
HTTPリクエスト
│
▼
remote_agent.php
│
▼
remote_client_authorized()
│
▼
get_client_addr()
│
▼
gethostbyaddr()
│
▼
pollerテーブルのホスト名比較
問題は get_client_addr() です。
1.2.22では、転送されたクライアントIPヘッダーを含む、HTTP由来の多数のサーバー変数を検査します。アドバイザリは、攻撃者が制御する HTTP_* 値がこの関数が返すIPに影響を与える可能性があると説明しています。(GitHub)
つまり、アプリケーションは次のように信じ込まされる可能性があります:
攻撃者
↓
"私のIPはCactiサーバーです"
↓
gethostbyaddr()
↓
Cactiサーバーのホスト名
↓
pollerテーブルと一致
↓
認可済み
したがって、攻撃者は正当なCactiアカウントを必要としません。
認可チェックをバイパスした後、注目すべきエンドポイント機能は polldata アクションです。
関連する実行パスはおおよそ次のとおりです:
remote_agent.php
│
▼
polldata
│
▼
poll_for_data()
│
├── host_id
├── local_data_ids
└── poller_id
│
▼
poller_item ルックアップ
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
proc_open()
│
▼
OSコマンド実行
重要なミスは poller_id の処理です。
アプリケーションはこれを次の方法で取得します:
get_nfilter_request_var()
整数であることを強制するのではなく。
その攻撃者が制御する値は、最終的にPHPの proc_open() に渡されるコマンドの一部になります。公式アドバイザリはこれをコマンドインジェクションのプリミティブとして明確に特定しています。(GitHub)
概念的には:
攻撃者が制御する入力
↓
poller_id
↓
文字列連結
↓
proc_open()
↓
オペレーティングシステムコマンド
これがこの脆弱性の重要な部分です。
PoC分析にとって興味深い点は、どちらのバグ単独では全体像にならないということです。
これは脆弱性チェーンです:
┌──────────────────────────┐
│ 認証なしの攻撃者 │
└────────────┬─────────────┘
│
▼
remote_agent.php
│
▼
クライアントIPロジックによる
認可バイパス
│
▼
polldata
│
▼
poller_item ルックアップ
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
攻撃者の入力
→ poller_id
│
▼
proc_open()
│
▼
コマンド実行
│
▼
RCE
これはあなたのレポートで非常に重要な区別です:
CVE-2022-46169 は単に「remote_agent.php の悪いパラメータ」ではありません。認可バイパス + コマンドインジェクションの連鎖的な脆弱性です。
公式アドバイザリは、脆弱な実行条件として、アクションが POLLER_ACTION_SCRIPT_PHP である poller_item が必要であることを確認しています。(GitHub)
これは重要な分析上の詳細であるため、PoCには明示的に文書化する必要があります。
ターゲットには、次のように構成された適切な poller_item が必要です:
POLLER_ACTION_SCRIPT_PHP
Cactiのアドバイザリは、Device - Uptime や Device - Polling Time などの定義済みテンプレートがこれらのエントリを作成できるため、これは本番環境では一般的であると述べています。(GitHub)
したがって、次のように書かないでください:
「すべてのCacti 1.2.22インストールが自動的に悪用可能です。」
より技術的に正確な記述は次のとおりです:
Cacti 1.2.22 は脆弱であり、コマンド実行の成功は適切な
poller_item設定の存在に依存します。
host_id と local_data_id が重要な理由poll_for_data() は指定された poller_id を単純に実行するわけではありません。
まず、次の値に対応する poller_item をクエリします:
host_id
local_data_id
次に、結果のアイテムのアクションを調べます。
脆弱な条件は実質的に次のとおりです:
host_id
+
local_data_id
↓
poller_item
↓
action == POLLER_ACTION_SCRIPT_PHP
↓
脆弱な実行パス
元のアドバイザリは、関連するエントリがアプリケーションのデータベースに存在するためこれらの識別子を発見でき、本番環境には適切なエントリが存在する可能性が高いと述べています。(GitHub)
公開PoC では、これを隠すのではなく明示的に実証することをお勧めします。
公開するものについては、読者に武器化されたリバースシェルペイロードを提供せずにコマンド実行を実証するPoCにすることをお勧めします。
たとえば、デモを次のように構成します:
1. 隔離されたVMにCacti 1.2.22をデプロイする
2. POLLER_ACTION_SCRIPT_PHP を使用して poller_item を構成する
3. remote_agent.php に到達可能であることを確認する
4. 認可判定が影響を受けることを実証する
5. polldata 実行パスに到達する
6. 無害なコマンド実行マーカーを使用する
7. 結果のアプリケーション/ログの証拠を取得する
8. 1.2.23 にアップグレードする
9. テストを繰り返す
10. 脆弱性が悪用できなくなったことを実証する
これにより、レポートを既製のインターネットRCE兵器に変えることなく、正当な脆弱性のデモが提供されます。
脆弱なコードを3つの領域に分けることができます。
remote_agent.phpリモートエージェント機能を公開し、要求されたアクションをディスパッチする役割を担います。
remote_agent.php
│
└── action = polldata
│
▼
poll_for_data()
lib/functions.phpget_client_addr() を含みます。
問題のある設計は、リクエスト元の実際のネットワークアドレスを決定する際にHTTP由来の値を信頼することです。
公式アドバイザリは、実際のリモートアドレスにフォールバックする前に検査される複数のHTTP関連変数をリストしています。(GitHub)
proc_open()最終的な危険なシンクは、proc_open() を通じて実行されるPHPコマンドの構築です。
アドバイザリは脆弱なフローを次のように特定しています:
poller_id
↓
get_nfilter_request_var()
↓
コマンド構築
↓
proc_open()
(GitHub)
Cactiのアドバイザリは、2つの重要な修正変更を特定しています。
まず、poller_id は整数として扱われるべきです:
get_nfilter_request_var()
↓
get_filter_request_var()
次に、値はコマンドに組み込まれる前にシェルエスケープされるべきです:
escapeshellarg($poller_id)
アドバイザリは両方の対策を具体的に推奨しています。(GitHub)
認可側も、攻撃者が認可に使用されるクライアントIPを恣意的に操作できないようにする必要があります。(GitHub)
Cacti 1.2.22
│
├── 脆弱
├── 認可バイパス
├── コマンドインジェクション
└── 認証なしRCEの可能性
Cacti 1.2.23
│
└── CVE-2022-46169 パッチ適用済み
ベンダーのアドバイザリは、1.2.22 が影響を受け、1.2.23 がパッチ適用済みの1.2.xリリースであるとリストしています。(GitHub)
Amazonのセキュリティアドバイザリは、この問題を認証なしの攻撃者が任意のコマンドを実行できるものとして独立して説明し、9.8のCVSSスコアを与えています。(AWS Training and Certification)
次のようなものを使用します:
CVE-2022-46169 — Cacti 1.2.22 における認証なしコマンドインジェクション / RCE
またはより技術的に:
CVE-2022-46169: Cacti 1.2.22 リモートエージェント認可バイパスおよびコマンドインジェクションチェーンの分析
そして、脆弱性の要約は次のように記述できます:
Cacti 1.2.22 には、リモートエージェント機能に重大な脆弱性チェーンが含まれています。攻撃者はクライアントアドレス判定ロジックを操作して、リモートエージェントの認可チェックをバイパスできます。
polldata機能に到達すると、poller_idパラメータの検証不足により、攻撃者が制御するデータがproc_open()を通じて実行されるコマンドに到達する可能性があります。POLLER_ACTION_SCRIPT_PHPポーラーアイテムを含む構成では、これにより認証なしのリモートコマンド実行が発生する可能性があります。この問題は Cacti 1.2.23 で修正されました。 (GitHub)
調査に関する重要な修正: これを CVE-2023-39362 と混同しないでください。その後のCacti RCEは 1.2.24 に影響し、1.2.25で修正されたため、1.2.22のPoCに必要な脆弱性ではありません。(NVD)