segunda-feira, 17 de outubro de 2011

HomeMade Patch Management System - Parte 1

Com a facilidade da virtualização, percebi que possuia inúmeros sistemas desatualizados em casa e como não era trivial saber o que realmente precisava ser atualizado. Independente da criticidade dos mesmos, como em qualquer outro ambiente, vi que finalmente era hora de ter um controle efetivo das atualizações de segurança pendentes.

Após algumas pesquisas, não consegui achar um software que atendesse as minhas necessidades de automatizar e consolidar esse processo. Foi então que resolvi integrar algumas tecnologias que conheço para resolver o meu problema e criar um HomeMade Patch Management System utilizando:
  • LAMP (Linux, Apache, MySQL, PHP)
  • Nessus
  • Perl



No meu caso, utilizei o Linux CentOS 5.6 como servidor, com o pacote RPM do Nessus disponível no site oficial, mas qualquer outra distribuição funcionará sem problemas. A própria Tenable já disponibiliza diversos pacotes para diversos sistemas operacionais.

A única atenção especial é a instalação do Nessus com a licença HomeFeed. Caso você vá utiliza-lo em um ambiente corporativo, é necessário comprar a licença ProfessionalFeed. Recomendo usar o guia da própria Tenable para maiores detalhes: Nessus 4.4 Installation Guide.

Antes de prosseguir para os scans com o Nessus, é essencial verificar se está tudo OK com a licença da sua instalação, assim como garantir que os plugins serão atualizados diariamente.

Verificando a licença:

[dms@s1 ~]# /opt/nessus/bin/nessus-fetch --check
nessus-fetch is properly configured to receive a HomeFeed

Vericando a atualização automática dos plugins:

[dms@s1 ~]# grep _update /opt/nessus/etc/nessus/nessusd.conf
auto_update = yes
auto_update_delay = 24

As configurações acima, ativas por padrão desde a versão 3.0 do Nessus, garantem que a cada 24 horas os plugins serão atualizados. Para verificar a data da última atualização, consulte o timestamp da variável PLUGIN_SET no arquivo abaixo:

[dms@s1 ~]# cat /opt/nessus/var/nessus/plugin_feed_info.inc
PLUGIN_SET = "201110131236";
PLUGIN_FEED = "HomeFeed (Non-commercial use only)";

