Ataque à cadeia de fornecimento BdThemes através de JSON contaminado
Uma cadeia de fornecimento comprometida no ecossistema BdThemes permitiu executar JavaScript malicioso nas sessões autenticadas de administradores do WordPress. O ataque está a explorar respostas JSON remotas destinadas a banners promocionais, sem alterar qualquer ficheiro do plugin no repositório oficial ou no disco do site; por isso, pode não detetar-se com verificações de integridade baseadas em ficheiros.
Os sete plugins afetados estão temporariamente fechados no diretório de plugins do WordPress enquanto decorre a inspeção. Se tens algum instalado, trata o incidente como uma potencial comprometimento completo do site: o código está a criar administradores indevidos, a instalar uma webshell e a estabelecer persistência no servidor.
Risco imediato
A versão vulnerável do componente não tem correção indicada. Os endpoints remotos passaram a devolver JSON limpo em 8 de agosto de 2026, mas isso não remove contas, plugins, ficheiros MU nem opções da base de dados que já tenham sido criados.
Como funciona a cadeia de ataque
Os plugins BdThemes incluem o Biggopti, um componente interno que está a obter banners promocionais de uma API e a mostrá-los no painel de administração. A API serve ficheiros JSON estáticos a partir de um bucket DigitalOcean Spaces protegido por Cloudflare, não de um servidor de aplicações dinâmico; o acesso de escrita ao bucket foi comprometido e as respostas legítimas foram substituídas por registos preparados para explorar XSS.
O script do Biggopti é colocado em fila durante admin_init, pelo que está a correr em todos os carregamentos de páginas wp-admin para cada plugin que o usa. Ao construir o contentor HTML no DOM, o valor remoto display_id concatena-se diretamente no atributo id, sem escape no lado do cliente; o campo data-display-id do mesmo código é escapado, o que confirma que a falha se limita à injeção do atributo id.
// display_id vem da resposta JSON remota e não é escapado
var f = t.display_id || t.id || "default";
var m = "bdt-admin-biggopti-api-biggopti-" + f;
A = 'id="' + m + '"'; // valor injetado no DOM
// Noutro atributo, o código já escapava caracteres HTML
function escapeAttribute(value) {
return (value || "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}A injeção de display_id está a sair do atributo id e a acrescentar um handler onanimationstart. Uma animação CSS dispara-o em cerca de 10 milissegundos, silenciosamente, assim que um administrador abre qualquer página do painel. Embora versões posteriores tenham acrescentado um sanitizador com DOMParser para o campo de conteúdo do banner, removendo tags e handlers perigosos, o atributo id continuou sem escape.
A falha foi introduzida em 1 de março de 2026, no Prime Slider 4.1.9, e acabou por aplicar-se a outros plugins. Não é necessária uma atualização do plugin para o site ficar exposto: basta que um administrador esteja a carregar o painel enquanto a resposta JSON maliciosa está disponível. A execução está a acontecer no navegador autenticado, o que dá ao script os nonces e as permissões dessa sessão.
Plugins e vulnerabilidade afetados
A vulnerabilidade é uma XSS através do parâmetro display_id da API Sigmative na biblioteca Biggopti, classificada com CVSS 5,4, de gravidade média e sem correção. Um atacante que controle o servidor da API consegue injetar scripts arbitrários nas páginas que mostram o registo contaminado; no cenário observado, está a visar especificamente administradores autenticados.
- Element Pack Addons for Elementor – Elementor Widgets, Elementor Templates, Elementor Addons –
bdthemes-element-pack-lite - Live Copy Paste for Elementor – Cross Domain Copy Paste & Page Duplicator –
live-copy-paste - Pixel Gallery Addons for Elementor – Easy Grid, Creative Gallery, Drag and Drop Grid, Custom Grid Layout, Portfolio Gallery –
pixel-gallery - Prime Slider Addons for Elementor – Widgets, Templates & Elementor Addons –
bdthemes-prime-slider-lite - Smart Admin Assistant – Dashboard and Site Enhancements –
smart-admin-assistant - Ultimate Post Kit Addons for Elementor –
ultimate-post-kit - Ultimate Store Kit – Addon For WooCommerce, EDD and Elementor –
ultimate-store-kit
Payloads observados e impacto
O handler injetado está a descarregar scripts externos conforme o endpoint utilizado pelo plugin. O payload principal, w2.js, é servido aos plugins que usam api-data-all-records; o alternativo, x.js, surge alojado diretamente na infraestrutura BdThemes para vítimas que usam api-data-records. Ambos procuram criar acesso administrativo persistente e comunicar os resultados a uma infraestrutura de comando e controlo (C2).
Payload principal: w2.js
- Validação do C2: contacta
ia-cdn[.]com/fz/c, enviando a origem do site para receber instruções de seleção. O script termina se o C2 responder com o estadoskipoudone. - Criação de administrador indevido: usa o
X-WP-Noncepresente na sessão administrativa para criar um administrador através da REST API do WordPress. Se falhar, recorre a submissões de formulários normais. - Instalação de webshell: descarrega do C2 um ZIP que se faz passar por plugin e instala-o pelo formulário padrão de carregamento de plugins. Usa o slug
wp-smart-thumbnails, ou outro nome neutro semelhante, e contém a webshellemer-run.php, chamada diretamente por URL. - Persistência em MU-plugins: ao chamar
emer-run.php, instala dois módulos na diretoria de plugins obrigatórios. As amostras observadas tinham datas retroativas para setembro de 2025, procurando misturar-se com timestamps legítimos; os nomes dos ficheiros podem variar entre infeções. - Backdoor de magic login: o primeiro módulo permite entrar como administrador sem autenticação através de
?_wplogin=<token>e visa o administrador registado há mais tempo no site. - Ocultação anti-análise: o segundo módulo usa hooks nas queries da base de dados do WordPress para esconder as contas indevidas da lista administrativa de utilizadores e reduzir os totais de utilizadores em conformidade.
- Exfiltração: envia os resultados de cada fase para o C2 através de
navigator.sendBeacon.
Payload alternativo: x.js
O x.js está a calcular credenciais administrativas determinísticas a partir do hostname da vítima. Calcula um hash inteiro do hostname, converte o valor absoluto para base 36 e usa os primeiros seis caracteres: o utilizador segue o padrão bd_ seguido desse hash e a palavra-passe segue Bd@26! mais o hash e o sufixo x. A conta associa-se a um endereço com domínio @wordpress.org.
// Lógica defensivamente reproduzida para identificar o padrão de credenciais
function makeCreds(host) {
let hash = 0;
for (let i = 0; i < host.length; i++) {
hash = ((hash << 5) - hash + host.charCodeAt(i)) | 0;
}
const suffix = Math.abs(hash).toString(36).slice(0, 6);
return {
user: 'bd_' + suffix,
pass: 'Bd@26!' + suffix + 'x'
};
}Como as credenciais são previsíveis, os atacantes não precisam de manter uma lista central de sites comprometidos: podem calculá-las quando conhecem o domínio. O script está a criar a conta pela página /wp-admin/user-new.php, extrai o nonce da página, usa a função de logout encontrada no HTML e guarda uma flag em localStorage quando consegue concluir a tentativa. Depois está a enviar para o C2 o estado, o utilizador, a palavra-passe, a origem, o URL de logout e o URL da página, recorrendo a sendBeacon ou a fetch com keepalive como alternativa.
Indicadores de comprometimento
A investigação deve cruzar os indicadores de rede, sistema de ficheiros e base de dados. Os endpoints Sigmative contaminados estão a devolver JSON limpo, mas os artefactos que o payload instalou podem continuar presentes e devem procurar-se ativamente.
Recursos externos
- Payload principal:
ia-cdn[.]com/fz/w2.js - Endpoint de beacon C2:
ia-cdn[.]com/fz/c - Endpoint contaminado, já limpo:
api[.]sigmative[.]io/prod/store/api/biggopti/api-data-all-records - Endpoint contaminado, já limpo:
api[.]sigmative[.]io/prod/store/api/biggopti/api-data-records - Payload alternativo, já limpo:
api[.]sigmative[.]io/prod/store/api/biggopti/x.js
Ficheiros e opções da base de dados
- Webshell
emer-run.php, MD51024732009983dd5e54b4cf5593f04d4. - Backdoor MU
class-wp-token-validate.php, MD57719cd98a35ffad2771f26d1ceab7d27. - Módulo furtivo MU
class-wp-query-9d127ff3.php, ou nome semelhante no padrãoclass-wp-query-*.php, MD59aadc3e5c5242b273bd17c5bdc358845. - Módulo MU apresentado como verificação de saúde,
wp-cache-optimizer.php, MD5e450ae5bc4bfc0d960dded06a76bb8e9. - Opção
fz_emer_login_tokens, onde se guardam tokens de magic login. - Opção
fz_emer_done_v1, que assinala a conclusão do comprometimento. - Contas com endereços
@wordpress.orgou@developer.wordpress.org. - Nomes de utilizador que correspondam a
bd_mais seis caracteres alfanuméricos.
Cronologia do incidente
- 1 de março de 2026: o JavaScript da API Biggopti entra no Prime Slider 4.1.9, no SVN
r3471891. Odisplay_idfica sem escape no atributoide o endpoint usado éapi-data-records. - 10 de maio de 2026: o endpoint muda para
api-data-all-records. Adiciona-se um sanitizadorDOMParserao campo de conteúdo, mas o atributoidcontinua vulnerável. - 23 de junho de 2026: data
start_dateda campanha contaminada, num aviso “Summer Sale”; é a data mais antiga em que a XSS pode ter estado ativa. - 6 de agosto de 2026, 22:40 UTC: último
Last-Modifiedobservado emapi-data-recordscontaminado. - 7 de agosto de 2026, 09:11 UTC: último
Last-Modifiedobservado emapi-data-all-recordscontaminado. - 7 de agosto de 2026: o ataque é observado em ambiente real e os plugins são fechados no diretório do WordPress enquanto aguardam revisão.
- 7 de agosto de 2026, 16:56 UTC: são recolhidos artefactos da investigação.
- 8 de agosto de 2026: ambos os endpoints da API passam a devolver JSON limpo.
O que deves verificar e fazer agora
Desativa os plugins afetados e impede novos carregamentos do painel por utilizadores não estritamente necessários enquanto estiveres a analisar o ambiente. A limpeza está a exigir mais do que reinstalar plugins, porque a cadeia deixa alterações na base de dados, em contas de utilizadores e na diretoria de MU-plugins; verifica também os registos HTTP e DNS para ligações aos indicadores externos.
- Audita manualmente a lista de utilizadores, incluindo diretamente na base de dados, para encontrar administradores
bd_com seis caracteres, contas com os domínios indicados e contas inesperadas que a interface possa ocultar. - Inspeciona
wp-content/mu-plugins/, as diretorias de plugins e os ficheiros acessíveis por URL para os nomes, padrões e hashes indicados. Remove os artefactos indevidos apenas depois de preservar evidência e de garantir que tens uma cópia de segurança. - Consulta a tabela de opções para
fz_emer_login_tokensefz_emer_done_v1, bem como outros dados inesperados relacionados com o incidente. - Revoga sessões, nonces e palavras-passe potencialmente expostos; redefine as credenciais de todos os administradores e substitui as chaves e salts do WordPress para invalidar cookies autenticados.
- Roda uma análise de malware que cubra o sistema de ficheiros, a base de dados e os indicadores de rede. Uma verificação que compare apenas ficheiros dos plugins pode não encontrar esta infeção.
- Revê as credenciais e os controlos de acesso da infraestrutura associada aos plugins se gerires uma instalação BdThemes, porque o incidente indica comprometimento grave de credenciais de armazenamento cloud ou da infraestrutura interna.
Esta campanha está a demonstrar que um feed remoto aparentemente inofensivo pode tornar-se um vetor de execução remota quando o código de apresentação confia nos dados recebidos. Depois de eliminar os indicadores, mantém a monitorização de contas administrativas, pedidos a endpoints suspeitos e alterações em MU-plugins, pois é essa persistência que pode devolver o controlo do site ao atacante.
Cobertura de deteção
As assinaturas de malware e regras de WAF para este comprometimento foram disponibilizadas em 7 de agosto de 2026 aos utilizadores Wordfence Premium, Care e Response e a clientes pagos do Wordfence CLI. As edições gratuitas do Wordfence e Wordfence CLI recebem-nas após o atraso habitual de 30 dias.
Referências / Fontes
- PSA: Supply Chain Compromise in BdThemes Ecosystem via Poisoned API Response
- Biggopti Library (Various Versions) – Cross-Site Scripting via display_id from Sigmative API
- Wordfence PRISM Detected Backdoored WordPress Plugin Within Two Hours of It Being Introduced
- Security Incident: Tampered Script Served via OptinMonster and TrustPulse
Beatriz Tavares
Especialista em gestão de conteúdo e CMS headless. Strapi e Contentful são os meus favoritos. Acredito no poder do conteúdo estruturado.
Todos os posts