Une question ? Contactez notre standard : 01 41 91 58 61 - Un incident de sécurité ? Faites-vous assister : 01 47 28 38 39

Trois vulnérabilités présentes dans des plugins WordPress impactant plus de 100,000 applications Web ont récemment été découvertes au sein du pôle Évaluation d’Intrinsec. Ces défauts de sécurité permettent à des attaquants de réaliser différentes attaques : l’un permet d’effectuer des injections SQL pouvant conduire à la suppression de fichiers arbitraires, un autre des attaques de type XSS, et le dernier, d’exploiter des défauts d’autorisation menant à l’usurpation d’identité bancaire.

Un plugin WordPress est un module additionnel pouvant étendre les fonctionnalités d’une application Web basée sur WordPress

À l’issue de ces découvertes de vulnérabilités, le CERT d’Intrinsec a communiqué les advisories (disponibles ci-dessous) aux éditeurs de plugins ainsi qu’à WordPress et WordFence. Le traitement de ces avis a conduit à l’obtention de trois numéros de CVE faisant l’objet de cet article.

Inscrites dans les catégories « Injection » et « Broken Access Control » du Top 10 OWASP 2021, ces vulnérabilités reflètent ce que l’on retrouve dans le cadre de prestations de tests d’intrusion. Ce type de mission s’inscrit dans les activités de tests d’intrusion externe du pôle Évaluation où des applications basées sur des CMS comme WordPress sont régulièrement auditées. La réalisation des tests techniques suit le Testing Guide de l’OWASP enrichi d’une méthodologie spécifique aux CMS et d’outils, développés en interne, propres à l’évaluation d’application basées sur des CMS en boîte blanche, c’est-à-dire avec un accès complet au code source. Ce cocktail unique permet aux consultants d’analyser en profondeur le niveau de sécurité de ces applications.

D’une injection SQL à la suppression de fichiers arbitraires

L’extension WP-Bannerize permet d’ajouter des bannières aux pages d’une application. Cependant, la gestion des bannières est vulnérable à des injections SQL. Les fonctions affectées correspondent aux actions de modification d’une bannière (fonction « updateBannerFromLocal » dans le code source de l’extension), de leur déplacement dans la corbeille (« setBannerToTrash »), de leur récupération depuis la corbeille (« unsetBannerToTrash »), et de leur suppression définitive (« deleteBanner »). Elles présentent le même défaut : l’absence de filtre pour l’entrée utilisateur « id ». Ce vecteur d’attaque permet à un utilisateur malveillant d’injecter du code afin de modifier le comportement de la requête SQL. L’extrait de code ci-dessous, correspondant à la fonction « updateBannerFromLocal » appelée lors de la mise à jour d’une bannière, illustre cette vulnérabilité où le paramètre POST « id » est inclu dans la requête SQL ligne 5 sans être filtré. Ce comportement est similaire à celui des autres fonctions vulnérables énoncées.

Extrait de “Classes/wpBannerizeAdmin.php” – fonction “updateBannerFromLocal”


L’exploitation de ce type de vulnérabilité pourrait notamment conduire à la compromission de la confidentialité de la base de données de l’application. Cependant, il est possible d’aller plus loin. En effet, la fonction appelée lors de la suppression définitive d’une bannière, « deleteBanner », dont le code figure ci-dessous, comporte deux requêtes SQL aux lignes 5 et 7, chacune employant la même entrée utilisateur non filtrée « id » vue précédemment. Lorsque la première requête retourne 1, la condition à la ligne 6 est vérifiée et la deuxième requête SQL est à son tour exécutée, ligne 7 ; son résultat est ensuite passé en argument à la fonction de suppression de fichier « unlink » ligne 8.

Extrait de Classes/wpBannerizeAdmin.php” – fonction “deleteBanner”

Ainsi, en parvenant à concevoir un code malveillant retournant la valeur 1 avec la première requête puis le chemin d’un fichier choisi par l’attaquant avec la deuxième, ce dernier serait alors supprimé.

Dans le cadre de la preuve de concept, l’élaboration du code malveillant à injecter a suivi le raisonnement suivant :

  • En injectant une unique charge malveillante (payload) il faut obtenir deux valeurs différentes ;
  • Une différence identifiée entre les deux requêtes SQL où la payload est injectée est le moment d’exécution ;
  • Suivant le moment où une requête est exécutée, son comportement peut être adapté : si la date d’exécution est inférieure à une date donnée, alors un comportement A est exécuté, sinon un comportement B est effectué ;
  • L’écart de temps entre l’exécution des deux requêtes peut être contrôlé par la fonction SQL « sleep ».

Cette réflexion a abouti au résultat suivant : lors de la requête POST de l’attaquant à T0, une date de référence Tref est fixée 2 secondes dans le futur et le code SQL malveillant comporte la condition suivante :

  • Si la date actuelle T est antérieure à Tref, alors une pause de 4 secondes est effectuée et la valeur 1 est retournée ;
  • Sinon (date actuelle T postérieure à Tref) le chemin du fichier à supprimer est retourné.

Détail de l'exploitation de l'injection SQL menant à la suppression d'un fichier
Détail de l’exploitation de l’injection SQL menant à la suppression d’un fichier

