Como remover malware e backdoors do WordPress (guia técnico)

Guia técnico para remover malware e backdoors do WordPress: backup, reinstalação do core e plugins, caça a eval/base64, uploads, mu-plugins e banco de dados.

Para remover malware do WordPress de forma que ele não volte, a regra é: não tente "consertar" os arquivos infectados um a um. Faça backup, reinstale o núcleo, os plugins e os temas a partir de fontes oficiais, cace os backdoors que sobram (em uploads, mu-plugins, .htaccess, wp-config.php e no banco de dados), troque todas as senhas e salts e corrija a falha que deixou o invasor entrar. Este guia mostra cada etapa com os comandos.

Ele assume que você tem acesso SSH e WP-CLI. Dá para fazer quase tudo pelo gerenciador de arquivos e pelo phpMyAdmin da hospedagem, só é mais trabalhoso. Se você ainda está nas primeiras horas da invasão, leia antes o que fazer quando o site WordPress é invadido.

Etapa 0: backup completo, antes de qualquer coisa

Atenção: não pule esta etapa. Um comando errado durante a limpeza pode apagar conteúdo, e o backup do site infectado também guarda as evidências de como o invasor entrou.

cd /caminho/do/site
wp db export ~/backup-infectado-$(date +%F).sql
tar -czf ~/arquivos-infectados-$(date +%F).tar.gz .

Dica: os comandos do WP-CLI carregam o WordPress, inclusive plugins e tema infectados. Durante a limpeza, prefira acrescentar --skip-plugins --skip-themes aos comandos (como wp --skip-plugins --skip-themes user list). Os comandos verify-checksums e core download já evitam carregar o site.

Baixe os dois arquivos para fora do servidor e identifique-os como infectados. Anote também a versão do WordPress e a lista de plugins e temas com versões:

wp core version
wp plugin list --fields=name,status,version
wp theme list --fields=name,status,version

Etapa 1: isolar

Se o site redireciona visitantes ou distribui malware, tire-o do ar (modo de manutenção da hospedagem ou senha HTTP) enquanto trabalha. Troque logo a senha da hospedagem, do SSH/FTP e do banco, de um computador confiável.

Se a mesma conta de hospedagem tem vários sites, considere todos comprometidos. Um site esquecido numa subpasta é uma fonte clássica de reinfecção, porque em muitas hospedagens compartilhadas todos rodam com o mesmo usuário do sistema e enxergam os arquivos uns dos outros.

Etapa 2: verificar o que foi alterado

Antes de reinstalar, colete pistas. Elas ajudam a descobrir a porta de entrada.

# Arquivos do núcleo e de plugins diferentes do original
wp core verify-checksums
wp plugin verify-checksums --all

# PHP modificados nos últimos 30 dias (ajuste o período)
find . -type f -name "*.php" -mtime -30 -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort

# PHP dentro de uploads (normalmente não deveria existir nenhum)
find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.php*" \)

No macOS ou em servidores sem find do GNU, troque o -printf por -ls.

Cruze as datas com os logs de acesso da hospedagem: requisições POST para arquivos estranhos ou para um plugin específico perto da data do primeiro arquivo malicioso costumam revelar como o invasor entrou.

Etapa 3: reinstalar o núcleo do WordPress

Reinstalar o núcleo substitui wp-admin, wp-includes e os arquivos da raiz por cópias oficiais, sem mexer em wp-content nem no wp-config.php:

wp core download --version=$(wp core version) --skip-content --force
wp core verify-checksums

O verify-checksums pode apontar arquivos que não deveriam existir dentro de wp-admin e wp-includes. Revise e apague esses extras, eles não fazem parte do WordPress. Na raiz, olhe com atenção tudo que não for um arquivo padrão do WordPress (index.php, wp-*.php, xmlrpc.php, wp-config.php, .htaccess).

Sem SSH: baixe o mesmo número de versão em wordpress.org, apague wp-admin e wp-includes do servidor e envie as pastas novas, mais os arquivos da raiz (exceto wp-config.php).

Etapa 4: reinstalar plugins e temas de fontes oficiais

Para plugins do repositório oficial, reinstale por cima com a mesma versão (ou já atualize):

wp plugin install nome-do-plugin --force
# ou, para reinstalar todos os do repositório na versão atual:
wp plugin list --field=name | xargs -n1 wp plugin install --force

