WordPress Th Shop Mania修复CVE-2024-10674漏洞
WordPress主题指用于定制和美化WordPress网站的模板,它包含了网站的整体布局、颜色、字体、图像和其他视觉元素及核心功能集成。
WordPress主题定义了网站的外观和感受,包括布局、排版、颜色和其他设计元素,用户可以通过更改主题来满足不同的需求和行业要求。
一、基本情况
TH Shop Mania是一款快速、轻量级、完全可定制WooCommerce WordPress主题,用于创建电子商务网站,主题使用强大的AJAX技术。
Shop Mania可以与所有页面构建工具完美配合,如Elementor、Visual Composer、Beaver Builder、pizy、Gutenberg等等的一系列工具。
利用该模板,可轻松地创建时装、家具、眼镜、手表、运动、鞋、珠宝、化妆品、多供应商市场、医疗、食品、汽车零部等等电商网站。
主题集成WooCommerce、高级产品搜索、Woo购物车插件、产品比较、变化样本插件和lead form builder插件,协助设计完美在线商店。
栋科技漏洞库关注到WordPress Th Shop Mania主题2024年11月6日更新版本,修复经身份验证任意插件安装/激活漏洞CVE-2024-10674。
二、漏洞分析
CVE-2024-10674漏洞源于WordPress Th Shop v1.4.9(含)th_shop_mania_install_and_activate_callback()函数功能中缺少对权限检查。
这就意味着,拥有用户级及以上访问权限的经过身份验证的攻击者能够利用这一漏洞随意的安装任意插件,该漏洞CVSS3.1评分为8.8分。
如此一来,具有订阅者级别及以上访问权限的认证攻击者可利用该漏洞安装任意插件,然后并利用其他漏洞实现远程代码执行和权限提升。
漏洞代码示例:
th-shop-mania/1.4.9/lib/notification/notify.php
<?php
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
function th_shop_mania_set_cookie() {
$expire_time = time() + (86400 * 7); // 7 days in seconds
if (!isset($_COOKIE['th_shop_mania_thms_time'])) {
// Set a cookie for 7 days
setcookie('th_shop_mania_thms_time', $expire_time, $expire_time, COOKIEPATH, COOKIE_DOMAIN);
}
}
function th_shop_mania_unset_cookie(){
$visit_time = time();
if (isset($_COOKIE['th_shop_mania_thms_time']) && $_COOKIE['th_shop_mania_thms_time'] < $visit_time) {
setcookie('th_shop_mania_thms_time', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN);
}
}
function th_shop_mania_clear_notice_cookie() {
// Clear the cookie when the theme is switched
if (isset($_COOKIE['th_shop_mania_thms_time'])) {
setcookie('th_shop_mania_thms_time', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN);
}
}
if(isset($_GET['notice-disable']) && $_GET['notice-disable'] == true){
add_action('admin_init', 'th_shop_mania_set_cookie');
}
if(!isset($_COOKIE['th_shop_mania_thms_time'])) {
add_action('admin_notices', 'th_shop_mania_display_admin_notice');
}
if(isset($_COOKIE['th_shop_mania_thms_time'])) {
add_action( 'admin_notices', 'th_shop_mania_unset_cookie');
}
// add_action('admin_notices', 'th_shop_mania_display_admin_notice');
// Display admin notice
function th_shop_mania_display_admin_notice() {
$allowed_pages = array(
'dashboard', // index.php
'themes', // themes.php
'plugins', // plugins.php
'users',
'appearance_page_th_shop_mania_thunk_started' // appearance_page_thunk_started
);
// Get the current screen
$current_screen = get_current_screen();
// Check if the current screen is one of the allowed pages
if (!in_array($current_screen->base, $allowed_pages)) {
return; // Exit if not on an allowed page
}
global $current_user;
$user_id = $current_user->ID;
$theme_data = wp_get_theme();
if ( get_user_meta( $user_id, esc_html( $theme_data->get( 'TextDomain' ) ) . '_notice_ignore' ) ) {
return;
}
// Retrieve the theme support data
$plugin_data = get_theme_support('recommend-plugins');
// Check if the theme support exists and has the plugin data
$plugin_data = $plugin_data[0];
// Get the specific plugin data
$hunk_companion = isset($plugin_data['hunk-companion']) ? $plugin_data['hunk-companion'] : array();
$th_shop_mania_pro = isset($hunk_companion['pro-plugin']) ? $hunk_companion['pro-plugin'] : array();
// Extract the values
$plugin_pro_slug = isset($th_shop_mania_pro['slug']) ? $th_shop_mania_pro['slug'] : '';
$plugin_pro_file = isset($th_shop_mania_pro['init']) ? $th_shop_mania_pro['init'] : '';
$plugin_companion_slug = isset($plugin_data['hunk-companion']['slug']) ? $plugin_data['hunk-companion']['slug'] : 'hunk-companion';
$plugin_companion_file = isset($plugin_data['hunk-companion']['active_filename']) ? $plugin_data['hunk-companion']['active_filename'] : '';
// Show admin notice to install or activate the secondary plugin
$plugin_pro_installed = is_plugin_active($plugin_pro_file);
$plugin_pro_exists = file_exists(WP_PLUGIN_DIR . '/' . $plugin_pro_file);
$plugin_companion_installed = is_plugin_active($plugin_companion_file);
$plugin_companion_exists = file_exists(WP_PLUGIN_DIR . '/' . $plugin_companion_file);
// Check if 'th-shop-mania-pro' is installed
$plugin_pro_installed = is_plugin_active($plugin_pro_file);
$plugin_pro_exists = file_exists(WP_PLUGIN_DIR . '/' . $plugin_pro_file);
if ((isset($_GET['page']) && $_GET['page'] == 'th_shop_mania_thunk_started' ) || ((!$plugin_pro_exists && !$plugin_companion_exists) ||($plugin_pro_exists && !$plugin_pro_installed) || (!$plugin_pro_exists && $plugin_companion_exists && !$plugin_companion_installed)) ) {
if ($plugin_pro_exists) {
// 'th-shop-mania-pro' is installed
if ($plugin_pro_installed) {
// Plugin is activated
echo '<div class="notice notice-info th-shop-mania-wrapper-banner is-dismissible">
<div class="left"><h2 class="title">
'.sprintf( esc_html__( 'Thank you for installing %1$s - Version %2$s', 'th-shop-mania' ), apply_filters( 'thsm_page_title', __( 'Th Shop Mania', 'th-shop-mania' ) ), esc_html( $theme_data->Version ) ).'</h2>
<p>' . esc_html__('To take full advantage of all the features this theme has to offer, please install and activate the ', 'th-shop-mania') . '<strong>Hunk Companion</strong></p>
<button class="button button-primary" id="go-to-starter-sites" data-slug="' . esc_attr($plugin_pro_slug) . '">' . esc_html__('Go to Ready To Import website Templates ', 'th-shop-mania') . '</button>
</div>
<div class="right">
<img src="' . esc_url(get_template_directory_uri() . '/lib/notification/banner.png') . '" />
</div>
<a href="?notice-disable=1" class="notice-dismiss dashicons dashicons-dismiss dashicons-dismiss-icon"></a>
</div>';
} else {
// Plugin is installed but not activated
echo '<div class="notice notice-info th-shop-mania-wrapper-banner is-dismissible">
<div class="left">
<h2 class="title">
'.sprintf( esc_html__( 'Thank you for installing %1$s - Version %2$s', 'th-shop-mania' ), apply_filters( 'thsm_page_title', __( 'Th Shop Mania', 'th-shop-mania' ) ), esc_html( $theme_data->Version ) ).'</h2>
<p>' . esc_html__('To take full advantage of all the features this theme has to offer, please install and activate the ', 'th-shop-mania') . '<strong>TH Shop Mania Pro</strong></p>
<button class="button button-primary" id="activate-th-shop-mania-pro" data-slug="' . esc_attr($plugin_pro_slug) . '"><span>' . esc_html__('Activate', 'th-shop-mania') . '</span><span class="dashicons dashicons-update loader"></span></button>
<button class="button button-primary" id="go-to-starter-sites" data-slug="' . esc_attr($plugin_pro_slug) . '" disabled>' . esc_html__('Go to Ready To Import website Templates ', 'th-shop-mania') . '</button>
</div>
<div class="right">
<img src="' . esc_url(get_template_directory_uri() . '/lib/notification/banner.png') . '" />
</div>
<a href="?notice-disable=1" class="notice-dismiss dashicons dashicons-dismiss dashicons-dismiss-icon"></a>
</div>';
}
} else {
// 'th-shop-mania-pro' is not installed, check 'hunk-companion'
$plugin_companion_installed = is_plugin_active($plugin_companion_file);
$plugin_companion_exists = file_exists(WP_PLUGIN_DIR . '/' . $plugin_companion_file);
echo '<div class="notice notice-info th-shop-mania-wrapper-banner is-dismissible">
<div class="left">
<h2 class="title">
'.sprintf( esc_html__( 'Thank you for installing %1$s - Version %2$s', 'th-shop-mania' ), apply_filters( 'thsm_page_title', __( 'Th Shop Mania', 'th-shop-mania' ) ), esc_html( $theme_data->Version ) ).'</h2>
<p>' . esc_html__('To take full advantage of all the features this theme has to offer, please install and activate the ', 'th-shop-mania') . '<strong>Hunk Companion</strong></p>';
if ($plugin_companion_exists) {
if ($plugin_companion_installed) {
echo '<button class="button button-primary" id="go-to-starter-sites" data-slug="' . esc_attr($plugin_pro_slug) . '">' . esc_html__('Go to Ready To Import website Templates ', 'th-shop-mania') . '<span class="dashicons dashicons-update loader"></span></button>';
} else {
echo '<button class="button button-primary" id="activate-hunk-companion" data-slug="' . esc_attr($plugin_companion_slug) . '"><span>' . esc_html__('Activate', 'th-shop-mania') . '</span><span class="dashicons dashicons-update loader"></span></button> <button class="button button-primary" id="go-to-starter-sites" data-slug="' . esc_attr($plugin_pro_slug) . '" disabled>' . esc_html__('Go to Ready To Import website Templates ', 'th-shop-mania') . '</button>';
}
} else {
echo '<button class="button button-primary" id="install-hunk-companion" data-slug="' . esc_attr($plugin_companion_slug) . '"><span>' . esc_html__('Install', 'th-shop-mania') . '</span><span class="dashicons dashicons-update loader"></span></button><button class="button button-primary" id="go-to-starter-sites" data-slug="' . esc_attr($plugin_pro_slug) . '"disabled >' . esc_html__('Go to Ready To Import website Templates ', 'th-shop-mania') . '</button>';
}
echo '</div>
<div class="right">
<img src="' . esc_url(get_template_directory_uri() . '/lib/notification/banner.png') . '" />
</div>
<a href="?notice-disable=1" class="notice-dismiss dashicons dashicons-dismiss dashicons-dismiss-icon"></a>
</div>';
}
}
}
// Custom function to check if a plugin is installed
function th_shop_mania_is_plugin_installed($plugin_slug) {
$plugin_dir = WP_PLUGIN_DIR . '/' . $plugin_slug;
return is_dir($plugin_dir);
}
function th_shop_mania_install_custom_plugin($plugin_slug) {
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$plugin_info = plugins_api('plugin_information', array('slug' => $plugin_slug));
if (is_wp_error($plugin_info)) {
return $plugin_info->get_error_message();
}
$upgrader = new Plugin_Upgrader(new Plugin_Installer_Skin(array(
'api' => $plugin_info,
)));
$result = $upgrader->install($plugin_info->download_link);
if (is_wp_error($result)) {
return $result->get_error_message();
}
return "success";
}
// AJAX handler for installing and activating plugins
add_action('wp_ajax_th_shop_mania_install_and_activate_callback', 'th_shop_mania_install_and_activate_callback');
// Callback function to install and activate plugin
function th_shop_mania_install_and_activate_callback() {
// Check nonce for security
check_ajax_referer('thactivatenonce', 'security');
// Retrieve plugin slug from AJAX request
$plugin_slug = isset($_POST['plugin_slug']) ? sanitize_text_field($_POST['plugin_slug']) : '';
if (empty($plugin_slug)) {
wp_send_json_error(array('message' => 'Plugin slug is missing.'));
return;
}
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_slug . '/' . $plugin_slug . '.php';
// Install the plugin
if (!file_exists($plugin_file)) {
// Start output buffering to capture the plugin installation output
ob_start();
$status = th_shop_mania_install_custom_plugin($plugin_slug);
// Get the buffered content
$install_output = ob_get_clean();
if (is_wp_error($status)) {
wp_send_json_error(array('message' => $status->get_error_message(), 'install_output' => $install_output));
return;
}
// Check if the plugin file exists after installation
if (!file_exists($plugin_file)) {
wp_send_json_error(array('message' => 'Plugin file does not exist after installation.', 'install_output' => $install_output));
return;
}
}
// Activate the plugin
if (!is_plugin_active($plugin_file)) {
$status = activate_plugin($plugin_file);
if (is_wp_error($status)) {
wp_send_json_error(array('message' => $status->get_error_message()));
return;
}
}
return 'Plugin installed and activated successfully.';
}
function th_shop_mania_admin_script($hook_suffix) {
// Define the pages where the script should be enqueued
$allowed_pages = array(
'index.php',
'themes.php',
'plugins.php',
'users.php',
'appearance_page_th_shop_mania_thunk_started'
);
// Check if the current page is one of the allowed pages
if (!in_array($hook_suffix, $allowed_pages)) {
return;
}
// Enqueue styles and scripts only on the allowed pages
wp_enqueue_style('th-shop-mania-admin-css', get_template_directory_uri() . '/lib/notification/css/admin.css', array(), TH_SHOP_MANIA_THEME_VERSION, 'all');
wp_enqueue_script('th-shop-mania-notifyjs', get_template_directory_uri() . '/lib/notification/js/notify.js', array('jquery'), TH_SHOP_MANIA_THEME_VERSION, true);
// Pass AJAX URL to the script
wp_localize_script('th-shop-mania-notifyjs', 'theme_data', array(
'ajax_url' => admin_url('admin-ajax.php'),
'security' => wp_create_nonce('thactivatenonce'), // Create nonce for security
'redirectUrl' => esc_url(admin_url('themes.php?page=themehunk-site-lipary&template=step')) // Generate dynamic URL
));
}
add_action('admin_enqueue_scripts', 'th_shop_mania_admin_script');
// Hook the function to clear the cookie when the theme is switched to
add_action('after_switch_theme', 'th_shop_mania_clear_notice_cookie');
?>
三、影响范围
Th Shop Mania <= 1.4.9
四、修复建议
Th Shop Mania >= 1.5.0
五、参考链接
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-themes/th-shop-mania/th-shop-mania-149-authenticated-subscriber-arbitrary-plugin-installationactivation