L’intérêt de cette faille est double pour un attaquant : il est possible d’extraire du contenu de la base de données de l’application en tant qu’utilisateur authentifié disposant d’un accès au tableau de bord, mais également de supprimer des fichiers sur lesquels l’utilisateur propriétaire du service Web dispose des droits. La suppression de fichiers peut notamment rendre le site indisponible et conduire à un déni de service ou encore, peut permettre de contourner des restrictions d’autorisation en supprimant le fichier « .htaccess » dans le cas d’un serveur Apache par exemple, qui définit certaines propriétés d’accessibilité.

XSS Réfléchie sur le tableau de bord administrateur

Le plugin FV Flowplayer Video Player permet d’inclure des vidéos dans les pages d’une application. Une fonctionnalité de statistiques est disponible sur le tableau de bord des administrateurs page fv_player_stats, cependant cette dernière est vulnérable à des attaques de type XSS réfléchies.

Extrait de view/stats.php

En effet, le paramètre GET « player_id » est utilisé sans vérification ni filtrage de son contenu ligne 7. Un attaquant pourrait alors injecter du code javascript arbitraire qui serait intégré dans le code HTML de la page généré par le serveur puis exécuté sur le navigateur de la victime. Cependant il est nécessaire que la variable « fv_single_player_stats_data » soit définie pour remplir la condition ligne 4 et atteindre la ligne vulnérable 7. Les contraintes à respecter dictées ligne 1 pour que cette variable soit définie sont :

  1. Le paramètre GET « player_id » doit exister ;
  2. La valeur du paramètre GET « player_id » doit être telle que la fonction intval($_GET[‘player_id’]) renvoie une valeur non nulle.

Cette deuxième contrainte fait appel à la fonction « intval » qui convertit son argument en valeur numérique entière. Pour que celle-ci soit validée, c’est-à-dire que la valeur retournée soit différente de 0, il suffit que la chaîne passée en argument commence par un chiffre. La valeur numérique retournée par « intval » sera celle du nombre qui préfixe la chaîne de caractères. Si la chaîne passée en argument comporte du code HTML, celui-ci sera alors inséré ligne 7 et interprété.

Détail de l'exploitation de la XSS
Détail de l’exploitation de la XSS

Un attaquant pourrait ainsi générer un lien comportant une charge malveillante au niveau de l’entrée « player_id », qui s’exécuterait sur le navigateur de la victime ayant cliqué sur le lien. Les cibles de cette attaque sont les utilisateurs administrateurs étant les seuls à disposer d’un accès à la page des statistiques de ce plugin. Le code malveillant pourrait engendrer, à l’insu de la victime, la réalisation d’actions d’administration comme la création d’un compte administrateur par exemple.

Défaut d’autorisation menant à l’usurpation d’identité bancaire

Le plugin Stripe For WooCommerce permet d’enrichir l’offre des méthodes de paiements pour les sites de e-commerces basés sur WooCommerce. Cependant un manque de vérification des capabilities permet à tout utilisateur authentifié de configurer son propre identifiant « customer_id ». En effet, lorsque qu’un utilisateur met à jour les données de son profil, la fonction vulnérable « save » , dont un extrait figure ci-dessous, est appelée.

Extrait de “/admin/class-wc-stripe-admin-user-edit.php”

Le « customer_id » d’un utilisateur correspond à l’identifiant utilisé pour Stripe et est stocké dans les paramètres du compte WordPress ; un utilisateur sauvegardant des méthodes de paiement sur l’application WordPress pourra alors faire appel à celles-ci lors d’un paiement sans entrer à nouveau leurs informations. Quant au « user_id », il s’agit de l’identifiant WordPress de l’utilisateur. La fonction « save » permet notamment de modifier la valeur du « customer_id » pour son propre « user_id », excepté pour les administrateurs pouvant également modifier les profils des autres utilisateurs. Lors d’une modification de l’identifiant Stripe, la fonction « save » appelle la fonction « wc_stripe_save_customer » ligne 12 pour mettre à jour la valeur ainsi que la fonction « WC_Stripe_Customer_Manager::sync_payment_methods » ligne 27 pour synchroniser les moyens de paiement associés à ce compte.

Toutefois, aucune vérification au niveau des capabilites d’un utilisateur n’est effectuée durant l’action de mise à jour de l’identifiant Stripe. Un attaquant pourrait alors modifier son propre identifiant « customer_id ». En remplaçant cet identifiant par celui d’un autre utilisateur, trouvé à l’aide d’autres attaques, il accéderait aux méthodes de paiement enregistrées par l’utilisateur légitimement lié à ce « customer_id » lors de son prochain paiement.

Impact de l'exploitation de la vulnérabilité
Résultat de l’exploitation de la vulnérabilité

L’exploitation de cette vulnérabilité impacterait négativement l’image de marque de l’entreprise de e-commerce, et impliquerait également une perte de confidentialité et d’intégrité des données.

Pour plus d’informations sur les prestations de tests d’intrusion externe, contactez-nous !

Article écrit par @Margaux Dabert, Consultante Sécurité chez Intrinsec