UpdraftPlus任意备份下载漏洞 CVE-2022-0633

UpdraftPlus任意备份下载漏洞 CVE-2022-0633

在对 UpdraftPlus 插件进行内部审计期间,我们发现了一个任意备份下载漏洞,该漏洞可能允许订阅者等低权限用户下载站点的最新备份。

UpdraftPlus任意备份下载漏洞 CVE-2022-0633

如果被利用,该漏洞可能允许攻击者访问受影响站点数据库中的特权信息(例如,用户名和hash密码)。

我们向插件作者报告了这个漏洞,他们最近发布了 1.22.3 版本来解决这个问题。由于此问题的严重性,还推送了强制自动更新。如果您的站点尚未安装,我们强烈建议您更新到最新版本 (1.22.3) 并在您的站点上安装成熟的安全解决方案,例如Jetpack Security

您可以在此处找到 UpdraftPlus 自己的建议

UpdraftPlus官网公告信息

UpdraftPlus 安全版本 – 1.22.3 / 2.22.3 – 请升级

我们新的 UpdraftPlus 版本 1.22.3(免费版)/2.22.3(付费版)是一个安全版本。简短的版本是:你应该更新。要获取详细信息,请继续阅读!

2 月 15 日晚,我们收到了 Automattic 的安全研究员 Marc-Alexandre Montpas 的安全缺陷报告,他在对 UpdraftPlus 的审计期间发现了当前版本的 UpdraftPlus 中存在一个以前未知的缺陷,该缺陷的 CVE 标识符为 CVE- 2022-23303。

此缺陷允许任何在 UpdraftPlus 处于活动状态的 WordPress 安装上登录的用户行使下载现有备份的权限,该权限本应仅限于管理用户。这是可能的,因为与检查当前备份状态相关的代码缺少权限检查。这允许获得一个内部标识符,该标识符在其他情况下是未知的,然后可用于在允许下载时通过检查。

这意味着,如果您的 WordPress 站点允许不受信任的用户使用 WordPress 登录,并且如果您有任何现有备份,那么您可能容易受到技术熟练的用户的攻击,该用户正在研究如何下载现有备份。如果您的网站包含任何非公开内容,则受影响的网站可能会因攻击者访问您网站的备份副本而导致数据丢失/数据被盗。我说“技术熟练”,因为那时还没有公开证明如何利用这个漏洞。目前,它依靠黑客对最新 UpdraftPlus 版本中的更改进行逆向工程来解决问题。但是,您当然不应该依赖这需要很长时间,而应该立即更新。如果您是 WordPress 网站上的唯一用户,或者如果您的所有用户都是可信的,那么您就不会受到攻击,

假设您已将加密密码保密,则使用UpdraftPlus Premium加密数据库备份功能的用户可免受此问题造成的数据丢失/盗窃。(没有已知的漏洞允许攻击者也可以访问它)。在这种情况下,只有文件备份中的任何机密信息有风险(然后通常只有您的媒体/上传文件,因为插件和主题通常只是不包含任何敏感信息的公共代码,可从其原始供应商/作者处下载任何公众成员)。另请注意,WordPress 数据库遵循现代安全标准,对存储的密码进行哈希处理。这意味着即使有人获得了未加密的密码副本,您的 WordPress 登录密码也会受到保护。

此信息现在在 UpdraftPlus 的更新、安全版本可用后大约一天发布。在此期间,大多数网站都已更新。

同样,我们敦促所有用户更新,如果他们还没有这样做的话。UpdraftPlus 对由此造成的任何不便深表歉意,并感谢 Marc 与我们一起工作。从我们收到报告的那一刻起,我们就“全力以赴”。在一小时内向高级用户推送了更新。我们已经失去了大量的睡眠,因为您的网站及其备份对我们很重要,我们将继续努力确保这种情况继续存在。

(附录:版本 1.22.4 / 2.22.4 随后已发布,通过添加解决方法处理与流行的第三方插件中的错误冲突(我们也向插件作者报告了该问题) )。

细节

插件名称:UpdraftPlus
插件 URI: https://wordpress.org/plugins/updraftplus/
作者:https ://updraftplus.com/

漏洞

任意备份下载

受影响的版本: 1.16.7 和 1.22.3(免费版)之间的每个版本
CVE-ID: CVE-20 2-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 安全选项,可确保您的网站和访问者的安全。

from

转载请注明出处及链接

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注