Após todas as instalações e verificações, o primeiro passo é entrar na console de configuração do Nessus ( https://servidor_nessus:8834 ) e configurar uma Policy com os plugins desejados. Será necessário informar o login e senha criados durante a instalação do Nessus. Caso você não tenha criado, use o comando /opt/nessus/sbin/nessus-adduser

Para criar uma nova Policy, clique no menu Policies->Add, que o levará para a tela abaixo:



A configuração inicial é bem intuitiva. A única preocupação que tive neste passo foi desmarcar todos os portscanners, com exceção do "Ping Host", por questão de performance. Este foi habilitado para que apenas os hosts "vivos" (verificados com ICMP Echo Request) sejam scaneados. Não vi necessidade de realizar um portscan em todos os servidores a cada vez que a política for executada, mas isso é algo pessoal. Habilitei também a opção "Reduce Parallel Connections on Congestion" para evitar problemas de congestionamento na rede. Os outros parametros todos são padrão e não foram alterados.

Ao finalizar, clique em Next ou no menu à esquerda, selecione "Credentials":



Para que o Nessus consiga conectar e obter informações dos servidores, é necessário configurar as credenciais de autenticação dentro da Policy, tanto para servidores Linux/BSD/UNIX através de SSH, como para servidores Windows. Recomendo criar um usuário exclusivamente para essa auditoria, por questões de controle.

Veja que existem diversas opções de configuração desse usuário. A forma mais recomendada é cria-lo sem privilégios, com permissão para utilizar o sudo e sua autenticação ser através de chaves, no caso dos sistemas Linux/UNIX-like. Um manual bem explicativo para configuração de chaves pode ser encontrado na documentação do Ubuntu. Para Windows, não vi outra solução: é necessário configurar um usuário com privilégio administrativo local.

Novamente, clique em Next ou no menu à esquerda, selecione "Plugins":



Como o foco é apenas verificar quais os patches de segurança pendentes nos sistemas, selecione os plugins "Local Security Checks" de acordo com os sistemas operacionais presentes no seu ambiente, inclusive separados por distribuição Linux, se precisar. Exemplos:

  • CentOS Local Security Checks
  • FreeBSD Local Security Checks
  • MacOS X Local Security Checks
  • Ubuntu Local Security Checks
  • Outros

Outros plugins serão automaticamente selecionados, por conta das configurações padrão do Nessus, dentro da subcategoria General e Settings, que você deve deixar selecionado. Um plugin interessante que pode também ser ativado é Settings-> Authenticated Check: OS Name and Installed Package Enumeration, para obter a lista de pacotes instalados.

Com todos esses passos definidos, clique em Submit e sua Policy está criada. É muito importante que você execute-a em alguns hosts para testes e verificar se o resultado está conforme o esperado. Essa execução inicial também será importante para validar se o usuário configurado está OK.

Um ponto importante agora é a instalação do pacote perl-Net-Nessus-XMLRPC, disponível nos principais repositórios Linux ou através do CPAN. Ele permitirá a integração entre o script Perl mostrado abaixo e o Nessus, através do protocolo Nessus-XMLRPC. Caso tenha interesse em conhecer a documentação desta implementação em Perl, recomendo checar a página oficial.

Existe essa mesma implementação do Nessus XMLRPC em Python, caso prefira utiliza-la. O conceito será o mesmo, assim como os parâmetros usados.

#!/usr/bin/perl

# Original script found at: http://www.centralconsultancy.com

if ($#ARGV < 0) {
 print "usage: nessus.pl target-file\n";
 exit;
}

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
$year += 1900;
$mon += 1;
my $datetime = sprintf "%04d%02d%02d%02d%02d", $year, $mon, $mday, $hour, $min;

use Net::Nessus::XMLRPC;

# On 1st field, '' is same as https://localhost:8834/
my $n = Net::Nessus::XMLRPC->new ('','usuario_nessus','senha_nessus');
my $target;
my $targets = $ARGV[0];

die "Cannot login to: ".$n->nurl."\n" unless ($n->logged_in);

print "Logged in\n";

my $polid=$n->policy_get_id('nome_policy_criada');
my $polname=$n->policy_get_name($polid);

print "Using policy ID: $polid with name: $polname\n";

my $scanid=$n->scan_new_file($polid,"report.$datetime",$target,$targets);

while (not $n->scan_finished($scanid)) {
        print "$scanid: ".$n->scan_status($scanid)."\n";
        sleep 15;
}

print "$scanid: ".$n->scan_status($scanid)."\n";
my $reportcont=$n->report_file_download($scanid);
my $reportfile="report.$datetime.xml";

open (FILE,">$reportfile") or die "Cannot open file $reportfile: $!";
print FILE $reportcont;
close (FILE);

Substitua acima os campos em vermelho (login, senha e policy) pelos criados nos primeiros passos desse tutorial para tornar o script funcional. Crie agora um arquivo texto com os nomes ou IPs de todos os servidores, um por linha, que deseja verificar os patches de segurança pendentes e o utilize como parâmetro do script Perl, conforme exemplo abaixo:

[dms@s1 ~]$ chmod +x nessus.pl
[dms@s1 ~]$ ./nessus.pl lista-servidores
Logged in
Using policy ID: -11 with name: patches
176927b5-396d-432f-bd3b-08ec3688e7952f13b14cbfca2a98: running
176927b5-396d-432f-bd3b-08ec3688e7952f13b14cbfca2a98: completed


O resultado final do scan será um arquivo report.DATE.xml com todos os patches de segurança pendentes separados por host. Tenha em mente que atualizações não relacionadas a segurança não serão listadas nos relatórios do Nessus,  assim como as falhas ainda não corrigidas pelo fabricante. É muito comum a lista de patches pendentes dele ser muito menor que as apontadas pelos gerenciadores de pacote.

É importante destacar também que o Nessus XMLRPC não aceitou, pelo menos nos meus testes, mais do que 20 linhas no arquivo texto com os servidores, então usemos a criatividade para criar um loop e realizar os scans em lotes com um shellscript:

#!/bin/bash

# garantindo o diretorio correto
cd /home/dms/audit

# dividindo servidores em arquivos de 20 linhas com o prefixo splitscan
split lista-servidores splitscan --lines=20

# loop para executar o scan em todos os arquivos separados acima
for a in `ls splitscan*`; do ./nessus.pl $a; done

# removendo todos os arquivos acima
rm /home/dms/audit/splitscan*

Basta agora inserir este script no crontab de acordo com a periodicidade desejada e você terá relatórios em XML com todas as atualizações de segurança pendentes no seu ambiente.

Na segunda parte do artigo, mostrarei como inserir esses dados em XML obtidos pelo Nessus no MySQL e alguns exemplos de relatórios utilizando PHP para visualizar os resultados de forma consolidada.

Nenhum comentário:

Postar um comentário