
Фаззер плагинов WordPress для проверки концепции
Доказательство концепции фаззера плагинов WordPress, который привел к обнаружению более 300 уязвимостей в плагинах WordPress, установленных почти на 30 миллионов сайтов.
Используемая методика описана в https://kazet.cc/2022/02/03/fuzzing-wordpress-plugins.html
Если вы хотите продолжить исследование, начните с менее популярных плагинов — если у плагина было не менее 10 000 активных установок в период с октября 2021 по январь 2024, я, скорее всего, просмотрел отчеты фаззера (и основное внимание уделялось плагинам, имеющим не менее 20 000 активных установок). Поскольку в работе фаззера много случайности, некоторые уязвимости в этих плагинах остаются необнаруженными — но их меньше.
Отчеты фаззера содержат много ложных срабатываний — большинство из них не указывают на уязвимость. Увидев отчет, сначала проанализируйте, является ли наблюдаемое поведение действительно уязвимостью или ложным срабатыванием. Не засоряйте WPScan/разработчиков сырыми отчетами фаззера — вместо этого предоставьте PoC-эксплойт.
По понятным причинам примеры будут содержать только уже исправленные уязвимости.
Предположим, вы фаззите responsive-vector-maps версии 6.4.0:
./bin/fuzz_object plugin responsive-vector-maps --version 6.4.0
(чтобы фаззить последнюю версию, просто опустите --version).
После завершения фаззинга (который займет 10-30 минут для этого плагина) вы можете вызвать:
./bin/print_findings data/object_fuzz_results/
Вы увидите, среди прочего:

Это означает, что фаззер обнаружил выполнение fopen() с известной полезной нагрузкой.
Большинство полезных нагрузок содержат слово GARLIC для облегчения автоматического обнаружения
в выводе. Вы можете просмотреть или настроить их в docker_image/magic_payloads.php.
Затем вы можете изучить исходный код и увидеть, что конечная точка wp_ajax_rvm_import_markers
действительно использует содержимое файла для формирования вывода, что позволяет читать произвольные файлы
на сервере: CVE-2021-24947.
То, что вы видите белым — это сбой, считающийся интересным (вы можете изменить их или добавить новые
в crash_detectors.py). Зеленым показан контекст. Синим — имя файла отчета
(с именем плагина), популярность плагина и имя конечной точки (здесь: имя ajax-действия).
Данные желтым цветом — это то, какие полезные нагрузки были внедрены в какие переменные.
Предположим, вы фаззите page-builder-add версии 1.4.9.4:
./bin/fuzz_object plugin page-builder-add --version 1.4.9.4
После вывода результатов вы увидите, что известная полезная нагрузка была отражена обратно:

Затем вы можете вручную проверить, действительно ли это место (помните: синим указано имя конечной точки, здесь: имя страницы меню) уязвимо к XSS. В данном случае это так: CVE-2021-25067.
./bin/fuzz_object plugin duplicate-page-or-post --version 1.4.6
После вывода результатов вы увидите вызов update_option:

Анализ кода конечной точки покажет, что это действительно приводит к уязвимости сохраненного XSS: CVE-2021-25075.
К сожалению, для большинства плагинов фаззер не находит интересных сбоев, а для остальных большинство отчетов являются ложными срабатываниями. Например, если вы видите:
Call: wp_mail arguments={'to': '[email protected]', 'subject': '[Plugin contact] - http://GARLICGARLICGARLIC.example.com'}
Это может означать, что wp_mail действительно вызывается, но получатель и большая часть темы
не контролируются вами. Чтобы быть уверенным, посмотрите исходный код плагина.
__GARLIC_ACCESSED__ _FILES[files] __ENDGARLIC__ — это означает, что был обнаружен
доступ к загруженному файлу. Дополнительные проверки пока не проводятся — чтобы определить, является ли это
уязвимостью, посмотрите код.$_GET['page'], если хотите, чтобы отображалась определенная страница меню.Первый запуск фаззинга или тестов может занять около часа, потому что нам нужно собрать Docker-образ с инструментированным PHP и WordPress.
./bin/fuzz_object plugin PLUGIN_SLUG
./bin/fuzz_object theme THEME_SLUG
Вы также можете установить плагин из локального zip-файла:
./bin/fuzz_object plugin PLUGIN_FILE_NAME.zip
Для вывода того, что нашел фаззер, используйте:
./bin/print_findings data/object_fuzz_results/
Для запуска тестов используйте:
./bin/test
Предупреждение: тесты выполняются долго (более часа), и поскольку они проверяют, найдет ли фаззер уязвимости, они могут завершиться с некоторой вероятностью неудачи.
wpgarlic использует pre-commit для запуска линтеров и форматирования кода.
pre-commit выполняется на CI для проверки корректности форматирования кода.
Для локального запуска используйте:
pre-commit run --all-files
Для настройки pre-commit так, чтобы он запускался перед каждым коммитом, используйте:
pre-commit install
Вы можете запустить тестовую среду с одним установленным плагином с помощью:
./bin/manual_testing PLUGIN_SLUG|PLUGIN_PATH.zip [version]
Вы можете установить плагин по его слагу или из локального zip-файла.
Он будет прослушивать http://127.0.0.1:8001/
В базе данных будут два тестовых пользователя:
Этот инструмент является доказательством концепции — в этом разделе указаны места, которые можно улучшить для нахождения большего количества уязвимостей.
Вы можете отредактировать filtering.py — он содержит правила, по которым конкретный сбой считается
важным или нет. Если вы их измените, может появиться больше ложных срабатываний, но вы также сможете найти больше уязвимостей.
Например, единственный заголовок, который я считаю интересным при отправке, — это заголовок Location
для обнаружения уязвимостей Open Redirect. Это всего лишь одна идея, и у вас могут быть другие.
Еще один файл, который стоит расширить, — docker_image/patch_wordpress.sh. Он описывает,
вызовы каких функций будут логироваться как интересные.
Если вы хотите внедрять другие полезные нагрузки (или изменить вероятности их внедрения),
отредактируйте docker_image/magic_payloads.php и docker_image/fuzz/config.py.
crash_detector.py содержит регулярные выражения для поиска интересных сбоев или интересной
информации (например, адресов электронной почты).
Фаззинг REST-маршрутов от имени администратора был отключен, так как приводил к ложным срабатываниям.
Раскомментируйте rest_routes_admin в config.DEFAULT_ENABLED_FEATURES, чтобы изменить это.
Некоторым плагинам требуются другие (например, woocommerce) в качестве зависимости. При фаззинге плагина с зависимостью мы хотим фаззить только выбранный плагин и пропустить AJAX-действия, REST-маршруты и страницы меню зависимости. Мы хотим фаззить действия/маршруты/страницы woocommerce только тогда, когда выбрали woocommerce для фаззинга.
Список действий/маршрутов/страниц зависимостей называется блок-листами и указан в docker_image/blocklists/.
Файлы с именем common содержат основные действия/маршруты/страницы WordPress — их мы тоже не хотим фаззить.
Чтобы обновить эти блок-листы, используйте ./bin/update_blocklists.
Возможно. Установите плагин в локальной тестовой среде (например, вы можете использовать описанную в разделе Среда ручного тестирования) и проанализируйте ошибку.
Не делайте такого предположения. Фаззер находит некоторые классы уязвимостей, но у него есть ограничения.
Фаззер ничего не находит для большинства плагинов — цель инструмента скорее в массовом сканировании большого количества плагинов WordPress, а не в проведении всесторонних тестов одного плагина.
Такое возможно. Фаззер выбирает полезные нагрузки случайным образом и вносит случайность в других местах (например,
как должен вести себя оператор == в случаях, описанных в
https://kazet.cc/2022/02/03/fuzzing-wordpress-plugins.html#patched-equality).
Создайте тикет на Github или напишите мне: [email protected].