Redirecionamentos maliciosos no WordPress: como os remover
Redirecionamento malicioso no WordPress: reproduza-o com curl e ferramentas de programador, encontre-o em .htaccess, PHP, base de dados ou CDN e evite que volte.
Também em: English Deutsch Français Español Italiano Polski Türkçe
Um redirecionamento malicioso no WordPress é concebido para que o proprietário não o veja. O código verifica quem está a visitar o site e redireciona apenas alguns visitantes: utilizadores de telemóvel, pessoas que chegam através do Google ou das redes sociais e, muitas vezes, cada visitante apenas uma vez. Quase sempre ignora de propósito os utilizadores com sessão iniciada e os administradores.
Por isso, quando um cliente diz "o seu site enviou-me para uma página falsa de prémios" e o site parece normal no seu portátil, acredite no cliente. Os destinos típicos são páginas de burla, falsos sorteios, redes de publicidade agressivas ou descargas de malware. O Google pode sinalizar o site e os visitantes deixam de confiar nele. Os redirecionamentos são apenas um de vários sintomas; os restantes estão descritos em 12 sinais de que o seu site WordPress foi pirateado.
Porque é que o proprietário nunca vê o redirecionamento
As condições são simples e eficazes. O código lê o cabeçalho User-Agent para detetar telemóveis e o cabeçalho Referer para detetar tráfego vindo de motores de pesquisa. Verifica também a existência do cookie de início de sessão do WordPress. Depois do primeiro redirecionamento, define um cookie próprio ou regista o endereço IP, para que a mesma pessoa não seja redirecionada outra vez.
Esta combinação explica a maioria dos relatos de "não consigo reproduzir". Está com sessão iniciada, num computador de secretária, a escrever o endereço diretamente, e talvez já tenha sido redirecionado uma vez. Qualquer uma destas condições basta para desligar o redirecionamento.
Reproduzir o redirecionamento em segurança
Antes de vasculhar ficheiros, descubra que tipo de redirecionamento tem à frente. O tipo de resposta indica-lhe a camada onde deve procurar.
Comece no navegador. Abra uma janela privada e confirme que não tem sessão iniciada. Abra as ferramentas de programador (F12 no Chrome, no Edge e no Firefox) e ative a barra de dispositivos (Ctrl+Shift+M) para emular um telemóvel. No separador Network, marque Preserve log (no Firefox: Persist Logs no menu de definições de Network), para que os registos sobrevivam à mudança de página. Para obter um referenciador real do Google, pesquise o seu próprio domínio no Google e clique no resultado.
Agora observe a primeira entrada no separador Network:
- **Estado 301, 302, 307 ou 308 com um
Locationexterno**: o redirecionamento acontece no servidor. Isto inclui a CDN, as regras do servidor web, o PHP e o próprio WordPress. - Estado 200, seguido de um pedido a um domínio externo: a página carregou normalmente e depois JavaScript (ou uma etiqueta meta refresh) enviou o navegador para outro lado. Procure script injetado.
Confirme depois o resultado com o curl. O curl nunca executa JavaScript e não segue redirecionamentos, a menos que lho peça. O comando seguinte faz um pedido GET normal e mostra apenas os cabeçalhos da resposta; evite curl -I, porque algum código injetado ignora pedidos HEAD:
curl -s -o /dev/null -D - \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1" \
-e https://www.google.com/ \
https://example.com/
Uma linha Location: a apontar para um domínio desconhecido confirma um redirecionamento no servidor. Se a linha de estado mostrar 200, obtenha o corpo da página e procure nele código de redirecionamento e ofuscação:
curl -s -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X)" \
-e https://www.google.com/ https://example.com/ \
| grep -Eio 'window\.location|location\.href|location\.replace|http-equiv=.?refresh|atob\(|eval\(|fromCharCode|script[^>]+src="[^"]+"'
Repita o teste sem -A e -e e compare os resultados. Teste depois vários URL, como um artigo do blogue, uma página de produto e a página de contactos. Muitas injeções afetam apenas alguns modelos.
Um resultado limpo não prova que o site está limpo. Se o código redireciona cada IP apenas uma vez ou visa só determinados países, o seu teste pode não o apanhar. Repita o teste a partir de outra rede, por exemplo um telemóvel com dados móveis.
Redirecionamentos no servidor: .htaccess, configuração do servidor e PHP que corre primeiro
Se o curl mostrar um 3xx para um domínio externo, procure no servidor e no código que corre antes de o WordPress gerar qualquer página.
No Apache, verifique todos os ficheiros .htaccess, não apenas o da raiz do site. Procure condições de reescrita sobre o user agent ou o referenciador e a diretiva auto_prepend_file, que faz o PHP carregar um ficheiro do atacante antes de cada pedido:
grep -rn --include=.htaccess -E "HTTP_(USER_AGENT|REFERER)|auto_prepend_file" .
grep -rn --include=.user.ini --include=php.ini "auto_prepend_file" .
Existem linhas RewriteCond %{HTTP_USER_AGENT} legítimas, por exemplo em alguns plugins de cache. Uma regra que envia tráfego móvel ou do Google para um domínio que não reconhece não é legítima.
A seguir, liste os ficheiros PHP e de configuração alterados recentemente. Os atacantes conseguem repor as datas dos ficheiros, por isso trate esta lista como ponto de partida e não como prova. Execute o comando a partir da raiz do WordPress:
find . -type f \( -name "*.php" -o -name ".htaccess" -o -name ".user.ini" \) -mtime -14 -print
Examine com atenção tudo o que tenha sido acrescentado no início ou no fim do wp-config.php e todos os ficheiros em wp-content/mu-plugins. Os plugins de uso obrigatório (must-use) carregam automaticamente e não aparecem na lista normal de plugins. Verifique também o functions.php do tema ativo. Execute depois wp core verify-checksums para detetar ficheiros do núcleo modificados. Para saber como interpretar o resultado e reinstalar o núcleo em segurança, consulte o nosso guia sobre verificar as somas de controlo do WordPress.
No nginx, as regras ficam na configuração do servidor e não no .htaccess. Em alojamento gerido, pode não ter acesso a elas. Em ambos os casos, peça ao fornecedor de alojamento que verifique regras de redirecionamento e definições de prepend ao nível do servidor.
As opções siteurl e home
Existe uma variante diferente e mais grosseira, que altera as opções siteurl e home. O WordPress passa então a redirecionar todos os visitantes, incluindo você, para o domínio do atacante. Verifique os dois valores:
wp option get siteurl
wp option get home
Sem WP-CLI, abra o phpMyAdmin e consulte a tabela wp_options. O prefixo das suas tabelas pode ser diferente de wp_; confirme $table_prefix no wp-config.php. Para corrigir os valores:
wp option update siteurl 'https://example.com'
wp option update home 'https://example.com'
Execute também grep -n "WP_HOME\|WP_SITEURL" wp-config.php. Se estas constantes estiverem definidas, sobrepõem-se aos valores da base de dados. Um atacante pode tê-las lá colocado, e a correção na base de dados parecerá não ter qualquer efeito.
Redirecionamentos JavaScript em artigos, widgets, ficheiros do tema e scripts do cabeçalho
Uma resposta 200 seguida de um salto para outro domínio significa que há um script a correr na página. Pode vir de vários sítios:
- Conteúdo dos artigos: etiquetas script injetadas em
post_content, muitas vezes em dezenas de artigos ao mesmo tempo. - Opções: linhas de widgets (
widget_*), opções do tema e definições de construtores de páginas emwp_options. - Definições de "Inserir cabeçalhos e rodapés": plugins de fragmentos de código e construtores de páginas guardam aí scripts para todo o site. Um atacante com credenciais de administrador só precisa de colar uma linha.
- Ficheiros do tema e dos plugins:
header.php,footer.phpe ficheiros JavaScript colocados em fila.
Uma pesquisa rápida na base de dados (ajuste wp_posts se o prefixo das suas tabelas for diferente):
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%script%src=%';"
wp db search 'fromCharCode' --all-tables
wp option list --search='widget_*' --fields=option_name
Conte com ofuscação. O código injetado raramente contém o URL de destino em texto simples. Procure atob(, longas cadeias base64, String.fromCharCode e origens de scripts que imitam domínios conhecidos de CDN ou de análise com uma grafia ligeiramente diferente. A técnica de pesquisa na base de dados e a limpeza estão explicadas com mais detalhe em spam SEO no WordPress.
Cópias em cache: plugins de cache, cache do servidor e CDN
Pode limpar totalmente a origem e os visitantes continuarem a ser redirecionados, porque a página infetada ainda está guardada algures. Há cópias que sobrevivem nos ficheiros da cache de páginas (wp-content/cache), numa cache de objetos como Redis ou Memcached, na cache do servidor do seu alojamento e nos servidores de borda da CDN.
Limpe pela ordem do pedido, da origem para fora:
- Termine a limpeza de ficheiros e da base de dados na origem.
- Limpe a cache de páginas do plugin de cache.
- Esvazie a cache de objetos com
wp cache flush. - Limpe a cache do servidor do alojamento no painel de alojamento.
- Limpe tudo na CDN.
- Volte a testar com os comandos curl acima, com e sem o user agent móvel e o referenciador do Google.
Considere também o caso inverso: alguém definiu o redirecionamento na CDN ou no DNS. Quem tiver acesso à sua conta da CDN pode criar uma regra de redirecionamento sem tocar no WordPress. Verifique as regras de redirecionamento e de página no painel da CDN e os seus registos DNS. Reveja quem tem acesso a essas contas e retire o acesso a quem já não precisa dele.
Encontre o ponto de entrada, ou o redirecionamento volta
O redirecionamento é a carga maliciosa, não a brecha. Se apagar apenas a carga, ela costuma regressar em poucos dias, porque a porta de entrada continua aberta. Os pontos de entrada mais comuns são plugins vulneráveis ou piratas (nulled), credenciais de administrador ou de alojamento roubadas, web shells em wp-content/uploads e backdoors esquecidas que reinjetam o código através de uma tarefa cron ou de uma opção da base de dados.
Uma primeira verificação rápida:
- Administradores desconhecidos:
wp user list --role=administrator - Palavras-passe de aplicação que não criou (Utilizadores > Perfil)
- Eventos agendados desconhecidos:
wp cron event list - Ficheiros PHP na pasta uploads:
find wp-content/uploads -name "*.php" - Plugins e temas desatualizados ou piratas (nulled)
Depois de fechar a brecha, altere as palavras-passe de administrador, do alojamento, da base de dados, do SFTP e da CDN. Em seguida, renove as salts com wp config shuffle-salts. Isto termina a sessão de todos os utilizadores. Siga o plano completo de remoção de malware no WordPress para a preservação de provas e a decisão entre limpar e restaurar.
O atacante pode também ter conseguido ler dados de clientes, registos de formulários de contacto ou encomendas. Nesse caso, avalie o incidente como uma possível violação de dados pessoais. Veja a notificação de violações de dados pessoais em 72 horas ao abrigo do RGPD.
FAQ
Porque é que só os utilizadores de telemóvel são redirecionados?
Quem visita no telemóvel tem menos probabilidade de reparar num endereço estranho e mais probabilidade de tocar em páginas de burla. Além disso, os proprietários costumam verificar o site num computador de secretária e com sessão iniciada. A condição "apenas telemóvel" existe para esconder o redirecionamento de si.
O Google mostra "Este site pode ter sido pirateado." E agora?
Primeiro, limpe o site, feche o ponto de entrada e limpe todas as caches. Depois, peça uma revisão no Google Search Console. O processo está descrito em spam SEO no WordPress. Se pedir a revisão antes de o redirecionamento ter realmente desaparecido, o pedido tende a ser recusado.
Um plugin de segurança pode remover o redirecionamento por mim?
Os analisadores ajudam a encontrá-lo, mas não substituem a limpeza manual nem a procura do ponto de entrada. O plugin de auditoria do secaudit.eu verifica a integridade dos ficheiros face a uma linha de base e assinala indicadores de comprometimento, como administradores ocultos, eventos cron suspeitos e spam na base de dados. Analisa também spam SEO oculto. Deteta e comunica. Remover o código e fechar a brecha cabe a si ou a um profissional que contrate.
Verifique o seu site
O Security Audit & Compliance é o plugin WordPress da secaudit.eu: procura malware, spam oculto, ficheiros do núcleo alterados e código vulnerável, e associa as conclusões ao art. 32.º do RGPD, ao art. 21.º da NIS2 e ao OWASP Top 10.
Ver o que o plugin verifica