quarta-feira, 10 de fevereiro de 2010

Hashset de Malware

Uma tecnica muito útil para um investigador ganhar tempo ou para ser alertado quanto a presença de arquivos maliciosos na máquina investigada é a filtragem por hashset.

De maneira muito resumida (já falamos nesse tópico aqui no blog), a filtragem por hashset permite, durante uma varredura pelos arquivos da imagem sendo periciada, eliminar do foco da investigação aqueles arquivos que são conhecidos e não poderiam ser relacionados com nenhum ponto ou problema da nossa investigação. Esses arquivos, conhecidos como known good, são os arquivos originais do sistema operacional, utilitários, programas e até mesmo imagens que fazem parte de pacotes comerciais ou não. Os arquivos known good podem ser reconhecidos através de um hashset, uma relação deles univocamente identificada pelo seu hash, em MD5 ou SHA-1. Durante a varredura, os arquivos cujo hash se encontram na base known good podem ser tranquilamente ignorados.

Por outro lado, seria interessante que durante essa mesma varredura pudéssemos ser alertados da presença inequívoca de um arquivo malicioso. Podemos atingir esse objetivo através de um hashset que reúna somente arquivos com reputação duvidosa, com malware, ferramentas hacker e códigos destrutíveis. Esse conjunto de hashs é comumente conhecido como known bad hashset, e a identificação também ocorre pelo hash do arquivo, em MD5 ou SHA-1.

Na verdade, o algoritmo nem precisa ser um desses dois. O que precisamos é ter a base de hashs (hashset) usando um determinado algoritmo de hash e varrer a imagem calculando o hash de cada arquivo neste mesmo algoritmo.

O problema surge exatamente aqui. A maior base pública de hashsets disponível é a NSRL, e curiosamente ela oferece, na mesma base, as duas classes: known good e known bad. Tomando como exemplo o sorter, se usarmos a base NSRL como known good, os arquivos maliciosos que porventura existirem na imagem serão ignorados. Por outro lado, se usarmos a base como known bad, seríamos alertados erroneamente em milhares de arquivos.

A solução desse impasse, enviada pelo colega Doug White do NIST, está em separar a base (que na verdade é composta por um conjunto de arquivos) em known good e known bad. Isso pode ser feito porque um dos arquivos que compoe a base possui um campo de classificação, e os arquivos known bad tem a classificação "Hacker Tool". Basta filtrarmos todos esses "Hacker Tool", jogando-os para um arquivo a parte, e teremos o Known Bad extraído da NSRL. Quem não tem essa classificação pode ser jogado em outro arquivo e será o Known Good.

Abaixo segue um código perl que fará a extração, conforme comentado:

#!/usr/bin/perl -w
# Extracts known good and known bad hashsets from NSRL
# uso: nsrlext.pl -n -p -g -b [-h]
#
# -n :nsrl files comma separated. Ex: -n c:\nsrl\RDA_225_A\NSRLFile.txt,c:\nsrl\RDA_225_B\NSRLFile.txt
# -p :nsrl prod files comma separated. Ex: -p c:\nsrl\RDA_225_A\NSRLProd.txt,c:\nsrl\RDA_225_B\NSRLProd.txt
# -g :known good txt filename. Ex: -g good.txt
# -b :known bad txt filename. Ex: -b bad.txt
# -h :help
#
#
use Getopt::Std;

my $ver="0.1";

#opcoes
%args = ( );
getopts("hn:p:g:b:", \%args);

#help
if ($args{h}) {
&cabecalho;
print << DETALHE ;
uso: nsrlext.pl -n nsrl_files_comma_separated -p nsrl_prod_files_comma_separated [-g known_good_txt] [-b known_bad_txt] [-h]

-n :nsrl files comma separated. Ex: -n c:\\nsrl\\RDA_225_A\\NSRLFile.txt,c:\\nsrl\\RDA_225_B\\NSRLFile.txt
-p :nsrl prod files comma separated. Ex: -p c:\\nsrl\\RDA_225_A\\NSRLProd.txt,c:\\nsrl\\RDA_225_B\\NSRLProd.txt
-g :known good txt filename. Ex: -g good.txt
-b :known bad txt filename. Ex: -b bad.txt
-h :help

DETALHE
exit;
}

die "Enter the NSRL hashset file list (comma delimited)\n" unless ($args{n});
die "Enter the NSRL product file list (comma delimited)\n" unless ($args{p});

die "Enter known good and/or known bad output filenames\n" unless (($args{g}) || ($args{b}));

my %hack;

&cabecalho;

#Prod files
my @prod = split(/,/, $args{p});

foreach $item (@prod) {
open(PRODUCT, "< $item");

while (< PRODUCT >) {
chomp;
my @line = split(/,/, $_);

#create a hash of hacker tool codes
$hack{$line[0]} = $item if ($line[6] =~ /Hacker Tool/);
}

close(PRODUCT);
}

#hashset files
my @hset = split(/,/, $args{n});

open(BAD, "> $args{b}") if ($args{b});

open(GOOD, "> $args{g}") if ($args{g});

my $i=0;

foreach $item (@hset) {
open(NSRL, "< $item");

while () {

#stdout feedback
print ">" if (($i % 10000) == 0);

my @line = split(/,/, $_);

if ($hack{$line[5]}) {
#is a hacker tool
print BAD $_ if ($args{b});
}
else {
print GOOD $_ if ($args{g});
}

$i++;
}

close(NSRL);
}

print "\nDone !\n";

close(BAD) if ($args{b});
close(GOOD) if ($args{g});

### Sub rotinas ####

sub cabecalho {
print << CABEC;

nsrlext.pl v$ver
Extracts known good and known bad hashsets from NSRL
Tony Rodrigues
dartagnham at gmail dot com
--------------------------------------------------------------------------

CABEC
}

#-----EOF-------


Comentários ?

Até o próximo post !

2 comentários:

Fernando ;) disse...

Olá Tony.
Você conhece outro(s) hashset(s) mantidos no Brasil? Considere os abertos e fechados.

Obrigado.

Tony Rodrigues disse...

Mantidos, propriamente, não. Lá fora, além da NSRL, tem os específicos da Guidance e da AccessData. O OSForensics também tem hashsets (esses são, inclusive, categorizados por malware, etc).

Talvez o trabalho do Dissect.pe, do Rubira, mantenha a criação de um hashset também, mas não tenho certeza. Vou perguntar a ele.

[]s,

Tony