Informática Numaboa - Tutoriais e Programação
A praga dos spammeiros
Sex 27 Fev 2009 16:01 |
- Detalhes
- Categoria: Joomla
- Atualização: Segunda, 02 Julho 2012 19:42
- Autor: vovó Vicki
- Acessos: 8626
Como se não bastasse a praga dos registros forçados, desde o final de janeiro de 2009 notei uma atividade anormalmente alta nos meus sites. Os arquivos de log estavam ficando inchados demais e os números das estatísticas de visitas e páginas vistas subiam vertiginosamente. Motivo de alegria, mas... quando o milagre é muito grande até o santo desconfia!
Resolvi dar uma analisada nos logs e acabei me deparando com um problemão: A praga dos spammeiros.
Primeiras constatações
Quando dei uma olhada no log do meu servidor web (Apache, naturalmente ), fiquei estarrecida com o número de registros enormes do tipo
193.86.238.33 - - [08/Feb/2009:02:42:54 -0200] "GET /destaque?texto=%3Ca+href%3D %22http%3A%2F%2Fmgty.com%2Fmember.php%3Fu%3D832%22%3Evintage+animal+porn%3C %2Fa%3E+%5Burl%3Dhttp%3A%2F%2Fmgty.com%2Fmember.php%3Fu%3D832%5Dvintage+animal+porn %5B%2Furl%5D+%3Ca+href%3Dhttp%3A%2F%2Fmgty.com%2Fmember.php%3Fu%3D832%3E vintage+animal+porn3C%2Fa%3E+%5Burl%3Dhttp%3A%2F%2Fmgty.com%2Fmemb er.php%3Fu%3D832+%5D+vintage+animal+porn+%5B%2Furl%5D&codigo=%3Ca+href%3D %22http%3A%2F%2Fmgty.com%2Fmember.php%3Fu%3D832%22%3Evintage+animal+porn...
ou de registros curtinhos do tipo
202.156.12.238 - - [15/Feb/2009:14:15:35 -0300] "GET /index.php?option =http://bikelove.hostinginfive.com/bike.htm? HTTP/1.1" 301 1415
Com certeza, puro lixo! Mas o que isto significava? Resolvi dar uma pesquisada nos IPs logados e acabei voltando para o Projeto Honey Pot por que estava na cara que estava lidando com tentativas de spam. Lá pude verificar que a maioria destes IPs eram classificados como Harvester (caçador de endereços) e Comment Spammer (spammer de comentários), ou seja, endereços de um pessoal que adora plantar tranqueira no mundo todo fazendo propaganda duvidosa de pornografia, medicamentos como viagra e cialis e outras baboseiras mais.
O que fazer? Se você também está neste fogo cruzado, acompanhe o que fiz para melhorar esta situação.
Primeiras providências
Infelizmente para muitos de vocês, para poder fazer frente a estes ataques inócuos, mas que consomem largura de banda e são muito perturbadores, é preciso ter acesso total ao servidor que esteja hospedando o site visado. Se você tiver acesso de root ao seu servidor, então a solução apresentada a seguir pode ajudar. Se não, só dá para optar por uma solução mais simples.
Como tenho acesso ao nosso servidor, a primeira providência que tomei foi começar a colocar os IPs maliciosos no iptables - no manual a mão mesmo. Um trabalhão danado, mas que já deu algum resultado. Logada como root (iptables, por princípio, é uma exclusividade do usuário root), fiz entradas como
# iptables -A INPUT -s 87.251.146.18 -j DROP # iptables -A INPUT -s 99.152.147.181 -j DROP
Podem crer, estes dois IPs são bichados mesmo e já estão listados no meu firewall.
Depois de ter colecionado cerca de 200 endereços em menos de 48 horas, percebi que esta não seria uma tática muito eficiente e resolvi partir para uma abordagem mais prática - mesmo porque, se continuasse a caçar spammeiros desta maneira não teria tempo para mais nada, nem para atualizar os sites.
Botando a cabeça para funcionar, pensei o seguinte: meus sites são movidos a Joomla então, por que não tirar proveito deste CMS para capturar informações que serviriam para bloquear visitantes indesejados, fichados no Projeto Honey Pot?
A idéia do plugin
No Joomla 1.5.x, os assim chamados plugins servem para executar rotinas quando são chamados por páginas que estão sendo carregadas ou quando o sistema é acionado. Como o objetivo era que nenhuma página fosse acionada sem que o IP chamador passasse por uma checagem, ficou claro para mim que eu precisava de um plugin do tipo system.
Este plugin precisava identificar o IP chamador, acionar o banco de dados do Honey Pot e, se o IP fosse "do mal", bloquear seu acesso redirecionando-o para um endereço com uma página mostrando "Vá lamber sabão" ou, melhor ainda, redirecionando-o para uma armadilha honey pot.
Acessando a base de dados httpBL do Honey Pot
O Projeto Honey Pot é uma rede de colaboração global cujo objetivo é caçar e fichar IPs com atividades suspeitas. Ao longo dos anos o projeto conseguiu criar um enorme banco de dados que pode ser usado gratuitamente. Para acessar esta base de dados é preciso se cadastrar e depois solicitar uma chave de acesso.
A forma como o Honey Pot disponibiliza as informações do seu banco de dados é, no mínimo, interessante. Nunca havia visto algo semelhante. Colocaram tudo num servidor DNS que pode ser acessado e que responde com um "endereço codificado" do tipo 127.x.x.x. Para exemplificar, digamos que a resposta de uma solicitação a este DNS tenha sido 127.3.5.1. Separando os octetos temos:
- 127: Não tem um significado especial. Diz apenas que a sua solicitação foi recebida. Caso não seja 127, a solicitação não estava formatada corretamente ou ocorreu algum outro erro.
- 3: Representa o número de dias desde a última atividade do IP pesquisado. Este valor varia de 0 a 255, dá uma idéia do nível de atividade do IP e serve para orientar nossa decisão - coisa do tipo, um IP parado há mais de 30, 60 ou 90 dias pode ser desconsiderado.
- 5: É o nível de periculosidade, quanto mais alto, pior!
- 1: Tipo de atividade:
- 0: Rastreamento normal (tipo Google ou Yahoo indexando suas páginas)
- 1: Suspeito
- 2: Harvester (caçador)
- 3: Suspeito + Caçador
- 4: Spammer de comentário
- 5: Suspeito + Spammer de comentário
- 6: Caçador + Spammer de comentário
- 7: Suspeito + Caçador + Spammer de comentário
- >7: reservado para uso futuro
Mais uma coisinha, a solicitação para o servidor DNS precisa ter o seguinte formato:
xxxxxxxxxxxx.IPinvertido.dnsbl.httpbl.org
onde xxxxxxxxxxxx é a chave composta por 12 letras minúsculas que você obteve no Honey Pot e IPinvertido é o IP que você quer pesquisar com os octetos "virados ao contrário". Por exemplo, para pesquisar o IP 201.48.123.184 (mais um dos bichados) a chamada fica assim:
xxxxxxxxxxxx.184.123.48.201.dnsbl.httpbl.org
Antes de criar um plugin partindo do zero, resolvi dar uma procurada no site das extensões do Joomla e acabei encontrando o http:BL Plugin do Michiel Bijland. Dei uma olhada no código do plugin e gostei do que vi.
O plugin httpBL
Este é o código original do plugin - só traduzi as observações:
Avaliando o plugin
Feliz da vida com o meu achado, instalei, configurei e ativei o plugin. Aí, fiquei esperando que alguma coisa acontecesse. Me dei ao trabalho de instalar o componente JSecure, do mesmo autor, porque percebi que o plugin e o componente podiam trabalhar juntos, ou seja, o plugin jogava os IPs bichados nas tabelas do JSecure.
Depois de uns 15 minutos, onde os arquivos de log mostravam intensa atividade dos malignos de plantão, nada aconteceu. Absolutamente NADA! Resolvi explorar o que estava acontecendo criando um log adicional que me mostrasse a atividade do plugin. Antes da linha 102, um pouco antes de explodir as respostas positivas, adicionei o seguinte:
No meu arquivinho de log chamado teste (não esqueça de colocar o seu num diretório acima do diretório raiz do site e com permissão para escrita) apareceram uma porção de IPs. Aliás, apareceram TODOS os IPs! Desabilitei rapidamente este log de teste e novamente botei a cabeça para funcionar: se todos os IPs estavam sendo logados, então para que servia a consulta ao cache? Fui verificar exatamente isto
O diretório /www/meusite/joomla/cache estava vazio, ou seja, o cache não estava funcionando. Como não havia habilitado o cache globalmente no Joomla (nas configurações globais da área administrativa), o plugin não podia "cachear".
Brilhante constatação: se o cache não está funcionando, $responce sempre vai estar vazia. Neste caso, entramos sempre no if da linha 85.
Isto significava que, para todas as requisições de todos os IPs clientes estavam sendo feitas consultas ao dnsbl.httpbl.org sobrecarregando meu servidor e o banco de dados dnsbl. Para que o plugin fizesse cache, evitando consultas desnecessárias independentemente da configuração global, adicionei o seguinte na linha 83:
O resultado foi imediato. Verificando novamente o diretório /www/meusite/joomla/cache constatei que um novo diretório havia sido criado, o /www.meusite/joomla/cache/httpBL e que alguns arquivos já podiam ser analisados. Uns mostravam '0.0.0.0', outros mostravam coisas menos desejáveis como '127.5.32.4' - cujo significado você já conhece: última atividade há 5 dias, nível de perigo 32 e se trata de um Spammer de comentário (4).
Tudo muito bem, tudo muito bom, mas o que fazer para bloquear estes intrusos se o diabo do JSecure não queria funcionar (nenhum IP aparecia no componente)? Desisti do JSecure e resolvi partir para a luta.
Existem componentes e plugins para o Joomla que interceptam IPs, comparam os endereços com uma lista negra que precisamos criar e, caso o IP se encontre na lista, apresentam uma página dizendo que o endereço foi bloqueado. Não serviriam aos meus propósitos por que a caça aos IPs precisava continuar a ser feita e, pior do que isto, o mesmo IP poderia continuar a fazer quantas requisições quisesse e seria logado toda vez que viesse chatear novamente.
Como no começo desta história toda eu estava caçando IPs para colocá-los no iptables, por que não deixar o plugin fazer o serviço? Uma vez no iptables, qualquer nova requisição seria bloqueada e o log nem seria acionado. Para isto, bastava fazer uma chamada shell_exec via PHP para acionar o iptables para que ele colocasse o IP infrator no firewall e tudo estaria resolvido. Foi o que fiz:
Foi mais uma idéia e tanto, só que não funcionou. O que estava faltando era entender um pouco mais das permissões de usuários.
Acionando o iptables
Como já comentei anteriormente, o iptables é uma prerrogativa do usuário root. O plugin, rodando sob a hegemonia do Apache, é do usuário nobody. Pelo menos é assim na minha configuração (para confirmar a sua, dê um ps aux no seu console para determinar o usuário do httpd - Apache). Viiixxxiii, o que fazer para que o usuário nobody pudesse alterar o firewall via iptables?
O arquivo sudoers
No Linux existe um arquivo de configuração no qual podemos definir os privilégios de execução dos usuários do sistema. Este arquivo é o sudoers onde configuramos os sudo. Para encontrá-lo use um whereis:
# whereis sudoers sudoers: /etc/sudoers /usr/man/man5/sudoers.5.gz /usr/share/man/man5/sudoers.5.gz
Na minha distribuição Linux (e acho que em qualquer uma delas) encontrei /etc/sudoers. Dando um cat /etc/sudoers encontrei o seguinte:
# sudoers file. # # This file MUST be edited with the 'visudo' command as root. # # See the sudoers man page for the details on how to write a sudoers file. # # Host alias specification # User alias specification # Cmnd alias specification # Defaults specification # Runas alias specification # User privilege specification root ALL=(ALL) ALL # Uncomment to allow people in group wheel to run all commands # %wheel ALL=(ALL) ALL # Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL # Samples # %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom # %users localhost=/sbin/shutdown -h now
Como nunca havia mexido neste arquivo, dei uma pesquisada e cheguei à conclusão de que deveria inserir uma linha que conferisse ao usuário nobody o direito de usar o iptables. Como é meu hábito, inseri a configuração após a última linha do arquivo:
nobody server = NOPASSWD: /usr/sbin/iptables
onde server é o nome do servidor. Pra mim estava tudo em riba, mas o iptables simplesmente se recusava a reagir. Toca pesquisar novamente. Descobri que todos aqueles aparentes comentários, como # Host alias specification e # User alias specification não eram comentários coisa nenhuma - eram seções do arquivo de configuração! Em primeiro lugar, não podem ser eliminados e, em segundo lugar, minha nova inserção estava fora da seção apropriada. Tirei então minha linha do fim do arquivo e a coloquei na seção # User privilege specification, logo após a configuração do usuário root:
# User privilege specification root ALL=(ALL) ALL nobody server = NOPASSWD: /usr/sbin/iptables
Não é que funcionou? Vocês nem podem imaginar como fiquei feliz. Uma verdadeira belezura, os IPs bichados começaram a aparecer no meu firewall! Foi minha primeira vitória
Comecei a me animar e, de tempos em tempos, chamava um iptables -L -v -n --line-numbers no meu console e a lista só ia aumentando. Deu uma sossegada no site, mas ainda não estava como eu queria...
Observando o hábito dos spammeiros
Analisando as "sujeiras" que estavam escapando do crivo do Honey Pot, descobri que havia mais uma porção de ataques. Relato aqui algumas das "pérolas" que encontrei e como coloquei estes IPs fora de combate.
Injeções PHP
Notei que ainda havia uma porção de linhas no log do Apache com coisas do tipo
122.36.116.147 - - [26/Feb/2009:14:25:40 -0300] "GET /index.php?option=http://babycaleb.fortunecity.co.uk/index.htm? HTTP/1.1" 301 1415 78.42.64.169 - - [26/Feb/2009:15:15:56 -0300] "GET /index.php?option=http://schoolpapers.hostinginfive.com/bike.htm? HTTP/1.1" 301 1415
Que eu saiba, pedir um GET de uma página qualquer (index.php) seguida por um sinal de interrogação (?) é uma chamada PHP com passagem de parâmetros. Se o parâmetro passado é um endereço da web, é claro que só pode se tratar de uma injeção PHP. Antes de tomar alguma atitude mais drástica, dei uma pensada: "existe algum endereço no meu site que chama uma página da web com "http://"? É claro que não! Então é treta :fear:
Estava na hora de dar um pé na b... destes palhaços. O que fiz foi inaugurar um trecho de código que analisasse os IPs que haviam escapado do banco de dados do Honey Pot, ou seja, logo depois da linha 92:
Criei a variável $uri que guarda a solicitação. Caso nesta string de requisição exista 'http://', então o IP deve ser banido. Decidi pela resposta '127.0.50.15' para tentar dizer o seguinte: 127 - resposta positiva; 0 - ataque ocorrido há 0 dias; 50 - nível arbitrário de perigo e 15 - uma classificação acima da fornecida pelo Honey Pot.
A classificação 15 não foi arbitrária, foi usada para que em
ela pudesse ser bloqueada. Como $block pode variar de 0 a 7, para que $responce[3] & block dê um resultado positivo precisamos usar um byte com os últimos três bits setados (15 em binário é 1111).
Como eu queria saber se estava conseguindo bloquear este tipo de ataque, dei mais uma caprichada. Já que havia criado um log "particular", usei este log para registrar minhas capturas particulares, inclusive com o tipo de requisição, além da data e da hora:
Para minha alegria e gáudio, não demorou muito e comecei a caçar alguns dos malfeitores de plantão tentando injetar PHP no meu site. Todos foram parar no iptables
O bacana desta história é que acabei pegando por tabela alguns dos ataques mais comuns a sites Joomla:
mosConfig_absolute_path=http://bmwmotoclubkw.com//administrator/components/com_freechat/test.txt?? com_remository&Itemid=298&func=fileinfo&id=http://piap.msb.gob.pe/preventorioweb//modules/mod_gcalendar_upcoming/languages/test.txt??
e algumas coisinhas mais. Novamente
Injeção PHP 2
Minha segunda constatação foi que havia um caminhão de chamadas para os primeiros links apresentados na página inicial (home page). O interessante é que a maior parte do lixo era colocado no link identificado como /destaque e que a tranqueira sempre aparecia depois de um /destaque?texto=. Ficou claro para mim que se tratava de uma nova treta :fear:
Segunda constatação, segunda providência tomada. Era só acrescentar mais uma linha nas minhas capturas particulares:
Para identificar o agressor, usei o próximo valor com os três últimos bits setados (23 em binário é 0001 0111). Aqui vai uma dica: para criar novas classificações é só ir acrescentando 8 aos valores previamente determinados (7 + 8 = 15 + 8 = 23 + 8 = 31...).
Foi mais uma baita de uma limpada e a coisa começou a acalmar pro meu lado. É claro que cada site é único e que os tipos de ataques dependem do que os panacas (ou os programinhas criados por estes panacas) encontram pela frente. Dei dois exemplos do que fiz só para ilustrar o texto. Procure no seu contexto analisando o arquivo de log e o arquivo de erros do Apache, mas cuidado...
Cuidados ao criar regras
Não invente de criar regras a torto e a direito só porque a situação está preta. Por pior que esteja, uma boa análise antes de decidir o que fazer é primordial. Digo isto por experiência própria, porque criei algumas regras que, depois de uma observação mais detalhada, se mostraram absolutamente equivocadas, ou seja, eu estava excluindo visitantes do meu site que não tinham culpa no cartório :blush:
O iptables
Depois de brigar alguns dias com os spammeiros lembrei-me que, se eu rebootasse o servidor, toda minha coleção de IPs bichados iria pro espaço. Resolvi mudar meu "log particular" de lugar (um pouco antes de inserir uma nova regra no iptables) e alterar um pouco o formato para que pudesse ser usado como shell script na hora de levantar o servidor. Além disto, também resolvi capinar todo o código que o autor do plugin havia previsto para o componente JSecure porque ele não seria mais necessário e isto daria uma enxugada no código. Veja como ficou a minha versão semifinal do plugin - digo semifinal porque ainda posso adicionar mais algumas regras.
O plugin (semi)final
Finalmentes
Espero que estas dicas sirvam para alguém. Para mim o processo foi doído (doido também), mas valeu.
Abraços da vó Vicki, um tanto exausta