Plugins e temas pagos você baixa de novo da conta oficial do fornecedor, apaga a pasta antiga e envia a nova. Apague de vez tudo que está desativado e não é usado.

E aqui está a regra mais importante: plugin ou tema pirata ("nulled") sai do servidor. Cópias baixadas de sites de "plugins premium grátis" são uma porta de entrada muito comum, e muitas vêm com backdoor de fábrica. Não adianta limpar o site e reinstalar o mesmo arquivo.

Tema com personalizações feitas direto nos arquivos (sem tema filho) exige revisão manual, arquivo por arquivo, comparando com a versão original.

Etapa 5: caçar backdoors que sobraram

Backdoor é o código que deixa o invasor voltar mesmo depois que você troca as senhas. Os lugares mais comuns:

Padrões de código ofuscado

grep -rnE --include="*.php" \
  "eval\(|base64_decode\(|gzinflate\(|gzuncompress\(|str_rot13\(|assert\(|create_function\(|preg_replace\(.*/e" \
  wp-content | less

Plugins legítimos também usam base64_decode, então isso gera falsos positivos. O que denuncia malware é a combinação: eval(base64_decode(...)), eval(gzinflate(...)), strings enormes sem sentido numa linha só, variáveis com nomes aleatórios, código PHP colado no começo de um arquivo legítimo antes do <?php original.

Procure também por funções de execução e por código que lê dados da requisição e executa:

grep -rnE --include="*.php" "(system|shell_exec|passthru|exec|popen)\s*\(\s*\\\$_(GET|POST|REQUEST|COOKIE)" .

Lugares para olhar com atenção

Local O que procurar
wp-content/uploads/ Qualquer .php, .phtml ou arquivo com extensão dupla. Apague.
wp-content/mu-plugins/ Plugins "obrigatórios" carregam sempre e não aparecem na lista comum. Tudo que você não instalou é suspeito.
Drop-ins em wp-content/ db.php, object-cache.php, advanced-cache.php. Podem ser legítimos (cache), confira de onde vieram.
wp-config.php include/require de arquivos estranhos, código antes de <?php, código depois de require_once ABSPATH . 'wp-settings.php';.
.htaccess (todos) Redirecionamentos condicionais por HTTP_REFERER ou HTTP_USER_AGENT, RewriteRule para domínios externos, auto_prepend_file.
.user.ini / php.ini auto_prepend_file apontando para um arquivo malicioso.
functions.php do tema Código colado no início ou no fim, criação de usuários, chamadas remotas.
Tarefas agendadas wp cron event list e o crontab do servidor (crontab -l).

Para listar todos os .htaccess, que muitas vezes existem em várias pastas:

find . -name ".htaccess" -o -name ".user.ini" -o -name "php.ini"

O .htaccess padrão do WordPress em instalação simples tem só o bloco entre # BEGIN WordPress e # END WordPress. Regras extras de cache ou segurança podem ser legítimas, mas você precisa saber explicar cada uma.

Etapa 6: limpar o banco de dados

