iThemes Security est une extension bien connue dans la communauté WordPress depuis des années. Il y a 2 semaines, j’ai découvert une faille de sécurité dans leur module “Hide Backend”, divulguant la page de connexion.
Cette vulnérabilité ByPass a été corrigée en 7.9.1, tenez vous à jour si vous l’utilisez.
ITS (iThemes Security) < 7.9.1 souffre d’un bug de lecture de GET/POST/REQUEST pouvant mener à la page wp-login de WordPress. Le but de ce module est donc cassé.
La vulnérabilité n’ouvrira pas de porte sur votre site, pas plus que la fonctionnalité native ne le fait. Donc ce n’est pas un grand danger mais quand on active un module qui nous dit qu’il va protéger le backend, on s’attend à ce que le module… protège le backend.
Timing du Report :
- 05 Avril 21 : Report de la vulnérabilité
- 06 Avril 21 : Vulnérabilité confirmée avec un patch
- 07 Avril 21: Le patch ne fonctionne pas, nouveau patch reçu
- 08 Avril 21 : Patch valide et confirmé.
- 14 Avril 21 : Versions mises à jour
- 20 Avril 21 : Récompense Bounty
Vulnérabilité expliquée
- La méthode de requête HTTP est
POST
- L’URL pointe sur
wp-login.php
- Le paramètre dans l’URL est “
action=postpass
” (donc c’est un param GET) - Le paramètre dans BODY est “
action=login
” (donc c’est param POST)
L’extension va lire le GET
et laissera passer puisque c’est autorisé (voir ci-dessous), mais WordPress va gérer le param POST
et affichera alors le formulaire de connexion.
Code de ITS 7.9.0
Ce sont mes commentaires et je ne montre que les lignes utiles à l’explication.
[pastacode lang=”php” manual=”%2F*%20https%3A%2F%2Fplugins.svn.wordpress.org%2Fbetter-wp-security%2Ftags%2F7.9.0%2Fcore%2Fmodules%2Fhide-backend%2Fclass-itsec-hide-backend.php%20*%2F%0A%0A%2F%2F%20Line%2324%20On%20ITS%20init%2C%20handle%20the%20page%20request%0Aadd_action(%20’itsec_initialized’%2C%20array(%20%24this%2C%20’handle_specific_page_requests’%20)%2C%201000%20)%3B%0A%0A%2F%2F%20Line%2395%20Handle%20the%20requested%20path%0A%24this-%3Ehandle_request_path(%20%24path%20)%3B%0A%0A%2F%2F%20Line%23107-109%20Since%20we%20are%20requesting%20’wp-login.php’%20page%2C%20we%20trigger%20this%20condition%0A%7D%20elseif%20(%20in_array(%20%24request_path%2C%20array(%20’wp-login’%2C%20’wp-login.php’%20)%20)%20)%20%7B%0A%24this-%3Ehandle_canonical_login_page()%3B%0A%7D%0A%0A%2F%2F%20Line%23137%20If%20%24_GET%5B’action’%5D%20is%20equal%20to%20’postpass’%2C%20do%20nothing.%0Aprivate%20function%20handle_canonical_login_page()%20%7B%0A%24action%20%3D%20isset(%20%24_GET%5B’action’%5D%20)%20%3F%20%24_GET%5B’action’%5D%20%3A%20”%3B%0A%0Aif%20(%20’postpass’%20%3D%3D%3D%20%24action%20)%20%7B%0Areturn%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Vous comprenez peut-être mieux maintenant, le action=postpass
est le bypass. Voilà pourquoi vous en devez pas utiliser 2 méthodes de lectures des paramètres.
WordPress fait ça :
[pastacode lang=”php” manual=”%2F%2F%20%2Fwp-login.php%23367%0A%24action%20%3D%20isset(%20%24_REQUEST%5B’action’%5D%20)%20%3F%20%24_REQUEST%5B’action’%5D%20%3A%20’login’%3B” message=”” highlight=”” provider=”manual”/]
Donc si $_REQUEST
est lu, vous devez le lire aussi.
Maintenant, rappelons-nous ce qu’est $_REQUEST
. C’est un tableau global qui contient à la fois les valeurs de $_GET
et $_POST
. L’ordre par défaut du mélange est configuré par le serveur et est 90% du temps GP
, signifiant “GET + POST”. Mais vous pouvez tomber sur des configurations en PG
.
Patchs
Le premier patch remplaçait $_GET['action']
par $_REQUEST['action']
ce qui semble bon à première vue mais pas vraiment si le serveur est configuré en PG
, la faille est toujours là, WordPress chargera la page de connexion, encore.
Saviez-vous que WordPress va forcer que configuration en GP
? Maintenant vous savez, c’est fait avec wp_magic_quotes() , cool non ? Mais cela ne va pas aider ITS car le plugin lit les valeurs avant son usage qui est fait avant setup_theme
, donc ITS a fait un second patch juste pour changer le hook sur setup_theme
.
C’est maintenant patché en 7.9.1, mettez à jour.
Il reste une chose à savoir…
Ce module a été développé pour empêcher les bots et scripts d’entrer ou de brute-forcer la page de connexion de WordPress. Il n’a pas été fait pour qu’un humain ne la trouve pas, donc, en tant qu’humain, vous pouvez trouver un moyen d’obtenir le jeton secret de la page protégée par ITS avec… Google.
Quand vous connaissez le nom de la nouvelle page de connexion, vous êtes redirigé vers la page de connexion avec le nouveau paramètre agissant tel un jeton secret, il s’agit de itsec-hb-token
. Puisque ce paramètre est en GET
, Google peut l’indexer, voilà pourquoi vous pouvez trouver ces jetons sur les moteurs de recherche.
Disons que je suis un humain (en vrai j’en suis un…) et que je cible example.com. Je vais chercher “site:example.com inurl:itsec-hb-token
” et je peux trouver des choses avec le jeton dedans. Cliquez simplement dessus et s’il est encore valide et que ITS est activé, vous obtiendrez le cookie itsec-hb-token
. Visitez maintenant la page wp-login.php
, vous êtes autorisé.
Ceci ne sera pas corrigé par ITS car cela signifie un redéveloppement complet du module, et comme il a été dit, il a été fait pour bloquer les bots et scripts seulement.