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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2024-42327 — CVE-2024-42327 の解説 | Kitploit
ツール/GitHubGitHub/igorbf495/cve-2024-42327
特権昇格偵察脆弱性分析エクスプロイトウェブアプリケーション悪用ポストエクスプロイトCTFペネトレーションテスト学習と教育ラボと実践
GitHubigorbf495/cve-2024-42327

CVE-2024-42327

151年前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2024-42327 の解説

リポジトリを見る

CVE-2024-42327 zabbix脆弱性のwriteup

対象: 10.129.231.176

情報: 対象はzabbixサーバーであることが分かっている。zabbixにログインするための標準ユーザーアカウントを受け取った: ユーザー matthew、パスワード 96qzn0h2e1k3。このアカウントは標準ユーザーであり、追加のグループや権限はない。

いつものように、列挙から開始する。nmapを使ってポートスキャンを行う。

image

nmapの出力から、標準のSSHポートとApache2も標準ポートで動作していることがわかる。また、ポート10051と10050でzabbixのサービスが動作している。

ブラウザのURLにIPアドレスを入力し、標準のHTTPポート(ポート80)でzabbixにアクセスする。

image

これがzabbixのログイン画面だ。受け取ったユーザーでログインする。

image

image

フッターでzabbixのバージョンを見つけた:

image

馬鹿の親玉(Google)を使って、このzabbixバージョンに既存のCVEがないか調べた。

image

かなりの調査時間の後、このバージョンがCVE-2024-42327(データベースからデータを取得し権限昇格するためのSQLインジェクションの悪用)とCVE-2024-36467(アクセス制御の欠如を悪用してユーザーのロールをスーパーユーザーに変更可能)に対して脆弱であることがわかった。

https://nvd.nist.gov/vuln/detail/CVE-2024-36467

https://nvd.nist.gov/vuln/detail/CVE-2024-42327

zabbixのドキュメントには、APIを呼び出すためのHTTPリクエストの方法が記載されている。

image

https://www.zabbix.com/documentation/current/en/manual/api

ドキュメントに従って、appinfo.versionを呼び出すリクエストを送信した。

image

以下の結果が返ってきた:

{"jsonrpc":"2.0","result":"7.0.0","id":1}

次のテストのために、このリクエストのパラメータをいくつか変更して再送信した。

image

methodをappinfo.versionからuser.loginに変更し、usernameとpasswordのパラメータを追加した。これもzabbixのドキュメントに記載されている。

image

トークンが返ってきた:

{"jsonrpc":"2.0","result":"9566174b00c9c3ca552abc1a52d670ba","id":1}

さらに調査した後、zabbixのGitHubリポジトリにアクセスすることにした。

https://github.com/zabbix/zabbix

CUserについて調べ、CUser.phpファイルを見つけた。

image

user.update関数を見つけた:

public function update(array $users) {
$this->validateUpdate($users, $db_users);
self::updateForce($users, $db_users);
return ['userids' => array_column($users, 'userid')];
}

認可チェックが見つからなかったため、自分の関数をスーパーユーザー関数に変更しようと決め、リクエストに戻ってペイロードを調整した。

image

invalid paramsというエラーメッセージが返ってきた。

さらにコードを長く分析すると、次の関数が見つかった。

