在对 UpdraftPlus 插件进行内部审核期间,我们发现了一个任意备份下载漏洞,该漏洞可能允许订阅者等低权限用户下载站点的最新备份。
如果被利用,该漏洞可能允许攻击者访问受影响站点数据库中的特权信息(例如,用户名和散列密码)。
我们向插件作者报告了这个漏洞,他们最近发布了 1.22.3 版本来解决这个问题。由于此问题的严重性,还推送了强制自动更新。如果您的站点尚未安装,我们强烈建议您更新到最新版本 (1.22.3) 并在您的站点上安装成熟的安全解决方案,例如 Jetpack Security。
您可以在此处找到 UpdraftPlus 自己的建议。
细节
插件名称:UpdraftPlus
插件 URI:https://wordpress.org/plugins/updraftplus/
作者:https://updraftplus.com/
漏洞
任意备份下载
受影响的版本:1.16.7 和 1.22.3(免费版)之间的每个版本,以及
CVE-ID:CVE-2022-0633
WPVDB ID:d257c28f-3c7e-422b-a5c2-e618ed3c0bf3
CVSSv3.1:8.5
CWSS:87.6
该插件使用自定义“随机数”和时间戳来安全地识别备份。鉴于上述 nonce 和时间戳的知识可以让某人访问相当多的插件功能,确保这些信息只对那些合法需要它的人开放是至关重要的。
不幸的是,正如我们将展示的那样,事实并非如此。
随机数泄漏
第一个罪魁祸首是 UpdraftPlus_Admin::process_status_in_heartbeat 方法。
/** * Receive Heartbeat data and respond. * * Processes data received via a Heartbeat request, and returns additional data to pass back to the front end. * * @param array $response - Heartbeat response data to pass back to front end. * @param array $data - Data received from the front end (unslashed). */ public function process_status_in_heartbeat($response, $data) { if (!is_array($response) || empty($data['updraftplus'])) return $response; try { $response['updraftplus'] = $this->get_activejobs_list(UpdraftPlus_Manipulation_Functions::wp_unslash($data['updraftplus'])); } catch (Exception $e) { $log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); $response['updraftplus'] = array( 'fatal_error' => true, 'fatal_error_message' => $log_message ); // @codingStandardsIgnoreLine } catch (Error $e) { $log_message = 'PHP Fatal error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); $response['updraftplus'] = array( 'fatal_error' => true, 'fatal_error_message' => $log_message ); } if (UpdraftPlus_Options::user_can_manage() && isset($data['updraftplus']['updraft_credentialtest_nonce'])) { if (!wp_verify_nonce($data['updraftplus']['updraft_credentialtest_nonce'], 'updraftplus-credentialtest-nonce')) { $response['updraftplus']['updraft_credentialtest_nonce'] = wp_create_nonce('updraftplus-credentialtest-nonce'); } } $response['updraftplus']['time_now'] = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'D, F j, Y H:i'); return $response; }
它没有正确确保发送此心跳请求的用户是管理员(例如,通过诸如 current_user_can 之类的函数),这是一个问题,因为该函数尝试做的第一件事是通过 get_activejobs_list
方法获取活动备份作业的列表。
备份下载
有几种方法可以在 UpdraftPlus 上下载备份,其中大部分都得到了适当的保护。
/** * Find out if the current request is a backup download request, and proceed with the download if it is */ public function maybe_download_backup_from_email() { global $pagenow; if ((!defined('DOING_AJAX') || !DOING_AJAX) && UpdraftPlus_Options::admin_page() === $pagenow && isset($_REQUEST['page']) && 'updraftplus' === $_REQUEST['page'] && isset($_REQUEST['action']) && 'updraft_download_backup' === $_REQUEST['action']) { $findexes = empty($_REQUEST['findex']) ? array(0) : $_REQUEST['findex']; $timestamp = empty($_REQUEST['timestamp']) ? '' : $_REQUEST['timestamp']; $nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce']; $type = empty($_REQUEST['type']) ? '' : $_REQUEST['type']; if (empty($timestamp) || empty($nonce) || empty($type)) wp_die(__('The download link is broken, you may have clicked the link from untrusted source', 'updraftplus'), '', array('back_link' => true)); $backup_history = UpdraftPlus_Backup_History::get_history(); if (!isset($backup_history[$timestamp]['nonce']) || $backup_history[$timestamp]['nonce'] !== $nonce) wp_die(__("The download link is broken or the backup file is no longer available", 'updraftplus'), '', array('back_link' => true)); $this->do_updraft_download_backup($findexes, $type, $timestamp, 2, false, ''); exit; // we don't need anything else but an exit } } }
因此,攻击者可以针对此心跳回调制作恶意请求,以访问有关该站点迄今为止的最新备份的信息,其中包括备份的随机数。
不幸的是,与 admin_init 挂钩的 UpdraftPlus_Admin::maybe_download_backup_from_email 方法也没有直接验证用户的角色。
虽然它确实间接应用了一些检查,例如检查 $pagenow
全局变量,但过去的研究表明该变量可以包含任意用户输入。 不良行为者可以根据他们从上述心跳漏洞中泄露的信息,使用此端点下载文件和数据库备份。
时间线
2022-02-14 – 与 UpdraftPlus 的初次接触
2022-02-15 – 我们向他们发送有关此漏洞的详细信息
2022-02-16 – UpdraftPlus 1.22.3 发布,强制自动更新启动
结论
我们建议您检查您的站点使用的是哪个版本的 UpdraftPlus 插件,如果在受影响的范围内,请尽快更新!
在 Jetpack,我们努力确保您的网站免受此类漏洞的影响。 我们建议您为您的站点制定一个安全计划,其中包括恶意文件扫描和备份。 Jetpack Security 是一种出色的 WordPress 安全选项,可确保您的网站和访问者的安全。
学分
原始研究员:马克·蒙帕斯