Versão alargada e atualizada deste tema: Limpar um WordPress pirateado: remoção de malware, cópias de segurança e proteção.
“O site a seguir contém programas prejudiciais.”
Esta frase, exibida num ecrã vermelho vivo (Google Safe Browsing) ou num e-mail do seu fornecedor de alojamento, é o pesadelo de qualquer proprietário de site. Uma infeção no WordPress não é apenas uma questão de reputação. Arrisca o roubo de dados de clientes, a perda de posições no Google (o chamado “Japanese Keyword Hack” ou redirecionamentos para sites de jogos de azar) e potencialmente o bloqueio da sua conta de alojamento.
Grande parte dos ataques ao WordPress é automatizada: o próprio guia de hardening do WordPress nota que muitos ataques são executados de forma autónoma por bots. Os bots não o atacam pessoalmente, eles varrem a web à procura de plugins desatualizados, senhas fracas ou vulnerabilidades em temas.
Neste artigo, vou mostrar-lhe um processo técnico e profissional para limpar um site WordPress hackeado. Esqueça os “plugins de remoção de malware” que muitas vezes apenas mascaram o problema. Vou mostrar como fazê-lo manualmente, eficazmente e ao nível do servidor usando SSH e WP-CLI.
Se o primeiro sinal foram páginas japonesas no Google e não algo visível no site, está provavelmente perante a variante camuflada, que exige um primeiro passo diferente: veja o hack japonês de palavras-chave antes de apagar seja o que for.
Sinais de que o WordPress foi hackeado e o que registar primeiro
“Hackeado” é um termo vago. A página FAQ My site was hacked da documentação oficial do WordPress chama aos sintomas concretos indicadores de compromisso (IoC) e enumera os mais claros:
- o site aparece em listas negras do Google, do Bing ou de outros motores;
- o alojamento desativou o site;
- o site foi sinalizado por distribuir malware;
- os visitantes queixam-se de que o antivírus do computador bloqueia o site;
- alguém o contactou porque o seu site está a ser usado para atacar outros sites;
- há ações que ninguém autorizou, por exemplo novos utilizadores;
- a alteração é visível quando abre o site no navegador.
A 20 de outubro de 2026, a Google anunciou que o Chrome divide em dois níveis os avisos do Safe Browsing sobre sites, para quem tem a proteção melhorada ativa: sites suspeitos (veredicto com menor confiança, possível risco para o utilizador) e sites perigosos (veredicto com elevada confiança, risco elevado para o utilizador) (Google, 20 de outubro de 2026). Os sites perigosos continuam a receber o aviso vermelho de ecrã inteiro. O aviso de site suspeito tem formato, ícone, cor e texto diferentes, e a Google mostra-o quando uma página apresenta padrões enganosos habitualmente associados a sites maliciosos conhecidos.
O primeiro passo prático, segundo a mesma página, é documentar. Antes de apagar qualquer coisa, anote o que vê, a hora em que reparou no problema (com o fuso horário) e o que mudou recentemente: um plugin novo, uma alteração ao tema, um widget editado. Junte os dados do ambiente de alojamento (versão de PHP, tipo de servidor, quem tem acesso). Esta nota é a base de um relatório de incidente e poupa tempo, quer faça a limpeza sozinho quer a entregue a outra pessoa.
Dois passos que costumam ser esquecidos vêm da mesma fonte. Primeiro, analise o seu próprio computador com um antivírus: um trojan local que capture as credenciais de FTP ou do /wp-admin torna inútil qualquer limpeza no servidor. Segundo, fale com o alojamento. Em alojamento partilhado a infeção pode ter atingido mais do que o seu site, e um site usado para enviar spam pode pôr o IP do servidor em listas negras de e-mail, o que afeta também o correio que sai desse servidor.
Passo 0: backup do WordPress infetado antes da limpeza
Antes de tocar em qualquer coisa, faça backup do seu estado atual. Porquê? Porque durante a limpeza pode apagar acidentalmente um ficheiro crítico (por exemplo, um functions.php modificado que continha funcionalidades importantes, não apenas o vírus). A documentação do WordPress recomenda esta cópia mesmo que o site esteja infetado: se a limpeza correr mal, tem pelo menos a versão anterior para consultar.
Se tiver acesso SSH:
## Arquivar todos os ficheiros
tar -czf backup-infected-files_$(date +%F).tar.gz .
## Exportar base de dados
wp db export backup-infected-db_$(date +%F).sql --allow-rootPasso 1: detetar malware no WordPress com grep
Antes de começar a cortar, precisa de saber contra o que está a lutar. Malware no WordPress esconde-se frequentemente como código ofuscado usando funções como eval, base64_decode, ou gzinflate. O relatório de problemas de segurança da Google mostra um exemplo típico, eval(base64_decode("...")), e sugere procurar os termos eval, base64_decode e unescape.
Aqui está uma lista de comandos grep úteis para verificar ficheiros à procura de strings suspeitas. Execute-os na diretoria raiz do seu site.
Código malicioso mais comum em ficheiros WordPress
Procura da função
eval(muito raramente usada legitimamente em código moderno):grep -rl --include=*.php 'eval(' .Procura de iframes ocultos e scripts injetados em ficheiros PHP:
grep -rl --include=*.php '<script' . grep -rl --include=*.php '<iframe' .Procura de strings codificadas e descompressão (Base64, Rot13, gzinflate):
grep -rl --include=*.php 'base64_decode' . grep -rl --include=*.php 'str_rot13' . grep -rl --include=*.php 'gzinflate' .Procura de
unescapeem JavaScript:grep -rl --include=*.js 'unescape(' .
Não use a opção -w com estes padrões. Com -w, o grep exige que a correspondência termine num carácter que não seja letra ou dígito, por isso eval( não encontra a forma mais comum, eval(base64_decode(.
Como distinguir malware de falsos positivos
Nem todos os resultados são vírus.
- Plugins como Elementor ou Visual Composer podem ter
base64_decodeno seu código. - Preste atenção a ficheiros em locais estranhos, por exemplo,
wp-content/uploads/2024/03/avatar.php. A pastauploadsnão deve conter ficheiros PHP.
Para encontrar todos os ficheiros PHP na pasta uploads:
find ./wp-content/uploads -name "*.php"Se encontrar algo aqui, trate-o como suspeito até prova em contrário. Só um plugin muito específico guarda PHP nessa pasta, e isso deve estar documentado pelo autor do plugin.
Como ver o site WordPress hackeado como o Google o vê
Muitos ataques mostram o spam apenas ao Googlebot ou a quem chega a partir da pesquisa (cloaking). O dono abre o site diretamente e vê tudo normal. O relatório de problemas de segurança da Google desaconselha abrir páginas infetadas no navegador, porque o malware pode explorar vulnerabilidades do próprio navegador, e propõe duas alternativas.
A primeira é a ferramenta de inspeção de URL na Search Console, que mostra a página tal como o Google a recebe. A segunda é o curl (ou wget) com um referer e um user-agent definidos, para imitar um visitante que vem do Google:
curl -sv --referer "https://www.google.com/" \
--user-agent "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://o-seu-dominio.pt/ -o pagina.html
grep -iE 'eval|base64_decode|unescape|<iframe' pagina.htmlRepita o pedido sem referer e compare as respostas. Um 301 ou 302 que aparece só com o referer do Google aponta para regras no .htaccess ou no código PHP. A Google lista três formas de redirecionamento usadas por atacantes: regras no ficheiro de configuração do servidor (.htaccess, httpd.conf), redirecionamentos em JavaScript condicionados ao document.referrer e scripts carregados de outro domínio.
Passo 2: reinstalar o core do WordPress com WP-CLI
Remover manualmente um vírus dos ficheiros do core do WordPress (wp-admin, wp-includes) é um trabalho de Sísifo. O método mais rápido e fiável é substituir todos os ficheiros do sistema por originais limpos.
Este é um processo seguro se não tiver modificado manualmente os ficheiros do core (o que não deve fazer de qualquer forma).
A documentação do WordPress pede que reinstale a mesma versão que o site está a usar: uma versão mais antiga ou mais recente pode deitar o site abaixo. Sem --version, o wp core download descarrega a versão mais recente, por isso indique a versão atual:
## Descarregar a mesma versão do WordPress (substituindo ficheiros)
wp core download --version=$(wp core version --allow-root) --force --skip-content --allow-rootA flag --skip-content é crítica, garante que o WP-CLI não sobrescreve a sua pasta wp-content, onde residem as suas imagens, temas e plugins.
Há um limite que convém conhecer. Segundo a mesma FAQ, os instaladores normalmente só sobrescrevem ficheiros existentes, e os ataques costumam adicionar ficheiros novos. Um ficheiro extra em wp-includes sobrevive ao --force. A verificação de checksums, descrita a seguir, mostra-o.
Se não tiver WP-CLI:
- Descarregue o pacote WordPress da mesma versão em wordpress.org.
- Descompacte-o localmente.
- Apague a pasta
wp-contente o ficheirowp-config-sample.phpdo pacote. - No servidor, apague as pastas
wp-adminewp-includese carregue as do pacote via SFTP, depois sobrescreva os ficheiros da raiz.
A FAQ do WordPress desaconselha o botão de reinstalação no painel nesta situação, pela mesma razão: só sobrescreve.
Verificar o core e os plugins com wp core verify-checksums
O WP-CLI compara os ficheiros instalados com as somas MD5 publicadas pelo WordPress.org. O comando wp core verify-checksums corre no hook before_wp_load, ou seja, não carrega o WordPress, o que importa quando o próprio WordPress pode estar comprometido.
wp core verify-checksums --allow-rootNum core limpo o resultado é:
Success: WordPress installation verifies against checksums.Num core alterado aparecem avisos por ficheiro e um erro final:
Warning: File doesn't verify against checksum: wp-includes/version.php
Warning: File should not exist: wp-includes/ficheiro-extra.php
Error: WordPress installation doesn't verify against checksums.O aviso “File should not exist” é o que interessa depois de um ataque. O código do comando mostra que, por omissão, verifica ficheiros extra em wp-admin, wp-includes e os ficheiros wp-*.php da raiz (exceto wp-config.php). Com --include-root (desde a versão 2.8.0) verifica toda a raiz, exceto .htaccess, .maintenance, wp-config.php e wp-content. Se o site usa uma tradução, junte --locale=pt_PT, ou o comando assinala ficheiros traduzidos como alterados. O nome ficheiro-extra.php no exemplo é só um marcador: num ataque real o ficheiro tem um nome que parece legítimo.
Para plugins existe o equivalente wp plugin verify-checksums:
wp plugin verify-checksums --all --allow-rootO comando compara cada plugin com as somas do WordPress.org e assinala ficheiros adicionados (“File was added”) e alterados (“Checksum does not match”). Para plugins que não estão no diretório do WordPress.org, como a maioria dos plugins pagos, não há somas para comparar: o WP-CLI mostra um aviso e salta o plugin. Esses têm de ser substituídos por um pacote limpo do fornecedor.
Passo 3: limpar plugins, temas e uploads infetados
É aqui que normalmente reside o problema.
Plugins e temas
Se possível, apague e reinstale todos os plugins gratuitos. Os vírus anexam-se frequentemente a cada ficheiro .js ou .php no servidor.
## Reinstalar plugin do repositório (ex. contact-form-7)
wp plugin install contact-form-7 --force --allow-rootPara plugins pagos, deve descarregar pacotes limpos do fornecedor e substituir ficheiros via SFTP.
Verifique o seu tema. Se usa um tema filho (child theme), reveja manualmente o functions.php e header.php. Estes são locais favoritos para código malicioso. A FAQ do WordPress acrescenta index.php e footer.php à lista de ficheiros a vigiar, porque uma alteração neles afeta todos os pedidos de página.
Pasta uploads
Como mencionado anteriormente, a pasta de média (wp-content/uploads) deve conter apenas imagens, PDFs e documentos. Limpeza radical (apaga todos os scripts PHP de uploads):
find ./wp-content/uploads -name "*.php" -deleteAviso: Verifique a lista antecipadamente (sem -delete) para garantir que não está a apagar algo legítimo.
Passo 4: remover spam e falsos administradores da base de dados
As infeções muitas vezes não terminam nos ficheiros. Os vírus injetam links de spam no conteúdo dos posts ou criam falsos administradores.
Faça login na base de dados (phpMyAdmin ou wp db cli) e verifique:
Falsos administradores:
SELECT * FROM wp_users;Procure utilizadores que não reconhece, muitas vezes com domínios
.ru,.cnou strings aleatórias. Apague-os imediatamente.Spam no conteúdo: Vírus do tipo “Japanese Keyword Hack” injetam milhares de páginas com caracteres chineses/japoneses a publicitar falsificações. Verifique a tabela
wp_posts:SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%'; SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%eval(%';
Se o site tiver de repente milhares de páginas novas no índice do Google, precisa de limpar estas entradas da base de dados e, em seguida, enviar um sitemap para a Google Search Console para acelerar a remoção do lixo do índice.
Listar administradores do WordPress com wp user list
A consulta SELECT * FROM wp_users mostra todos os utilizadores, mas não o papel de cada um, que fica guardado na wp_usermeta. O comando wp user list junta as duas tabelas e filtra por papel:
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-rootCompare a lista com as pessoas que de facto têm acesso. A coluna user_registered ajuda a ligar uma conta desconhecida à data do incidente que registou no início. Numa instalação multisite, --network lista os utilizadores de toda a rede (sem papéis, porque o mesmo utilizador pode ter papéis diferentes em cada site), por isso verifique também os super administradores:
wp super-admin list --allow-rootSe o atacante tomou a sua conta de administrador e não consegue entrar, a FAQ do WordPress descreve a saída: entre na base de dados pelo phpMyAdmin ou Adminer, altere o e-mail da sua conta na tabela wp_users para um endereço que controla e use a ligação de recuperação de palavra-passe no ecrã de login.
Passo 5: verificar wp-config.php e .htaccess infetados
O malware modifica frequentemente estes dois ficheiros-chave.
wp-config.php: Abra-o e verifique se há linhas estranhas. Muitas vezes são adicionadas referências a ficheiros temporários:
include '\tmp\sess_dsf43...'; // SUSPEITO!Compare o seu ficheiro com o
wp-config-sample.php. Deve conter apenas credenciais da base de dados e definições de constantes..htaccess: Os vírus adicionam frequentemente regras aqui que redirecionam o tráfego dos motores de busca (por exemplo, se o User-Agent for Googlebot) para sites com malware, enquanto o utilizador, ao visitar diretamente, vê o site normal. Se não tiver a certeza, gere o ficheiro .htaccess padrão do WordPress:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
A FAQ do WordPress lembra que o .htaccess não vive só na raiz: pode estar embutido noutras diretorias da mesma instalação. Procure-os todos:
find . -name ".htaccess"Passo 6: proteger o WordPress depois de remover malware
Limpou o site? Ótimo. Agora tranque as portas para que o ladrão não volte.
Mudar palavras-passe:
- Para todas as contas de administrador.
- Para a base de dados.
- Para FTP/SFTP e para o painel do alojamento.
A FAQ do WordPress insiste num pormenor: se mudou as palavras-passe quando descobriu o ataque, mude-as outra vez depois de confirmar que o site está limpo. Se mudar o utilizador ou a palavra-passe da base de dados, atualize o
wp-config.phpcom os novos valores.Mudar chaves de sal (salt keys): Isto força o logout de todos os utilizadores. Edite o
wp-config.phpe substitua a secção de chaves por novas geradas aqui: https://api.wordpress.org/secret-key/1.1/salt/ Ou use WP-CLI:wp config shuffle-saltsDesativar edição de ficheiros no painel: Adicione ao
wp-config.php:define( 'DISALLOW_FILE_EDIT', true );Isto impede que um hacker que obtenha uma senha de administrador possa editar ficheiros de temas/plugins diretamente do painel. O guia de hardening explica que a constante equivale a retirar as capacidades
edit_themes,edit_pluginseedit_filesa todos os utilizadores, e que o editor do painel é muitas vezes a primeira ferramenta que um atacante usa depois de entrar.Desativar XML-RPC: Se não usa a app móvel do WordPress ou o Jetpack, o XML-RPC é apenas um buraco de segurança (usado para ataques DDoS e Brute Force). Adicione ao
.htaccess:<Files xmlrpc.php> order deny,allow deny from all </Files>Esta é a sintaxe do Apache 2.2. No Apache 2.4 sem o módulo
mod_access_compat, useRequire all denieddentro do bloco<Files>.
Permissões de ficheiros e utilizador da base de dados depois da limpeza
O guia de hardening dá valores concretos. Diretorias com 755, ficheiros com 644, todos graváveis apenas pela conta do utilizador dono do site:
find /caminho/para/wordpress/ -type d -exec chmod 755 {} \;
find /caminho/para/wordpress/ -type f -exec chmod 644 {} \;O wp-config.php deve ser legível apenas por si e pelo servidor web, o que normalmente significa 400 ou 440.
O mesmo guia lembra que, para o funcionamento normal, o utilizador MySQL só precisa de SELECT, INSERT, UPDATE e DELETE. Mas avisa no mesmo parágrafo que retirar ALTER e afins não é recomendado sem um plano de backups testado, porque algumas atualizações alteram o esquema da base de dados. Depois de um ataque, o passo mais útil é outro: se tem vários sites no mesmo servidor, cada um deve ter a sua própria base de dados e o seu próprio utilizador, para que um site comprometido não dê acesso aos restantes.
Por fim, os logs. O guia de hardening descreve-os como a fonte principal para perceber por onde o atacante entrou: os registos de acesso do servidor mostram IP, hora e pedidos, incluindo tentativas de força bruta e de inclusão de ficheiros. A FAQ chama a esta fase análise forense, e o objetivo é fechar o vetor de ataque e não só apagar os sintomas. O guia também recomenda guardar cópias periódicas do site completo num local de confiança, porque um ataque detetado dias depois só se compara com uma cópia anterior a ele.
Como confirmar que o WordPress já não está infetado
Uma limpeza só termina quando o site passa nas mesmas verificações que revelaram o problema. Nos dias seguintes, repita os comandos grep do Passo 1, o find ./wp-content/uploads -name "*.php" e o wp core verify-checksums. Uma lista vazia em uploads é o resultado esperado. Um ficheiro PHP novo nessa pasta significa que a porta de entrada continua aberta.
Volte também à base de dados. Corra de novo wp user list --role=administrator para confirmar que não reapareceu nenhum administrador desconhecido, e repita as consultas à wp_posts à procura de <script e eval(. Compare o wp-config.php e o .htaccess com as versões limpas, porque são os dois ficheiros que o malware modifica com mais frequência.
Se a infeção foi do tipo Japanese Keyword Hack, acompanhe o índice na Google Search Console depois de enviar o sitemap e confirme que as páginas de spam estão a desaparecer.
Se alguma verificação falhar, não se limite a repetir a limpeza. Procure primeiro o plugin desatualizado, o tema nulled ou a palavra-passe fraca que deixou o atacante entrar, e só depois limpe outra vez.
Relatório de problemas de segurança e pedido de revisão na Search Console
Se o Google marcou o site, o aviso só sai depois de uma revisão. O relatório de problemas de segurança da Search Console é, segundo a própria Google, a fonte de verdade: o Safe Browsing mostra avisos conforme o contexto de navegação, por isso pode não conseguir reproduzir o aviso no seu navegador. O relatório agrupa os problemas em três categorias: conteúdo hackeado, malware e software indesejado, e engenharia social.
Cada problema traz exemplos de URLs afetados. A Google avisa que é apenas uma amostra e que um problema sem exemplos não significa que nenhuma página está afetada. Corrija o problema em todo o site: corrigir só algumas páginas não dá um regresso parcial aos resultados de pesquisa. Se o relatório lista vários problemas, corrija todos.
Quando estiverem todos resolvidos, use a opção Request Review (pedir revisão) no relatório. Segundo a Google, um bom pedido faz três coisas: explica o problema exato, descreve os passos que tomou para o corrigir e documenta o resultado. Aqui a nota de incidente do início do artigo e a saída dos comandos de verificação servem de prova.
A revisão demora de alguns dias a algumas semanas e a Google informa por e-mail quando recebe o pedido e quando o conclui. Não reenvie o pedido antes de ter uma decisão. Um pedido feito antes de o problema estar resolvido pode atrasar o seguinte e até levar a que o site seja marcado como reincidente.
Se comprou recentemente um site que já trazia estes problemas, a Google pede que o diga no pedido de revisão, depois de corrigir tudo o que o relatório lista.
Resumo
Lutar contra malware é uma corrida armamentista. A melhor proteção, no entanto, não é um “plugin de segurança mágico”, mas sim higiene digital:
- Atualizações imediatas do WordPress e plugins.
- Não instalar plugins e temas “nulled” (pirateados), uma fonte frequente de infeções.
- Ter um backup externo (por exemplo, na nuvem).
Se sente que o aspeto técnico o sobrecarrega, é melhor contratar profissionais. Uma limpeza mal executada pode deixar uma porta dos fundos (backdoor) aberta, através da qual o hacker voltará em poucos dias, e perderá mais dinheiro e confiança aos olhos do Google.







