Saudações,
2019 começou agitado! Em menos de dois meses eu peguei dois clientes e suas instalações de WordPress invadido.
E algo me diz que mais sites aparecerão infectados, pois, até a data deste post, 33.4% dos sites são feitos em WordPress.
Entretanto, não desanime. Me permita fazer uma "acho analogia": empresas como a Sony, Forbes... a Casa Branca... usam e não reclamam do WordPress. O que tem acontecido nos últimos dias, acho eu, que seja algo parecido com o Windows, Linux, MacOS... um programa OpenSource ou Proprietário está com falhas, este permite a invasão e quem leva a "fama" é o Sistema Operacional.
Desinfectando sites WordPress invadidos
Este post não tem a menor intenção de ser um guia definitivo. Use-o apenas como um "ponta pé" inicial para sanar o seu problema. Este foi o caminho que eu escolhi; exitem outros.
Primeiro, via FTP, eu baixei o site, e pelo phpMyAdmin o seu banco de dados. Depois, com o usuário shell em mãos, eu ascendi à pasta web do site, neste caso a public_html, e executei os seguintes comandos:
Corrigindo os permissões dos arquivos e pasta...
$find ./ -type f -exec chmod 644 {} \;
$find ./ -type d -exec chmod 755 {} \;
Abra o arquivo .htaccess para edição...
$vi .htaccess
Dentro dele coloque as seguintes diretivas...
# DESATIVA LISTAGEM DE DIRETORIO Options -Indexes # https://kb.sucuri.net/warnings/hardening/http-trace <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_METHOD} ^TRACE RewriteRule .* - [F] </IfModule> <IfModule mod_headers.c> # https://kb.sucuri.net/warnings/hardening/headers-x-content-type Header set X-Content-Type-Options nosniff # https://kb.sucuri.net/warnings/hardening/headers-x-frame-clickjacking Header always append X-Frame-Options SAMEORIGIN # https://kb.sucuri.net/warnings/hardening/headers-x-xss-protection Header set X-XSS-Protection "1; mode=block" </IfModule> # https://codex.wordpress.org/Hardening_WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / # DEIXE COMENTADO QUANDO USAR O DUPLICATOR RewriteRule ^wp-snapshots/ - [F,L] RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php$ - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] </IfModule> # NEGA ACESSO DIRETO AO... <FilesMatch "(wp-config|xmlrpc)\.php$"> order allow,deny deny from all </FilesMatch> # NEGA ACESSO SE INICIADO COM PONTO <files ~ "^\..*"> order allow,deny deny from all </files>
Proteja o diretório upload criando um .htaccess...
$vi wp-content/uploads/.htaccess
Com o conteúdo...
# https://codex.wordpress.org/Hardening_WordPress <Files ~ "\.ph(?:p[345]?|t|tml)$"> deny from all </Files>
Isto foi apenas a preparação. eheheh Agora vamos para a "brincadeira".
Com o comando egrep procure por alguns padrões...
$egrep -r '@include "\\' ./
Você deve ver uma saída do tipo...
Remova, de cada arquivo localizado, a linha que casa com o padrão pesquisado!
Execute...
$egrep -r "\\\$[a-z]+ = .*;\\\$[a-z]+ = Array" ./
Exemplo da saída...
Aqui eu peguei o caso dos arquivos de nomes aleatórios. Usando a opção -l no egrep podemos pegar apenas os nomes dos arquivos; no meu caso foram:
./wp-includes/js/tinymce/langs/xhwvkpvd.php
./wp-includes/ID3/brfoxngy.php
./wp-content/endurance-page-cache/-/-/mjoiuhex.php
./wp-content/uploads/2018/xbcycrbw.php
./wp-content/plugins/members/templates/xgwvimjf.php
./wp-content/plugins/admin-menu-editor/lajpjcjr.php
Apague todos os aquivos de nomes aleatórios que o comando retornou para você.
Você pode usar o comando xargs para agilizar a tarefa de remoção!
Agora execute...
$egrep -r "\\\$_[a-z0-9]+ = basename\/" ./
Minha saída foi...
Como você pode ver, temos um arquivo PHP disfarçado de .ico, e com o seu nome iniciando com ".", ou seja, para um sistema Unix Like não basta apenas um ls para listar os arquivos, mas, um ls -a para que o mesmo liste também os arquivos ocultos.
Nas instalações de WordPress que eu peguei, havia mais de um arquivo deste tipo! Se for este o seu caso, apague todos o arquivos .ico que contem comandos PHP.
Execute...
$egrep -r "eval\/\*[a-z]+\*\/\([a-z]+\(\\\$" ./
Saída...
Aqui em encontrei e apaguei apenas o arquivo kptgwxby.php; este de nome aleatório.
Como penúltimo comando, execute...
$egrep -r "\[\\\$[a-z]+ % strlen\(\\\$[a-z]+\)\]" ./
Saída do comando...
Mais um arquivo de nome aleatório que pode, e vede ser apagado.
E para finalizar com o uso do egrep, execute...
$egrep -r 'dgreusdi' ./
Saída que eu obtive...
Arquivos de nomes aleatórios? Apague!
WordFence e o Quttera
Pergunta: Por que você não usou um plugin de segurança como o WordFence e o Quttera para iniciar a limpeza?
Resposta: Porque depois de instalado ambos os plugins, nem um deles iniciava a checagem do sistema. O infecção impedia a execução de ambos.
Para ser mais exato, em uma das instalações, o wp-load.php estava infectado. Com isto o WordFence, por exemplo, retornava uma mensagem que o Scan tinha recebido um comando stop. Já o Quttera aparentemente iniciava o processo de verificação, contudo ficava "eternamente" procurando e não mostrava nada nos logs.
Depois de limpar o wp-load.php, eu reinstalei manualmente ambos os plugins, e este funcionaram corretamente.
Bem, se você chegou até aqui, eu acredito que agora você, assim como eu, já pode terminar a limpeza com a excelente ajuda do WordFence e do Quttera.
Verificação online
Use o inspetor de elementos do seu navegador e também use os links abaixo para ver exatamente o que o seu site está carregando quando é acessado.
Use o comando diff
Como um desencargo de consciência, eu baixei do wordpress.org a mesma versão do WordPress instalada, e usei o comando diff para comparar os arquivos; por exemplo:
$diff --brief -r /tmp/wordpress/ public_html/
Only in public_html/: favicon.ico
Only in public_html/: .htaccess
Only in public_html/: .htaccess.bkp
Files /tmp/wordpress/license.txt and public_html/license.txt differ
Only in public_html/: robots.txt
...
Ah! Eu também modifiquei as permissões de alguns arquivos para 444, atualizei alguns plugins e desativei outros que não estavam em uso, desativei o acesso ao /wp-json para usuários não autenticados e ativei um captcha no /wp-admin. Usei algumas RegExp na consulta ao banco de dados para localizar alguma infecção, mas não encontrei nada de errado.
Caso você mesmo queira fazer uma auditoria no seu site WordPress, use a ferramenta WPScan. Esta pode ser baixada no site wpscan.org. Se você usa o Kali Linux, este já traz a ferramenta instalada e pronta para o uso; confira youtube.com/results?search_query=kali+linux+wpscan.
Bibliografia
- stopbadware.org/webmaster-help
- aw-snap.info
- aw-snap.info/articles/spam-hack-wordpress.php
- wordpress.org/support/article/changing-file-permissions
- codex.wordpress.org/FAQ_My_site_was_hacked
- codex.wordpress.org/Hardening_WordPress
- sucuri.net/guides/how-to-clean-hacked-wordpress
- etalented.co.uk/recover-hacked-wordpress-website
- blog.laserphile.com/2018/11/removing-persistent-backdoor-on.html ( Brother, what incredible post! )
- secure.wphackedhelp.com/blog/wordpress-malware-redirect-hack-cleanup
Paz a todos!
Atualização de 26 de Julho de 2019
Peguei um serviço para limpar 4 site que estavam com erro 500 no wp-admin. O erro foi causado pela existência de arquivos infectados.
Todo os sites funcionavam corretamente, apenas o wp-admin estava inacessível.
Como havia urgência de retornar os sites, eu apenas baixei o essencial por FTP.
Depois baixei em br.wordpress.org/download/releases em baixei a versão do WordPress correspondente a cada site.
Como eu não tinha acesso ao wp-admin, para saber a versão do WP instalada no site, eu abri o arquivo version.php dentro do wp-includes...
Com o numero da versão em mãos, basta baixar o lançamento correspondente e enviar o CORE via FTP.
Feito isto o erro 500 sumiu e o wp-admin ficou acessível outra vez. Depois eu procedi com a limpeza manual; tinha muitos arquivos .php com nomes aleatórios.
Eu não instalei a versão mais recente do WP a pedido do cliente. Ele assumiu a responsabilidade de checar a compatibilidade dos plugins para atualizar sem ter "dor de cabeça".
Atualização de 29 de Julho de 2019
Caso de plugin desatualizado...
Todos o site estava funcional, mas ao acessar o wp-admin ou uma pagina inexistente o site era redirecionado para uma pagina externa e maliciosa!
Fiz o backup do básico e reenviei o CORE mas não surtiu efeito. 👎
Via SSH, eu pesquisei o nome do site malicioso dentro dos arquivos do WP. Achei várias entradas dentro dos arquivos de cache do pluing W3 Total Cache.
Removi todas as entras do W3 Total Cache dentro do .htaccess.
Acessei a pasta dos plugins e renomeei o pasta w3-total-cache para _w3-total-cache.
Também apaguei a pasta cache dentro do wp-content.
Feito isto o wp-admin retornou...
Não se preocupe com o erro referente ao advanced-cache.php e o object-cache.php. Basta você instalar e ativar o pluing outra vez.
Você também pode baixar e enviar o plugin manualmente; surte o mesmo efeito!
Ah... checando o banco de dados do site em encontrei uma entrada do site malicioso na tabela wp_options no campo siteurl; aqui deve conter algo do tipo https://nome-do-seu-site.
Atualização de 03 de Agosto de 2019
Somente hoje eu tive tempo de verificar os logs do servidor web, e percebi que o W3 Total Cache não foi a porta de entrada.
O plugin vulnerável em questão foi o ND Shortcodes!
Veja a imagem quando o plugin é usado para modificar o campo siteurl da tabala wp_options:
Identificado o problema, eu, como de praxe, fui no site do plugin, na área de suporte acessando wordpress.org/support/plugin/nd-shortcodes.
De cara os dois primeiros tópicos estão relacionados com Hack/Exploit:
1 - wordpress.org/support/topic/nd-shortcodes-hacked-exploited
2 - wordpress.org/support/topic/hack-exploit-of-this-plugin-my-experience-and-how-i-worked-it-out
Tudo parece se resumir a uma falha no plugin que permite elevação de privilégios.
Enfim... como eu não sou o responsável pelo site, eu solicitei ao administrador do site que atualizasse o seu plugin que está na versão 5.6 para a ultima versão disponível; à 5.9.1.
Verificando o registro de mudança ( wordpress.org/plugins/nd-shortcodes/#developers ) podemos ver que a versão 5.9 já havia feito a correção da falha:
Changelog
5.9.1
- Sanitize, validate, and escape all datas on POST and GET requests
- Improved plugins_url()
- Removed post-search, import/export and locations features.
5.9
- Improved nd_options_import_settings_php_function function for security reasons
0 comentários:
Postar um comentário