
Un fuzzer de plugin WordPress de preuve de concept
Un fuzzer de plugins WordPress preuve de concept qui a conduit à la découverte de plus de 300 vulnérabilités dans des plugins WordPress installés sur près de 30 millions de sites.
La technique utilisée est décrite dans https://kazet.cc/2022/02/03/fuzzing-wordpress-plugins.html
Si vous souhaitez poursuivre la recherche, commencez par les plugins moins populaires – si un plugin a atteint au moins 10 000 installations actives entre octobre 2021 et janvier 2024, j'ai très probablement examiné les rapports du fuzzer (et la plupart des efforts ont été concentrés sur les plugins ayant au moins 20 000 installations actives). Comme le fuzzer fonctionne avec beaucoup d'aléatoire, certaines vulnérabilités dans ces plugins restent non découvertes – mais moins nombreuses.
Les rapports du fuzzer contiennent beaucoup de faux positifs – la plupart n'indiquent pas une vulnérabilité. Après avoir vu un rapport, analysez d'abord si le comportement que vous observez est effectivement une vulnérabilité ou un faux positif. Ne spammez pas WPScan/les fournisseurs avec des rapports bruts du fuzzer – fournissez plutôt une preuve de concept (PoC) à la place.
Pour des raisons évidentes, les exemples ne contiendront que des vulnérabilités déjà corrigées.
Supposons que vous fuzziez responsive-vector-maps dans la version 6.4.0 :
./bin/fuzz_object plugin responsive-vector-maps --version 6.4.0
(pour fuzzer la dernière version, omettez simplement –version).
Une fois le fuzzing terminé (ce qui prendrait 10 à 30 minutes pour ce plugin), vous pouvez appeler :
./bin/print_findings data/object_fuzz_results/
Vous verrez, entre autres :
.
Cela signifie que le fuzzer a détecté l'exécution de fopen() sur une charge utile connue. La plupart des charges utiles contiennent le mot GARLIC pour faciliter la détection automatique dans la sortie. Vous pouvez les voir ou les configurer dans docker_image/magic_payloads.php.
Ensuite, vous pouvez parcourir le code source et constater que le point de terminaison wp_ajax_rvm_import_markers utilise le contenu du fichier pour générer la sortie, vous permettant ainsi de lire des fichiers arbitraires sur le serveur : CVE-2021-24947.
Ce que vous voyez en blanc est un crash considéré comme intéressant (vous pouvez les modifier ou en ajouter de nouveaux dans crash_detectors.py). Le vert est le contexte. En bleu, vous voyez le nom du fichier de rapport (avec le nom du plugin), la popularité du plugin et le nom du point de terminaison (ici : le nom de l'action ajax). Les données en jaune indiquent quelles charges utiles ont été injectées dans quelles variables.
Supposons que vous fuzziez page-builder-add dans la version 1.4.9.4 :
./bin/fuzz_object plugin page-builder-add --version 1.4.9.4
Après avoir affiché les résultats, vous verrez une charge utile connue renvoyée :
.
Vous pouvez alors tester manuellement si cet endroit (rappelez-vous : en bleu vous avez le nom du point de terminaison, ici : le nom de la page de menu) est vulnérable aux XSS. Dans ce cas, il l'est : CVE-2021-25067.
./bin/fuzz_object plugin duplicate-page-or-post --version 1.4.6
Après avoir affiché les résultats, vous verrez update_option être appelé :
.
L'analyse du code du point de terminaison vous indiquera que cela conduit effectivement à une vulnérabilité XSS stockée : CVE-2021-25075.
Malheureusement, pour la plupart des plugins, le fuzzer ne trouve aucun crash intéressant, et pour le reste, la plupart des rapports sont des faux positifs. Par exemple, si vous voyez :
Call: wp_mail arguments={'to': '[email protected]', 'subject': '[Plugin contact] - http://GARLICGARLICGARLIC.example.com'}
Cela peut signifier que wp_mail est effectivement appelé, mais vous ne contrôlez pas le destinataire ni la majeure partie du sujet. Si vous voulez en être sûr, regardez le code source du plugin.
__GARLIC_ACCESSED__ _FILES[files] __ENDGARLIC__ – cela signifie qu'un accès
à un fichier téléchargé a été détecté. Aucune vérification supplémentaire n'est effectuée pour l'instant – pour vérifier s'il s'agit d'une vulnérabilité, regardez le code.$_GET['page'] si vous voulez qu'une page de menu particulière soit affichée.La première exécution du fuzzing ou des tests peut prendre environ une heure, car nous devons construire l'image Docker avec PHP et WordPress instrumentés.
./bin/fuzz_object plugin PLUGIN_SLUG
./bin/fuzz_object theme THEME_SLUG
Vous pouvez également installer un plugin à partir d'un fichier zip local :
./bin/fuzz_object plugin PLUGIN_FILE_NAME.zip
Pour afficher ce que le fuzzer a trouvé, utilisez :
./bin/print_findings data/object_fuzz_results/
Pour exécuter les tests, utilisez :
./bin/test
Attention : les tests sont longs (plus d'une heure) et comme ils vérifient si le fuzzer trouverait des vulnérabilités, ils échouent avec une certaine probabilité.
wpgarlic utilise pre-commit pour exécuter les linters et formater le code.
pre-commit est exécuté en CI pour vérifier que le code est correctement formaté.
Pour l'exécuter localement, utilisez :
pre-commit run --all-files
Pour configurer pre-commit afin qu'il s'exécute avant chaque commit, utilisez :
pre-commit install
Vous pouvez démarrer un environnement de test avec un seul plugin installé en utilisant :
./bin/manual_testing PLUGIN_SLUG|PLUGIN_PATH.zip [version]
Vous pouvez installer un plugin via son slug ou à partir d'un fichier zip local.
Il écoutera sur http://127.0.0.1:8001/
Il y aura deux utilisateurs de test dans la base de données :
Cet outil est une preuve de concept – cette section contient des endroits où il peut être amélioré pour trouver plus de vulnérabilités.
Vous pouvez modifier filtering.py – il contient les règles qui jugent un crash particulier comme important ou non. Si vous les modifiez, vous pouvez avoir plus de faux positifs, mais aussi trouver plus de vulnérabilités. Par exemple, le seul en-tête que je considère comme intéressant lorsqu'il est émis est l'en-tête Location, pour détecter les vulnérabilités de redirection ouverte. Ce n'est qu'une idée et vous pouvez en avoir d'autres.
Un autre fichier qui peut être intéressant à étendre est docker_image/patch_wordpress.sh. Il décrit les appels aux fonctions qui seront journalisées comme intéressantes.
Si vous souhaitez injecter d'autres charges utiles (ou modifier les probabilités avec lesquelles elles sont injectées), modifiez docker_image/magic_payloads.php et docker_image/fuzz/config.py.
crash_detector.py contient des expressions régulières qui trouvent des crashes intéressants ou des informations intéressantes (par exemple, les e-mails) exposées.
Le fuzzing des routes REST en tant qu'administrateur connecté a été désactivé car il provoquait des faux positifs. Décommentez rest_routes_admin dans config.DEFAULT_ENABLED_FEATURES pour modifier cela.
Certains plugins nécessitent d'autres (par exemple woocommerce) comme dépendance. Lors du fuzzing d'un plugin qui a une dépendance, nous voulons fuzzer uniquement le plugin choisi et ignorer les actions AJAX, routes REST et pages de menu de la dépendance. Nous voulons fuzzer les actions/routes/pages de woocommerce uniquement lorsque nous avons choisi woocommerce à fuzzer.
La liste des actions/routes/pages de dépendance est appelée listes de blocage et est répertoriée dans docker_image/blocklists/. Les fichiers nommés common contiennent les actions/routes/pages du noyau WordPress – nous ne voulons pas non plus fuzzer ceux-ci.
Pour mettre à jour ces listes de blocage, utilisez ./bin/update_blocklists.
Peut-être. Installez le plugin dans un environnement de test local (par exemple, vous pouvez utiliser celui décrit dans la section Environnement de test manuel) et analysez le bogue.
Ne présumez pas cela. Le fuzzer trouve certaines classes de vulnérabilités, mais a ses limites.
Le fuzzer ne trouve rien pour la plupart des plugins – le but de l'outil est plutôt de scanner massivement un grand nombre de plugins WordPress, pas d'effectuer des tests complets d'un seul plugin.
C'est possible. Le fuzzer choisit les charges utiles aléatoirement et introduit de l'aléatoire à d'autres endroits (par exemple, comment l'opérateur == doit se comporter dans les cas décrits dans https://kazet.cc/2022/02/03/fuzzing-wordpress-plugins.html#patched-equality).
Ouvrez un ticket Github ou envoyez-moi un e-mail : [email protected].