Le 13 août 2020, l’équipe de Wordfence Threat Intelligence a terminé d’enquêter sur deux vulnérabilités dans Gestionnaire d’accès avancé, un plugin WordPress avec plus de 100000 installations, y compris une vulnérabilité de contournement d’autorisation de haute gravité qui pourrait entraîner une élévation de privilèges et une prise de contrôle de site.

Nous avons contacté l’auteur du plugin le lendemain, le 14 août 2020, et avons reçu une réponse en quelques heures. Après avoir fourni la divulgation complète de la vulnérabilité, nous avons reçu une réponse le 15 août 2020, indiquant qu’un correctif avait été publié dans la version 6.6.2.

Les utilisateurs de Wordfence Premium ont reçu une règle de pare-feu protégeant contre la vulnérabilité de contournement d’autorisation le 14 août 2020. Les sites exécutant toujours la version gratuite de Wordfence recevront cette règle 30 jours plus tard, le 13 septembre 2020.


Advanced Access Manager permet un contrôle d’accès précis et a la capacité d’attribuer plusieurs rôles à un seul utilisateur. Si le paramètre «Prise en charge de plusieurs rôles» est activé, le plug-in est vulnérable au contournement des autorisations authentifiées et, dans certains cas, à l’élévation des privilèges.

Un utilisateur à faibles privilèges peut s’attribuer ou passer à n’importe quel rôle avec un niveau d’utilisateur égal ou inférieur, ou à tout rôle n’ayant pas de niveau d’utilisateur attribué. Cela pourrait être fait en envoyant un POST demande à wp-admin/profile.php avec des paramètres de mise à jour de profil typiques et en ajoutant un aam_user_roles[] paramètre défini sur le rôle qu’ils souhaitent utiliser.

La raison pour laquelle cela a fonctionné est que le AAM_Backend_Manager::profileUpdate méthode qui attribue réellement ces rôles est déclenchée par le profile_update et user_register actions et n’a pas réussi à utiliser une vérification de capacité standard.

            add_action('profile_update', array($this, 'profileUpdate'), 10, 2);
            add_action('user_register', array($this, 'profileUpdate'), 10, 2);
    public function profileUpdate($id)
    {
        $user = get_user_by('ID', $id);

        //save selected user roles
        if (AAM::api()->getConfig('core.settings.multiSubject', false)) {
            $roles = filter_input(
                INPUT_POST,
                'aam_user_roles',
                FILTER_DEFAULT,
                FILTER_REQUIRE_ARRAY
            );

            // let's make sure that the list of roles is array

            $roles = (is_array($roles) ? $roles : array());
            $okroles=array_keys(get_editable_roles());

            // prepare the final list of roles that needs to be set
            $newRoles = array_intersect($roles, array_keys(get_editable_roles()));

            if (!empty($newRoles)) {
                //remove all current roles and then set new
                $user->set_role('');

                foreach ($newRoles as $role) {
                    $user->add_role($role);
                }
            }
        }
    }

Cela signifiait que, si le paramètre “Prise en charge de plusieurs rôles” était activé, tout utilisateur déclencherait cette méthode lors de la mise à jour de son profil. le profileUpdate la fonction vérifierait alors si des rôles étaient présents dans le aam_user_roles[] POST paramètre. Si des rôles étaient présents, il utilisait alors le WordPress get_editable_roles pour déterminer si l’utilisateur était autorisé à ajouter un rôle donné et, dans l’affirmative, accorder ce rôle à l’utilisateur sans effectuer aucune autre forme de vérification de capacité.

Par défaut, get_editable_roles renvoie tous les rôles enregistrés. Cependant, le plug-in Advanced Access Manager a ajouté un filtre pour limiter ces rôles dans le AAM_Service_UserLevelFilter::filterRoles méthode. Cette méthode parcourt chaque rôle enregistré et détermine le niveau d’utilisateur du rôle à l’aide de AAM_Core_API::maxLevel méthode.

    public function filterRoles($roles)
    {
        static $levels = array(); // to speed-up the execution

        foreach ($roles as $id => $role) {
            if (!empty($role['capabilities']) && is_array($role['capabilities'])) {
                if (!isset($levels[$id])) {
                    $levels[$id] = AAM_Core_API::maxLevel($role['capabilities']);
                }

                if (!$this->isUserLevelAllowed(true, $levels[$id])) {
                    unset($roles[$id]);
                }
            }
        }

        return $roles;
    }

AAM_Service_UserLevelFilter::filterRoles puis supprimé tous les rôles avec un niveau d’utilisateur plus élevé que l’utilisateur actuel de la liste des rôles que l’utilisateur actuel était autorisé à choisir. Par défaut, cela fonctionnait raisonnablement bien; tous les rôles intégrés ont un attribut de niveau utilisateur intégré. Malheureusement, l’attribut de niveau utilisateur était obsolète dans WordPress 3.0.

Cela signifiait que si un rôle n’avait pas d’attribut de niveau utilisateur ou avait un attribut de niveau utilisateur égal ou inférieur à celui de l’utilisateur connecté, l’utilisateur connecté pouvait s’attribuer à ce rôle.

