
Эксплойт для проверки концепции, использующий отражённую XSS-уязвимость в плагине Groundhogg для WordPress, демонстрирующий неаутентифицированную инъекцию скриптов через специально сформированные параметры URL.
Плагин WordPress
Название компонента WordPress CRM, Email & Marketing Automation for WordPress | Award Winner — Groundhogg
Уязвимая версия <= 3.7.3.2
Слаг компонента groundhogg
Ссылка на компонент https://wordpress.org/plugins/groundhogg/
Класс уязвимости A3: Инъекции
Тип уязвимости Межсайтовый скриптинг (XSS)
Без аутентификации
Версии 3.7.3.3 и ниже плагина Groundhogg содержат уязвимость отражённого межсайтового скриптинга (Reflected XSS), вызванную недостаточной проверкой вводимых данных и обработкой экранирования параметров URL. Эта уязвимость возникает при использовании функции фильтрации поиска в меню «Контакты», «Воронки» и «Журналы» панели управления плагина.
Благодаря этой уязвимости неаутентифицированный пользователь может создать URL-адрес, содержащий вредоносные скрипты, и когда другие пользователи переходят по этому URL-адресу, скрипт выполняется в их браузере, что потенциально может привести к утечке информации из файлов cookie. Это представляет серьёзный риск для безопасности, поскольку может быть использовано, в частности, для перехвата сеансов пользователей с правами администратора.
Подготовьте сайт WordPress с активированным плагином 'Groundhogg' <=3.7.3.2.
Поскольку этот плагин использует REST API, постоянная ссылка (Permalink) должна быть установлена в значение
Имя записи.
Затем переход по ссылкам для каждого меню ниже вызовет уязвимость отражённого XSS.
Меню «Контакты»(/wp-admin/admin.php?page=gh_contacts)
http://localhost:8080/wp-admin/admin.php?page=gh_contacts&filters=W1t7ImlkIjoiIiwidHlwZSI6ImZpcnN0X25hbWUiLCJjb21wYXJlIjoiZXF1YWxzIiwidmFsdWUiOiI8aW1nIHNyYz1cInhcIiBvbmVycm9yPVwiYWxlcnQoZG9jdW1lbnQuY29va2llKVwiPiJ9XV0

Меню «Воронки»(/wp-admin/admin.php?page=gh_funnels)
Чтобы воспроизвести уязвимость XSS в этом меню, должна существовать как минимум 1 воронка.
http://localhost:8080/wp-admin/admin.php?page=gh_funnels&status=inactive&include_filters=W1t7ImlkIjoiMTBjY2FmZmUtZjE0YS00MTg5LWE0MzctYjA2MTFhMTQ2ZDk1IiwidHlwZSI6InRpdGxlIiwidmFsdWUiOiI8aW1nIHNyYz1cInhcIiBvbmVycm9yPVwiYWxlcnQoZG9jdW1lbnQuY29va2llKVwiPiIsImNvbXBhcmUiOiJlcXVhbHMifV1d

Меню «Журналы»(/admin.php?page=gh_events)
http://localhost:8080/wp-admin/admin.php?page=gh_events&tab=emails&include_filters=W1t7ImlkIjoiIiwidHlwZSI6ImZyb21fYWRkcmVzcyIsInZhbHVlIjoiPGltZyBzcmM9XCJ4XCIgb25lcnJvcj1cImFsZXJ0KGRvY3VtZW50LmNvb2tpZSlcIj4iLCJjb21wYXJlIjoiZXF1YWxzIn1dXQ

При выполнении фильтрующего поиска в меню «Контакты», «Воронки» и «Журналы» панели управления плагина Groundhogg параметры фильтрации кодируются в Base64 перед передачей в качестве параметров URL.
Например, при настройке фильтрующего поиска в меню «Контакты», где «Имя» установлено в значение «Test», параметр URL filters получает следующие данные:
W1t7ImlkIjoiMjM3NzdjMGItYTQ1Ni00M2JlLWExZGMtODkzN2E1MDk0M2I5IiwidHlwZSI6ImZpcnN0X25hbWUiLCJjb21wYXJlIjoiZXF1YWxzIiwidmFsdWUiOiJUZXN0In1dXQ

Когда значение, введённое в параметр URL filters, декодируется из Base64, можно увидеть следующие данные.
[[{"id":"23777c0b-a456-43be-a1dc-8937a50943b9","type":"first_name","compare":"equals","value":"Test"}]]

Когда запрашивается фильтрующий поиск, выполняется функция scripts класса Contacts_Page в файле /wp-content/plugins/groundhogg/admin/contacts/contacts-page.php.
В этот момент параметр URL filters, закодированный в Base64, декодируется и передаётся переменной ContactSearch в области JavaScript HTTP-ответа.

Таким образом, можно убедиться, что в данных HTTP-ответа данные, закодированные в Base64 и переданные в параметр URL filters, декодируются перед доставкой.

Впоследствии декодированные данные напрямую вставляются в элементы DOM, отображающие результаты фильтрующего поиска, с помощью логики JavaScript.

Благодаря этому условие фильтрующего поиска (<img src="x" onerror="alert(document.cookie)">), введённое в PoC, передаётся как переменная в коде JavaScript без обработки экранирования и вставляется и выполняется в элементах DOM клиентской логикой.


В результате из-за недостаточной обработки экранирования данных фильтрующего поиска значения, содержащие вредоносные скрипты, могут выполняться напрямую, и эта уязвимость возникает одинаковым образом во всех меню «Контакты», «Воронки» и «Журналы».