
Prova de conceito de exploit para uma vulnerabilidade de XSS refletido no plugin Groundhogg para WordPress, demonstrando injeção de script não autenticada por meio de parâmetros de URL manipulados.
Plugin WordPress
Nome do componente WordPress CRM, Email & Marketing Automation for WordPress | Award Winner — Groundhogg
Versão vulnerável <= 3.7.3.2
Slug do componente groundhogg
Link do componente https://wordpress.org/plugins/groundhogg/
Classe de vulnerabilidade A3: Injeção
Tipo de vulnerabilidade Cross Site Scripting (XSS)
Não autenticado
As versões 3.7.3.3 e anteriores do plugin Groundhogg contêm uma vulnerabilidade de Cross Site Scripting Refletido devido à validação de entrada insuficiente e ao processamento de escape dos parâmetros de URL. Esta vulnerabilidade ocorre ao utilizar a funcionalidade de filtro de pesquisa nos menus 'Contacts', 'Funnels' e 'Logs' do painel do plugin.
Através desta vulnerabilidade, um utilizador não autenticado pode criar um URL contendo scripts maliciosos e, quando outros utilizadores acedem a este URL, o script é executado no navegador deles, podendo levar à fuga de informações de cookies. Isto representa um sério risco de segurança, pois pode ser explorado particularmente para sequestrar sessões de utilizadores com privilégios de administrador.
Prepare um site WordPress com o plugin 'Groundhogg' <=3.7.3.2 ativado.
Como este plugin utiliza a REST API, o Permalink deve ser definido como
Post name.
Em seguida, aceder aos links de cada menu abaixo irá acionar uma vulnerabilidade de XSS Refletido.
Menu Contacts(/wp-admin/admin.php?page=gh_contacts)
http://localhost:8080/wp-admin/admin.php?page=gh_contacts&filters=W1t7ImlkIjoiIiwidHlwZSI6ImZpcnN0X25hbWUiLCJjb21wYXJlIjoiZXF1YWxzIiwidmFsdWUiOiI8aW1nIHNyYz1cInhcIiBvbmVycm9yPVwiYWxlcnQoZG9jdW1lbnQuY29va2llKVwiPiJ9XV0

Menu Funnels(/wp-admin/admin.php?page=gh_funnels)
Para reproduzir a vulnerabilidade de XSS neste menu, deve existir pelo menos 1 Funnel.
http://localhost:8080/wp-admin/admin.php?page=gh_funnels&status=inactive&include_filters=W1t7ImlkIjoiMTBjY2FmZmUtZjE0YS00MTg5LWE0MzctYjA2MTFhMTQ2ZDk1IiwidHlwZSI6InRpdGxlIiwidmFsdWUiOiI8aW1nIHNyYz1cInhcIiBvbmVycm9yPVwiYWxlcnQoZG9jdW1lbnQuY29va2llKVwiPiIsImNvbXBhcmUiOiJlcXVhbHMifV1d

Menu Logs(/admin.php?page=gh_events)
http://localhost:8080/wp-admin/admin.php?page=gh_events&tab=emails&include_filters=W1t7ImlkIjoiIiwidHlwZSI6ImZyb21fYWRkcmVzcyIsInZhbHVlIjoiPGltZyBzcmM9XCJ4XCIgb25lcnJvcj1cImFsZXJ0KGRvY3VtZW50LmNvb2tpZSlcIj4iLCJjb21wYXJlIjoiZXF1YWxzIn1dXQ

Ao realizar pesquisas com filtros nos menus 'Contacts', 'Funnels' e 'Logs' do painel do plugin Groundhogg, as definições de filtro são codificadas em Base64 antes de serem passadas como parâmetros de URL.
Por exemplo, ao definir uma pesquisa com filtro no menu 'Contacts' onde 'First Name' é definido como 'Test', o parâmetro de URL filters recebe os seguintes dados:
W1t7ImlkIjoiMjM3NzdjMGItYTQ1Ni00M2JlLWExZGMtODkzN2E1MDk0M2I5IiwidHlwZSI6ImZpcnN0X25hbWUiLCJjb21wYXJlIjoiZXF1YWxzIiwidmFsdWUiOiJUZXN0In1dXQ

Quando o valor introduzido no parâmetro de URL filters é descodificado em Base64, pode ver os seguintes dados.
[[{"id":"23777c0b-a456-43be-a1dc-8937a50943b9","type":"first_name","compare":"equals","value":"Test"}]]

Quando uma pesquisa com filtro é solicitada, a função scripts da classe Contacts_Page no ficheiro /wp-content/plugins/groundhogg/admin/contacts/contacts-page.php é executada.
Neste momento, o parâmetro de URL filters codificado em Base64 é descodificado e passado para a variável ContactSearch na área Javascript da resposta HTTP.

Portanto, pode verificar que nos dados da resposta HTTP, os dados codificados em Base64 passados para o parâmetro de URL filters são descodificados antes de serem entregues.

Posteriormente, os dados descodificados são inseridos diretamente nos elementos DOM que exibem os resultados da pesquisa com filtro através da lógica JavaScript.

Através disto, o termo de pesquisa com filtro (<img src="x" onerror="alert(document.cookie)">) introduzido no PoC é passado como uma variável no código Javascript sem processamento de escape e é inserido e executado nos elementos DOM pela lógica do cliente.


Como resultado, devido ao processamento de escape insuficiente dos dados de pesquisa com filtro, valores contendo scripts maliciosos podem ser executados diretamente, e esta vulnerabilidade ocorre da mesma forma em todos os menus 'Contacts', 'Funnels' e 'Logs'.