Elderward
Scanner de malware e resposta a incidentes para WordPress. Instale o plugin, rode uma varredura pelo painel e descubra o que entrou no site e por onde, sem alterar nada.
$ cd wp-content/plugins $ git clone https://github.com/fioa8c/elderward.git elderward $ wp plugin activate elderward
Gratuito e GPL. Ainda não está no WordPress.org.
Uma varredura, direto do painel
Abra o Elderward no menu do painel e clique em Start scan. A varredura roda em segundo plano pelo WP-Cron, então você pode fechar a aba, e ela não altera nada no site.
Scan this site
- WordPress, plugin and theme files compared with the official copies
- Known malware in your files
- Suspicious entries in the database and admin accounts
- Files with faked dates, and the server crontab
- Access logs in /var/log/apache2
Last scan: complete. Started 2 Nov 2026 14:02, finished 14:09.
Findings
Export as text Export as JSON| Severity | Type | Where | Details | Actions |
|---|---|---|---|---|
| HIGH | UPLOADS_PHP | wp-content/uploads/2024/03/cache.php | executable PHP inside wp-content/uploads - usually a webshell dropped through an upload form | Mark as false positive Download sample Look up on VirusTotal |
| HIGH | DB_OPTION_IOC | db:wp_options:widget_text | db.option.hidden-iframe: Hidden iframe inside an option value - a classic drive-by injection | Mark as false positive |
| MEDIUM | DB_NEW_ADMIN | db:wp_users:ID=7 | administrator "wp-sync" <wp-sync@example.com> registered 2024-03-12 03:16:40 - created within the last 30 days, the classic takeover artifact; verify who created it | Mark as false positive |
| LOW | INTEGRITY_MISSING | wp-admin/css/about.min.css | core 6.6.2: file from the official package is missing | Mark as false positive |
O que uma varredura examina
Sete verificações num relatório só. Tudo o que impede uma verificação, como um arquivo ilegível ou uma extensão PHP ausente, aparece como erro em vez de ser pulado.
- Verificações rápidasUPLOADS_PHP, PHP_PREPEND, MU_PLUGIN, HIDDEN_PHP
- Os esconderijos baratos dos invasores: PHP executável em
wp-content/uploads, ganchosauto_prepend_fileem.user.ini,php.inie.htaccess, mu-plugins que carregam sem precisar de ativação e arquivos PHP ocultos (começando com ponto). - IntegridadeINTEGRITY_MODIFIED, INTEGRITY_MISSING, INTEGRITY_EXTRA
- O core, cada plugin e cada tema comparados com o pacote oficial do wordpress.org da versão instalada. PHP sobrando dentro do core ou de um plugin é o clássico webshell plantado. Plugins premium e temas filhos que não podem ser verificados aparecem como tal, então um relatório limpo nunca significa, em silêncio, "não verificado".
- Banco de dadosDB_NEW_ADMIN, DB_ROLE_CAPS, DB_OPTION_IOC, DB_POST_IOC
- Só leitura. Lista todos os administradores e destaca os recentes, aponta papéis que não são de admin mas ganharam poderes de tomada de controle, PHP, iframes ocultos ou JavaScript ofuscado em opções e posts,
siteurlouhomesequestrados eactive_pluginsadulterado. - Logs de acessoLOG_IOC, LOG_FILE_CORRELATION
- Opcional: informe um arquivo ou pasta de logs nas configurações, incluindo arquivos rotacionados e
.gz. Acessos a webshells, tentativas de exploit em plugins vulneráveis conhecidos, sondagens de.env, injeção de código e enxurradas de força bruta, além dos arquivos modificados minutos depois desse tráfego. - Assinaturas de malwareMALWARE_FOUND, SIGNATURE_MATCH
- Injeções conhecidas, como as campanhas JavaScript
ndsw/ndsxewqpq, mais as assinaturas que você escrever. Pelo painel isso roda em modo de simulação. A limpeza é feita pela linha de comando. - Datas de modificaçãoTIMESTAMP_OUTLIER, TIMESTAMP_TIMESTOMP
- Arquivos alterados depois do resto do pacote, e PHP cuja data de modificação foi recuada com
touch. São pistas, não provas. - CrontabCRONTAB_IOC
- O crontab do usuário que roda o PHP, verificado em busca de decodificadores base64 encadeados por pipe, downloads do pastebin e droppers em diretórios tmp.
Além da varredura
O resto da página do Elderward, aba por aba.
- Revisar achadosAba Scan
- Marque um achado como falso positivo, com uma nota. Num arquivo, a marca só vale enquanto ele for byte a byte o mesmo que você revisou. Download sample empacota o arquivo suspeito num zip criptografado com a senha
infected, e achados de arquivo têm um link para consultar o hash no VirusTotal. Exporte o relatório em texto ou NDJSON. - Varreduras agendadasAba Scan, Settings
- Diárias, duas vezes por dia ou semanais, no fuso horário do site. Se o WP-Cron não for confiável no seu servidor, rode as varreduras só enquanto a página estiver aberta.
- Assinaturas própriasAba Signatures
- Texto exato ou expressões regulares para arquivos, valores de opções ou conteúdo de posts. Teste contra uma amostra colada ou um arquivo do site e depois compartilhe em JSON com outros sites e com a linha de comando. Assinaturas próprias só detectam.
- Blindagem do servidorAba Hardening
- Regras de servidor que bloqueiam PHP em uploads, cópias do
wp-config.php, arquivos ocultos, backups e logs, arquivos internos do WordPress e listagem de pastas. Comece pelo modelo Recommended ou Strict, ou escolha cada proteção. No Apache e no LiteSpeed ele grava no.htaccesse desfaz tudo se o site parar de responder. No Nginx você baixa um arquivo para incluir na configuração. Check now testa o que o servidor de fato bloqueia. - Modo de recuperaçãoAba Recovery
- Uma página protegida por chave que funciona quando o WordPress não carrega, depois de uma tela branca ou um erro crítico. Mostra os erros de PHP que derrubaram o site e o plugin ou tema responsável, e roda a varredura completa. Sem chave, responde 404.
- Assistentes de IAAba AI assistants
- No WordPress 6.9 ou mais novo, com o plugin MCP Adapter, Claude, ChatGPT, Antigravity ou Cursor podem rodar varreduras, explicar achados, ler arquivos suspeitos e escrever assinaturas com você. Eles não limpam nem alteram arquivos. Sem MCP? Copie um resumo para qualquer chat.
Proteções que ele nunca quebra
Ele roda em sites já comprometidos, então trata todo nome de arquivo, linha de log e resposta de API como hostil.
-
A varredura não altera nada
As varreduras do painel só geram relatório. Os únicos arquivos que o painel grava são as regras de
.htaccessque você aplicar e a chave de recuperação que você criar. -
Nada sai do servidor
Sem conta e sem telemetria. As únicas requisições externas vão para o wordpress.org, atrás de checksums e pacotes oficiais.
-
A verificação TLS fica ligada
Um "tudo limpo" jamais pode vir de um invasor posicionado entre o site e o wordpress.org.
-
O banco de dados só é lido
Apenas consultas SELECT, o
wp-config.phpé lido sem ser executado e os valores guardados nunca passam por unserialize, o que poderia disparar uma injeção de objeto PHP. -
Verificação bloqueada não passa em silêncio
Uma extensão ausente, um banco inacessível ou um log ilegível vira um achado ERROR, nunca é pulado em silêncio. Um relatório limpo significa que todos os scanners de fato olharam.
-
Falso positivo não esconde arquivo alterado
A marca num arquivo guarda o SHA-256 dele. Se o arquivo mudar, o achado volta.
-
Assistentes olham, nunca mexem
Nenhuma ferramenta de IA limpa, restaura ou grava arquivos. Tudo o que é escaneado vai marcado como dado não confiável, então um arquivo plantado não consegue dar ordens ao assistente.
-
Restaurações são verificadas antes
Cada arquivo do zip oficial é conferido byte a byte com os checksums de referência antes de ser gravado. Um pacote adulterado é recusado, e arquivos sobrando nunca são apagados.
-
A blindagem se desfaz sozinha
Depois de gravar as regras, o Elderward carrega a página inicial, o login e uma requisição do painel. Se algum deles quebrar, todos os arquivos voltam exatamente como estavam.
A limpeza acontece no terminal
Limpar e restaurar gravam arquivos, então rodam pelo WP-CLI, onde você faz backup e simula antes. Cada scanner também é um comando wp elderward, com saída pronta para pipe.
Limpar e restaurar
$ wp elderward scan --dryrun
$ wp elderward scan
$ wp elderward integrity --restore --dryrun
$ wp elderward integrity --restore --quarantine-dir=/path/outside/webroot
Arquivos limpos são gravados num arquivo temporário e renomeados no lugar, então uma gravação que falha não trunca o original. --quarantine-dir guarda cada original como evidência.
Quando o WordPress não carrega
Abra o modo de recuperação, ou rode os mesmos scanners a partir da pasta do plugin com a CLI independente. Ela precisa de PHP 5.6 e de nenhum WordPress funcionando.
$ php bin/elderward.php scanall=1 scandirectory=/path/to/wp-root
$ php bin/elderward.php help=1
Texto
Uma linha por achado, no mesmo formato em todos os scanners. Caminhos e conteúdo de logs vêm do servidor comprometido, então caracteres de controle e vírgulas em caminhos são codificados com %. Um nome de arquivo malicioso não consegue forjar uma linha de achado.
SEVERITY,TYPE,path,detail
JSON
--format=json imprime um evento por linha no stdout e manda o progresso para o stderr. A exportação JSON do painel usa os mesmos eventos.
{"event":"finding","severity":"HIGH",
"type":"LOG_IOC","path":"...","detail":"..."}
O que o código de saída diz
- 0
Limpo, ou só achados informativos.
- 1
Erro de uso ou fatal. Confira os argumentos.
- 2
Achados LOW, MEDIUM ou ERROR para revisar.
- 3
Achados HIGH. Uma limpeza bem-sucedida também sai com 3: havia malware.
Como instalar
O Elderward ainda não está no WordPress.org, então instale pelo GitHub.
Baixe o plugin
$ cd wp-content/plugins $ git clone https://github.com/fioa8c/elderward.git elderward $ wp plugin activate elderward
Ou baixe o repositório como zip e descompacte em wp-content/plugins/elderward/. A pasta precisa se chamar elderward.
Depois de ativar
- Abra o Elderward no menu do painel, ou no Network Admin em multisite, e clique em Start scan.
- Em Settings, informe onde ficam os logs de acesso e, se quiser, ative as varreduras automáticas.
- Aplique o modelo Recommended na aba Hardening.
- Crie uma chave de recuperação na aba Recovery, para o modo de recuperação estar pronto se o site quebrar.
- Faça backup e depois limpe com os comandos WP-CLI mostrados abaixo dos resultados.
Requisitos
- WordPress 6.0 ou mais novo e PHP 7.2 ou mais novo. A CLI independente e o modo de recuperação rodam em PHP 5.6.
- Acesso ao shell só para limpar ou restaurar arquivos. O painel não precisa disso.
- WordPress 6.9 e o plugin MCP Adapter para os assistentes de IA.
- Apache ou LiteSpeed com
AllowOverridepara as regras de blindagem que o Elderward grava. No Nginx, alguém com acesso ao servidor inclui o arquivo gerado. - Algumas verificações usam extensões PHP que servidores mais fechados não têm: zlib para logs
.gz, zip para temas e qualquer restauração,shell_execpara o crontab. A falta de uma delas aparece como ERROR.
Faça backup antes de limpar. Simule antes com --dryrun.
Ele encontra malware conhecido. Uma varredura limpa não prova que o site está limpo, e os alertas de log incluem muitas tentativas que falharam.
Envie o que ele deixou passar
O Elderward só conhece malware que alguém já pegou. Se você limpar um site e achar algo que ele não apontou, abra uma issue no GitHub com uma amostra para que a próxima varredura pegue.
O que colocar na issue
- A amostra. O Download sample do achado gera um zip criptografado com a senha
infected, com um manifesto de onde e por que ele foi apontado. O GitHub não aceita um anexo.phpsolto. - O hash SHA-256 e o caminho onde você o encontrou.
- Como ele era carregado: um include no
functions.php, um mu-plugin, uma entrada no cron,auto_prepend_fileou outra coisa. - As versões do WordPress, dos plugins e do tema, se você tiver.
- Para tráfego de ataque, as linhas correspondentes do log de acesso.
- Se você escreveu uma assinatura que pega o arquivo, exporte pela aba Signatures e anexe o JSON.
Prepare pelo terminal
$ shasum -a 256 suspicious.php
$ zip -j -P infected sample.zip suspicious.php
Issues são públicas. Remova tudo o que identifique o site antes de enviar.
Isso inclui nomes de domínio, credenciais do banco, salts, endereços de e-mail e IPs de visitantes nas linhas de log. Nunca anexe o wp-config.php nem um dump do banco.