Muito malware vive no banco: scripts injetados em posts, em opções do tema ou em widgets. Procure por <script, eval( e domínios estranhos:

wp db search "<script" --all-tables
wp db search "eval(" --all-tables

Ou em SQL (troque wp_ pelo seu prefixo):

SELECT ID, post_title, post_type FROM wp_posts
WHERE post_content LIKE '%<script%' OR post_content LIKE '%<iframe%';

SELECT option_name FROM wp_options
WHERE option_value LIKE '%<script%' OR option_value LIKE '%eval(%'
   OR option_value LIKE '%base64_decode%';

Scripts legítimos (Google Analytics, pixel, chat) também vão aparecer. Remova o que você não reconhece e confira se o endereço do site em siteurl e home está correto.

Revise os usuários e apague administradores que você não criou:

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
wp user delete ID_DO_INVASOR --reassign=ID_DE_UM_ADMIN_SEU

Se a loja ou área de membros tem muitos usuários, procure também contas recentes com papéis elevados (editor, gerente da loja).

Etapa 7: trocar senhas e salts

Agora, com o código limpo:

wp config shuffle-salts
wp user session destroy --all-users

Depois troque as senhas de todos os administradores (e peça para os demais usuários trocarem), a senha do banco (atualizando DB_PASSWORD no wp-config.php), as chaves de API guardadas no site (gateway de pagamento, SMTP, serviços de e-mail) e as senhas da hospedagem e do e-mail, se ainda não fez.

Etapa 8: corrigir a porta de entrada e endurecer

Se você não descobriu como o invasor entrou, o mais provável é: plugin ou tema desatualizado com falha conhecida, plugin pirata, senha fraca ou reutilizada, ou outro site na mesma conta. Atualize tudo, remova o que não usa e aplique o básico do checklist de segurança para WordPress, como DISALLOW_FILE_EDIT, 2FA e permissões corretas (pastas 755, arquivos 644, como recomenda a documentação de hardening do WordPress.org).

Etapa 9: verificar e monitorar

  • rode de novo wp core verify-checksums e wp plugin verify-checksums --all;
  • teste o site no celular, vindo do Google, em aba anônima;
  • verifique a busca site:seudominio.com.br e a Inspeção de URL no Search Console;
  • se havia aviso do Google, só agora peça revisão: veja como remover o aviso de site perigoso do Google;
  • repita o find de arquivos modificados nos dias seguintes. Arquivo novo aparecendo sozinho significa que algo ficou para trás.

Checklist rápido da limpeza

  • Backup completo do site infectado, fora do servidor
  • Site isolado e senhas da hospedagem/SSH/banco trocadas
  • Checksums verificados e arquivos alterados anotados
  • Núcleo reinstalado da fonte oficial
  • Plugins e temas reinstalados de fontes oficiais; piratas e não usados removidos
  • uploads, mu-plugins, drop-ins, .htaccess, wp-config.php e cron revisados
  • Banco de dados varrido; admins desconhecidos removidos
  • Salts regenerados, sessões encerradas, senhas e chaves de API trocadas
  • Porta de entrada identificada e corrigida
  • Monitoramento nos dias seguintes

Quando chamar um profissional

Este é exatamente o roteiro que um profissional seguiria, então se você domina SSH, WP-CLI e SQL, dá para fazer sozinho. Vale chamar ajuda quando:

  • o site é crítico (loja, captação de clientes) e cada hora fora do ar custa dinheiro;
  • o site já foi reinfectado depois de uma limpeza;
  • há dados de clientes envolvidos e você precisa de um relatório do que aconteceu;
  • a hospedagem suspendeu a conta ou o Google já está exibindo aviso;
  • você não se sente seguro mexendo em arquivos e banco de produção.

Nesses casos, a Mobgeek faz a limpeza de site WordPress invadido: diagnóstico, remoção de malware e backdoors, restauração, troca de credenciais, hardening, pedido de revisão no Google e relatório, com 30 dias de garantia contra reinfecção. Começa em até 24h, a partir de R$ 790, e há um plano mensal de proteção para quem quer monitoramento depois. Se quiser, peça um orçamento contando o que você já encontrou.

Perguntas frequentes

Um plugin de segurança remove todo o malware do WordPress?

Ajuda bastante, mas raramente remove tudo. Scanners reconhecem padrões conhecidos e podem deixar passar backdoors novos, muito ofuscados ou guardados no banco de dados. Use o plugin como apoio e faça a reinstalação a partir de fontes oficiais.

Posso simplesmente apagar os arquivos infectados que o scanner apontou?

Apagar só o que foi apontado costuma deixar backdoors para trás, e o site volta a ser infectado. Além disso, se o arquivo infectado for do núcleo ou de um plugin, apagar pode derrubar o site. O mais seguro é substituir núcleo e plugins por cópias oficiais e revisar o que sobrar.

Por que o malware volta depois que eu limpo?

Normalmente por um destes motivos: ficou um backdoor escondido, a falha que permitiu a invasão não foi corrigida (plugin vulnerável, tema pirata), alguma senha não foi trocada ou outro site na mesma conta de hospedagem continua infectado e reinfecta o seu.

Preciso trocar as salts do WordPress depois da limpeza?

Sim. Regenerar as chaves e salts do wp-config.php invalida todos os cookies de login, inclusive os que o invasor possa ter roubado. Com WP-CLI basta rodar wp config shuffle-salts.

Quando vale chamar um profissional?

Quando o site é crítico para o negócio, tem loja ou dados de clientes, já foi reinfectado depois de uma limpeza, a hospedagem suspendeu a conta ou você não se sente seguro mexendo em SSH, WP-CLI e banco de dados.


Leia também