
GiveWP WordPressプラグインのPHPオブジェクトインジェクション(CVE-2024-12877)に関する教育用エクスプロイトデモです。根本原因分析、正規表現バイパス技術、安全なエクスプロイト実践方法が含まれます。
第66週 | 著者: Ali Soltani (soltanali0))
GO-TO CVE シリーズ第66週へようこそ。ここでは脆弱性を分析し、根本原因を探り、安全で教育目的の環境で実践的なエクスプロイト手法を実演します。
CVE-2024-12877 は、最も広く使われているWordPress寄付プラグインの1つである GiveWP における PHP オブジェクトインジェクション の脆弱性です。ユーザー制御の入力に対する unserialize() の安全でない使用により、攻撃者はPHPのマジックメソッド(__wakeup() など)をトリガーでき、次のような事態を引き起こす可能性があります:
CVSS: 9.8 Critical | Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
GiveWP は、数千のチャリティサイト、NGO、資金調達プラットフォームを支えています。機密性の高い金融データやドナー情報を取り扱うため、ここでの脆弱性は非常に影響が大きくなります。オブジェクトインジェクションを悪用する攻撃者は、単一のプラグインからWordPressインストール全体とその基盤となるサーバーを侵害することへ拡大できます。
根本原因: 信頼できない入力に対する unserialize()
PHP マジックメソッド: PHPはオブジェクトのライフサイクル中にこれらを自動的に呼び出します:
この脆弱性は、ユーザー制御の入力に対するPHP関数 unserialize() の安全でない使用に起因します。unserialize() はPHPデータ構造を再構築するために設計されていますが、危険な副作用があります。オブジェクトが再構築されると、PHPは自動的にマジックメソッドを呼び出します。
__wakeup() – オブジェクトがアンシリアライズされたときにトリガーされる
__destruct()、__toString()、__get/__set()、__call/__callStatic() – 悪意のある実行に悪用される可能性がある
正規表現による検証: GiveWPは、シリアライズ入力を検出するための正規表現チェックを実装しました。新しい正規表現はより多くのデータ型を検出しますが、正規表現はオブジェクトインジェクションを確実に防ぐことはできません。

巧妙に細工されたシリアライズオブジェクトを使用すると、攻撃者はオブジェクトのプロパティを設定でき、PHP自体がマジックメソッドを呼び出すことで攻撃者のロジックを実行します。
GiveWPは、入力がシリアライズされているかをチェックするために、正規表現ベースの検証を実装しました。 旧正規表現(不完全)
• 配列とオブジェクトのみを認識。
• その他のシリアライズ型(string、int、bool、float、null)は検出をすり抜ける。

• すべてのPHPシリアライズ型を認識する。
• 一部の単純なペイロードをブロックする。
• しかし核心の問題は残る: unserialize() をユーザー入力に使う限り、正規表現では救えない。

このスニペットは、2つの異なる正規表現の実装を比較するために書かれました:
• is_serialized_old() → 配列とオブジェクトのみを検出する旧バージョン。
• is_serialized_new() → すべてのPHPシリアライズデータ型(配列、オブジェクト、文字列、整数、ブール、浮動小数点数、null)を認識する改善版。
テスト値(array、object、string、integer、boolean、float、null)のセットを作成し、それらをシリアライズして、各値を両方の正規表現関数に対してチェックします。
簡単に言うと:

そして、このコードをDocker上で実行すると、ブラウザでこの結果が表示されます。

ステップ 1

ステップ 2: 脆弱なクラスを作成する

このクラスには __wakeup() メソッドがあり、アンシリアライズされると自動的に実行されます。
ステップ 3: ペイロードを作成する

ステップ 4: 出力 ファイルを保存した後、このファイルで以下のエクスプロイトが確認できます。

エクスプロイト :

• 旧正規表現: FALSE → ペイロードの検出に失敗。
• 新正規表現: TRUE → シリアライズ入力として検出。
• 実行結果: Hello RCE! → ペイロードがアンシリアライズされ、マジックメソッド __wakeup() が攻撃者制御のコードを実行した。
予防
• 信頼できない入力に unserialize() を使用しない。json_decode() などのより安全な代替手段に置き換える。
• GiveWPおよびすべてのWordPressプラグインを最新の状態に保つ。
• 悪意のあるシリアライズペイロードをブロックするためにWeb Application Firewall(WAF)を導入する。
• 最小権限の原則に従い、PHPとデータベースアカウントを必要最小限の権限で実行する。
結果:
重要な洞察:
unserialize()の安全性を正規表現に頼ってはならない。最も安全な方法は、信頼できない入力を一切アンシリアライズしないことです。
unserialize() を使用しない。json_decode() などの安全な代替手段を優先する。私は脆弱性調査とエクスプロイトに特化した2つのTelegramチャンネルを運営しています:
チャンネルをフォローして、最新のCVE、エクスプロイト手法、セキュリティ研究の洞察を入手しましょう。
このリポジトリは教育および研究目的に限定されています。許可なく脆弱性を悪用することは違法かつ非倫理的です。著者は誤用について一切責任を負いません。