C’était un problème dans 3 scénarios possibles:

  • Plugins avec des rôles personnalisés. Il existe plusieurs milliers de plugins qui ajoutent des rôles personnalisés dans le référentiel de plugins WordPress, et la plupart de ces plugins n’attribuent pas d’attribut de niveau utilisateur à ces rôles. Pour quelques exemples concrets, un plugin de sauvegarde pourrait ajouter un rôle qui est autorisé à restaurer des fichiers arbitraires, y compris du code malveillant ou des modifications de base de données, ou un plugin éducatif pourrait ajouter un rôle d’instructeur avec la possibilité d’insérer du HTML non filtré et d’incorporer du JavaScript malveillant. dans le site.
  • Rôles sans niveau d’utilisateur attribué. Si un rôle a été créé à partir de zéro dans Advanced Access Manager, mais qu’aucun niveau utilisateur n’est affecté, tout utilisateur disposant d’un accès au niveau abonné peut basculer vers ce rôle.
  • Rôles d’utilisateurs clonés. Si un rôle était cloné à partir d’un rôle existant (par exemple, un contributeur ou un auteur) et des fonctionnalités supplémentaires lui étaient affectées, tout utilisateur du rôle d’origine pouvait basculer vers le nouveau rôle ou s’y attribuer.

Dans l’un de ces scénarios, un attaquant à faibles privilèges pourrait potentiellement basculer vers un rôle qui lui permettait de prendre directement le contrôle d’un site ou pourrait être utilisé dans le cadre d’une chaîne d’exploit, selon les rôles configurés.


Advanced Access Manager permet également aux utilisateurs de se connecter via l’API REST WordPress. Malheureusement, le plugin aam/v1/authenticate et aam/v2/authenticate Les points de terminaison REST ont été définis pour répondre à une connexion réussie avec une copie codée en json de toutes les métadonnées sur l’utilisateur, exposant potentiellement les informations des utilisateurs à un attaquant ou à un utilisateur à faibles privilèges. Cela comprenait des éléments tels que le mot de passe haché de l’utilisateur, ses capacités et ses rôles, ainsi que toutes les métadonnées personnalisées qui auraient pu être ajoutées par d’autres plug-ins. Cela peut inclure des informations de configuration sensibles, qu’un attaquant pourrait potentiellement utiliser dans le cadre d’une chaîne d’exploitation. Par exemple, un attaquant capable de s’attribuer un rôle personnalisé à l’aide de la vulnérabilité précédente pourrait voir les capacités qui lui ont été attribuées, ce qui lui permet de planifier la phase suivante de son attaque.

Que sont les rôles et les capacités?

Tous les sites WordPress ont besoin d’un administrateur, un utilisateur qui a un contrôle total sur le site afin d’apporter des modifications et d’effectuer la maintenance. De même, un site de commerce électronique devrait permettre aux clients de se connecter pour suivre leurs commandes, et un site d’actualités devrait probablement permettre à ses journalistes de créer des articles et pourrait avoir besoin d’un éditeur. Dans ces cas, «administrateur», «éditeur», «auteur» et «client» sont les rôles.

Chacun de ces rôles est livré avec un certain ensemble de capacités. Par exemple, un administrateur aurait le manage_options capacité qui leur permet d’apporter des modifications aux options d’un site, mais il serait désastreux de donner à un client, voire à un auteur, les mêmes capacités. De même, un auteur aurait besoin de la capacité de edit_posts, mais non edit_others_posts, et un client ou un abonné ne doit avoir aucune de ces capacités.

Dans de nombreux cas, un propriétaire de site peut avoir besoin d’un contrôle plus précis sur les utilisateurs pouvant effectuer certaines actions, de sorte qu’ils peuvent utiliser un plug-in comme Advanced Access Manager pour créer des rôles personnalisés pour leurs utilisateurs. Ils pourraient ensuite attribuer les capacités qu’ils souhaitent que ces utilisateurs disposent, par exemple en permettant à un concepteur de site de edit_theme_options sans changer les autres options du site.

De plus, de nombreux plugins ajoutent des rôles spécifiques et des capacités personnalisées. Par exemple, bien que «client» ne soit pas un rôle WordPress intégré, les plugins de commerce électronique définiront un rôle de «client» spécifique doté de capacités personnalisées liées à la visualisation de l’état de leur commande et à la mise à jour de leurs informations d’adresse, tout en leur interdisant d’apporter d’autres modifications. sur le site.

La possibilité de personnaliser les rôles et les capacités à l’aide de plugins fait partie de la puissance de l’utilisation de WordPress pour une variété d’applications, y compris le commerce électronique, les systèmes de gestion de l’apprentissage, les sites d’adhésion et bien d’autres. Cependant, cette fonctionnalité étendue exige une plus grande attention au contrôle d’accès et aux capacités de la part des propriétaires de sites.

Chronologie

13 août 2020 – Wordfence Threat Intelligence termine l’analyse des vulnérabilités.
14 août 2020 – Nous publions une règle de pare-feu pour les utilisateurs de Wordfence Premium pour se protéger contre la vulnérabilité d’escalade de privilèges et fournir la divulgation à l’auteur du plugin.
15 août 2020 – Un patch complet est publié.
13 septembre 2020 – La règle de pare-feu devient disponible pour les sites utilisant la version gratuite de Wordfence.

Conclusion

Dans l’article d’aujourd’hui, nous avons détaillé deux vulnérabilités dans le plug-in Advanced Access Manager, y compris une vulnérabilité de gravité élevée qui pourrait permettre aux utilisateurs de niveau inférieur d’élever leurs privilèges. Nous vous recommandons vivement de mettre à jour vers la dernière version du plugin Advanced Access Manager, actuellement la version 6.6.2, dès que possible.

Wordfence Premium les utilisateurs sont protégés contre cette vulnérabilité depuis le 14 août 2020. Les sites utilisant encore la version gratuite de Wordfence recevront la règle de pare-feu 30 jours plus tard, le 13 septembre 2020.

Si vous connaissez un ami ou un collègue qui utilise ce plugin sur son site, veuillez lui transmettre cet avis pour aider à protéger ses sites.

Un merci spécial à l’auteur du plugin, Vasyl Martyniuk, pour sa réponse excellente et rapide à notre divulgation


Source link