/**
* Additional check to exclude an opportunity to deactivate himself.
*
* @param array $users
* @param array $users[]['usrgrps'] (optional)
*
From this snippet, we understand that we cannot change our roles because our role is checked
from extracting our data from the API token, and verifying against the database if we are that user.
But following the code we see that usrgrps has no validation at all, and therefore can be abused
to add ourselves into multiple groups at once. As long as the group is not disabled and the group
allows GUI access we can abuse this to change our current role with the following command:
User ID 3 is matthew , User group 7 is the Zabbix administrators group and user group 13 is the
Internal group which both hold unrestrictive privileges. The response indicates that the change
was successful:
* @throws APIException
*/
private function checkHimself(array $users) {
foreach ($users as $user) {
if (bccomp($user['userid'], self::$userData['userid']) == 0) {
if (array_key_exists('roleid', $user) && $user['roleid'] !=
self::$userData['roleid']) {
self::exception(ZBX_API_ERROR_PARAMETERS, _('User cannot change
own role.'));
}
if (array_key_exists('usrgrps', $user)) {
$db_usrgrps = DB::select('usrgrp', [
'output' => ['gui_access', 'users_status'],
'usrgrpids' => zbx_objectValues($user['usrgrps'], 'usrgrpid')
]);
foreach ($db_usrgrps as $db_usrgrp) {
if ($db_usrgrp['gui_access'] == GROUP_GUI_ACCESS_DISABLED
|| $db_usrgrp['users_status'] ==
GROUP_STATUS_DISABLED) {
self::exception(ZBX_API_ERROR_PARAMETERS,
_('User cannot add himself to a disabled group or a
group with disabled GUI access.')
);
}
}
}
break;
}
}
}

このスニペットによると、自分のロールを変更することはできない。なぜなら、APIトークンからデータを抽出し、データベースでそのユーザーであることを確認することでロールがチェックされるからだ。しかし、コードを追っていくと、usrgrpsにはまったくバリデーションがないことがわかる。そのため、このバリデーションの欠如を悪用して、自分を複数のグループに一度に追加できる。グループが無効化されておらず、GUIアクセスが許可されていれば、以下のコマンドで現在のロールを変更できる: ユーザーID 3はmatthew、ユーザーグループ7はZabbix管理者グループ、ユーザーグループ13は内部グループであり、どちらも制限のない権限を持つ。応答は変更が成功したことを示している。

このバリデーションの欠如を利用して権限昇格を試みる。ペイロードを編集してリクエストを再送信する。

image

userid 3はmatthewユーザーのID。 usrgrpsにはグループIDのリストが含まれる: 13は内部グループ、7はZabbix管理者グループ。サーバーからの応答が操作の成功を確認する:

{"jsonrpc":"2.0","result":{"userids":["3"]},"id":1}

これで、現在のユーザーのユーザーグループを抽出できる。リクエストを変更して再送信する。

image

応答を確認すると、ID 3のユーザーが内部管理者グループとZabbix管理者グループに所属していることがわかる。

{"jsonrpc":"2.0","result":[{"userid":"1","usrgrps":
[{"usrgrpid":"7","name":"Zabbix administrators"},
{"usrgrpid":"13","name":"Internal"}]},{"userid":"2","usrgrps":
[{"usrgrpid":"8","name":"Guests"}]},{"userid":"3","usrgrps":
[{"usrgrpid":"7","name":"Zabbix administrators"},
{"usrgrpid":"13","name":"Internal"}]}],"id":1}

有効なホストグループがZabbix管理者グループに割り当てられているシナリオでは、アイテム作成を悪用してリモートコード実行をトリガーできる。これについては次のCVEで扱う。

CVE-2024-42327 の悪用

CUserクラスのソースコードを再度分析し、68行目のuser.get関数を調査する。108行目に次のコードによるチェックがある:

// permission check
if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) {
if (!$options['editable']) {
$sqlParts['from']['users_groups'] = 'users_groups ug';
$sqlParts['where']['uug'] = 'u.userid=ug.userid';
$sqlParts['where'][] = 'ug.usrgrpid IN ('.
' SELECT uug.usrgrpid'.
' FROM users_groups uug'.
' WHERE uug.userid='.self::$userData['userid'].
')';
}
else {
$sqlParts['where'][] = 'u.userid='.self::$userData['userid'];
}
}

このコードから、APIリクエストにeditableオプションが指定された場合、ユーザーグループの検証を行わず、代わりに現在のユーザーIDが現在のユーザーと一致するかどうかのみチェックする。これにより、user.getを使用する際に権限チェックがバイパスされる。234行目でaddRelatedObjectsが呼び出されており、これがSQLインジェクションに対して脆弱な関数である。2969行目のaddRelatedObject関数を分析すると、ほとんどのSQL文は安全に見えるが、3041行目に到達する。

// adding user role
if ($options['selectRole'] !== null && $options['selectRole'] !==
API_OUTPUT_COUNT) {
if ($options['selectRole'] === API_OUTPUT_EXTEND) {
$options['selectRole'] = ['roleid', 'name', 'type', 'readonly'];
}
$db_roles = DBselect(
'SELECT u.userid'.($options['selectRole'] ? ',r.'.implode(',r.',
$options['selectRole']) : '').
' FROM users u,role r'.
' WHERE u.roleid=r.roleid'.
' AND '.dbConditionInt('u.userid', $userIds)
);
foreach ($result as $userid => $user) {
$result[$userid]['role'] = [];
}
while ($db_role = DBfetch($db_roles)) {
$userid = $db_role['userid'];
unset($db_role['userid']);
$result[$userid]['role'] = $db_role;
}
}
return $result;

このブロックで、selectRoleオプションが指定されると、ユーザー入力をサニタイズせずにDBSelect関数が安全でない形で呼び出される。これにより、時間ベースおよびブラインドブールベースのSQLインジェクションが発生する。

これをテストするために、このリンクからペイロードを取得し、selectRoleパラメータでインジェクションポイントが成功するかどうかを検証する。

ツールをダウンロード