CVE-2023-30534 : Cacti のバージョン 1.2.24 以前に存在する安全でない逆シリアル化の脆弱性

概要 

Cactiバージョン 1.2.24 以前に安全でないシリアル化の2つのインスタンスがあることを私たちは発見しました。この脆弱性は CVE-2023-30534 として知られています。安全でない逆シリアル化の各インスタンスはリモートでトリガーされますが、実行環境の制限により悪用されることはありません。これについては「悪用の試み」のセクションで詳しくご説明します。

Cacti は RRDtool のデータストレージとグラフ化機能を利用するオープンソースのネットワーク管理・グラフ化ソリューションで、グラフの作成やデバイスの発見などに利用されます。Cacti のインスタンスの一部は外部からのアクセスが可能ですが、Cacti の主な用途は内部ネットワークシステムのモニタリングです。

技術面についてもう少し詳しくみてみましょう。シリアル化とは、PHP や Java オブジェクトなど複雑なデータ構造を持つオブジェクトを、ネットワーク経由で送信しやすい形式に変換するプロセスを指します。一方、逆シリアル化は、変換されたデータを元の複雑なデータ構造に再構築することをいいます。安全でない逆シリアル化は、ユーザーが制御するデータが逆シリアル化される場合に発生し、攻撃者による任意のオブジェクトのインスタンス化やファイルの読み込み/書き込みに加えて、リモートコードの実行さえも可能になるおそれがあります。

注 : Cacti のバージョン 1.2.25 (および 1.3.0) では、Cacti に存在するその他の17件の脆弱性 (深刻で影響力の大きいものも含まれます) も修正されているので、管理者はできる限り早急にアップグレードすることが推奨されます。

影響を受けるバージョン

私たちはまず Cacti のバージョン 1.2.10 に安全でない逆シリアル化の脆弱性があることを発見し、バージョン 1.2.25 より前のすべてのバージョンにこの脆弱性が存在することが分かっています。Cacti のバージョン 1.2.5 に加えて 1.3.5 でも安全でない逆シリアル化の問題が修正されています。

安全でないシリアル化の脆弱性の詳細

安全でない逆シリアル化の各インスタンスは、ユーザーが指定した入力を適切にサニタイズせずに unserialize 関数を使用することで発生します。Cacti は、unserialize 関数を呼び出す前にサニタイズを行い、文字列が特定の値のみを含むことを確認しようとすることで安全な逆シリアル化を行うユーティリティ機能を提供していますが、この機能はこれらのインスタンスでは使用されていません。

注 : コードブロックを簡潔にするため、参照されないコードは削除されています。

managers.php

脆弱なコードが managers.php ファイルの form_actions 関数内に存在します。以下のコードスニペットは Cacti のバージョン 1.2.10 のものです。

function form_actions() {
global $manager_actions, $manager_notification_actions;
if (isset_request_var('selected_items')) {
if (isset_request_var('action_receivers')) {
...
...
...
} elseif (isset_request_var('action_receiver_notifications')) {
get_filter_request_var('id');
$selected_items = unserialize(stripslashes(get_nfilter_request_var('selected_items')));
...
}
...
}

POST リクエストの変数 action_receiver_notifications を設定することで、form_actions 関数で unserialize の呼び出しを実行するようにコードフローを仕向けることができます。form_actions をトリガーするには、「action」変数を「actions」に設定する必要があります。undefinedundefinedこれにより、以下のように switch ステートメントで適切な case を実行できます。

switch (get_request_var('action')) {
case 'save':
form_save();
break;
case 'actions':
form_actions();
break;
...
...

脆弱な unserialize 関数を悪用するには、以下のように URL がエンコードされシリアル化された PHP オブジェクトが「selected_items」変数に使用されている POST リクエストを、認証済みユーザーが送信する必要があります。

cve blog image 1

無効なオブジェクト (誤った形式や、Cacti によって認識されないクラスを含むものなど) を「selected_items」変数の値として入力した場合、Cacti がペイロードを逆シリアル化できなかったことがログで確認できます。

cve blog image 2

この時点でコードフローをコントロールし、managers.php でユーザーが制御するシリアル化されたオブジェクトに対して unserialize 関数を呼び出すことができます。

graphs_new.php

脆弱なコードが graphs_new.php ファイルの host_new_graphs_save 関数に存在します。以下のコードスニペットは Cacti のバージョン 1.2.10 のものです。

function host_new_graphs_save($host_id) {
$selected_graphs_array = unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array')));
$values = array();

この関数は、ユーザーが制御するパラメーター selected_graphs_array を逆シリアル化します。stripslashes が最初に実行されますが、これは単に前処理中に文字列で必要だった余分なスラッシュを取り除くためのものです。 

上記の関数を呼び出すには、action=savesave_component_new_graphs=1 の2つのパラメータを使用して graphs_new.php にリクエストを送信します。これにより、以下のコードスニペットが示すように脆弱な関数が呼び出されます。

switch (get_request_var('action')) {
case 'save':
form_save();
break;
case 'query_reload':
...
...
...
function form_save() {
...
...
...
if (isset_request_var('save_component_new_graphs')) {
host_new_graphs_save(get_filter_request_var('host_id'));
header('Location: graphs_new.php?host_id=' . get_filter_request_var('host_id') . &header=false');
}
}

脆弱な unserialize 関数を悪用するには、以下のように URL がエンコードされシリアル化された PHP オブジェクトが selected_graphs_array 変数に使用されている POST リクエストを、認証済みユーザーが送信する必要があります。

cve blog image 3

無効なオブジェクト (誤った形式や、Cacti によって認識されないクラスを含むものなど) を selected_graphs_array 変数の値として入力した場合、Cacti がペイロードを逆シリアル化できなかったことがログで確認できます。

cve blog image 4

この時点でコードフローをコントロールし、graphs_new.php でユーザーが制御するシリアル化されたオブジェクトに対して unserialize 関数を呼び出すことができます。

悪用の試み

PHPマジックメソッド

PHP の逆シリアル化の脆弱性を悪用するには「マジックメソッド」が実装されたオブジェクトにアクセスする必要があります。  マジックメソッドは、オブジェクトが作成されたり破棄されたりする際に自動的に呼び出されます。このようなメソッドには __construct__unserialize__destruct__wake などがあります。ペイロードがオブジェクトに逆シリアル化される際にこれらの関数の一部が自動的に呼び出されるので、これらの関数を使用するオブジェクトにアクセスできる必要があります。このコンテキストでは、「ガジェット」はこれらのメソッドのひとつが実装され、ペイロードで使用可能なオブジェクトです。ネストされたオブジェクトをペイロードで使用することで、これらのガジェットを組み合わせて「ガジェットチェーン」を構成し、ファイルの読み込みや書き込み、コードの実行といった望み通りのアクションを実行できるようになります。 

ガジェットチェーンを探す

これまでに多くのガジェットチェーンが人気の高いライブラリで発見されています。PHPGCC ツールは、安全でない逆シリアル化のペイロードを作成するのに使用できる既知のガジェットチェーンのリストを提供しています。Cacti の PHP ベンダーである PHPSecLib には、既知の利用可能なガジェットチェーンがひとつ含まれています。しかし、Cacti は PHPSecLib のガジェットチェーンを使用するのに必要なガジェット (TripleDES、AES、SSH1) のいずれも必要とせず、含んでいません。

既存のガジェットチェーンの利用に加えて、使用可能なマジックメソッドが実装されたオブジェクトがプロジェクトにある場合は、新しいガジェットチェーンを作成することが可能です。例えば、Cacti __construct メソッドの実装をソースコードで確認し、これらのなかで使用可能なものがあるかを見てみましょう。Cacti の PHP オブジェクトで実装されたマジックメソッドを調べたところ、新しいガジェットチェーンで使用可能なものは見つかりませんでした。

利用可能なガジェットチェーンを見つけられない場合、この脆弱性は悪用することが不可能であることを意味します。

CVE-2023-30534ための Nuclei テンプレート

この脆弱性の迅速なテストを促進するため、また修復の取り組みをサポートするため、私たちは CVE-2023-30534ためのテストを実行する Nucleiテンプレートを作成しました。このテンプレートは認証を要求し、オブジェクトに対して unserialize 関数が呼び出されたことを示すログメッセージを生成するために無効な PHP オブジェクトを送信します。テンプレートはログのエラーメッセージを確認して unserialize 関数が呼び出されたことを検証し、unserialize 関数がペイロードで呼び出されたことを確認します。以下のように、このテンプレートはローカルで実行されます。

cve blog image 4

Cacti の管理者はバージョン 1.2.5 以降 (1.3.0 など) にアップグレードすることで、この脆弱性を修復できます。Cacti の標準インストールではこの脆弱性が悪用されることはありませんが、Cacti のセキュリティアドバイザリで修復に関する詳細を確認し、Cacti のアドバイスに従うことをお勧めします。

: Cacti のバージョン 1.2.25 (および 1.3.0) では、Cacti に存在するその他の17件の脆弱性 (深刻で影響力の大きいものも含まれます) も修正されているので、管理者はできる限り早急にアップグレードすることが推奨されます。

Fastly Security Research Team
Fastly Security Research Team
Matthew Mathur
Senior Security Researcher
投稿日

この記事は6分で読めます

興味がおありですか?
エキスパートへのお問い合わせ
この投稿を共有する
Fastly Security Research Team
Fastly Security Research Team

Fastly Security Research Team は、お客様が必要なツールやデータを利用してシステムを安全に保てる環境づくりに注力しています。同チームは Fastly ならではのスケールで攻撃を分析し、ブロックします。Fastly Security Research Team は、絶えず高度に変化し続けるセキュリティ環境の最先端を行く技術を駆使し、裏方としてお客様を支えるセキュリティエキスパートです。

Matthew Mathur
Senior Security Researcher

Matthew は Fastly の Senior Security Researcher として、脆弱性に関する研究、Web アプリケーション攻撃、保護ソリューションの開発に注力しています。Metasploit Framework や Nuclei を含む、オープンソースのセキュリティツールの開発に積極的に貢献し、熱心に研究結果をセキュリティコミュニティと共有しています。

Fastly試してみませんか ?

アカウントを作成してすぐにご利用いただけます。また、いつでもお気軽にお問い合わせください。