quinta-feira, 23 de agosto de 2007

Nosso Amigo Hash - Parte V

Hash Aplicado na Forense Computacional - Prática

Classificação de arquivos usando banco de dados

Enfim, cheguei ao tão falado post. Minha cara de pau já estava além da conta, mas realmente foi impossível escrever antes ...

Um ponto importante: Esse artigo é uma adaptação do artigo escrito pelo Mark McKinnon em seu blog.

Apenas relembrando o final do último artigo sobre hash, nosso objetivo maior é classificar cada arquivo em nossa imagem a ser analisada, de forma a indicar se o arquivo é conhecido ou não. Com essa classificação, conseguimos reduzir a ação de análise forense e focar em arquivos que podem realmente ter relevância para o processo. Quem nos apoiará na classificação é a base de hashes (conhecida também por hashset) do NSRL.

Pois bem, o problema é que as ferramentas disponíveis não são eficientes com bases grandes como a do NSRL. Tanto pelo fato da memória lotar com a base (que é realmente gigantesca e é carregada para a memória antes da primeira comparação/classificação) quanto pelo próprio algoritmo de busca na base não ser o melhor para esse fim.


Vamos melhorar isso acrescentando mais uma ferramenta importante à nossa equação: Um banco de dados. A estratégia é dividir o problema em três fases:

1) Vamos criar uma base de dados e popular ela com os hashes da NSRL

2) Vamos passar o MD5Deep na imagem (ela precisará estar montada) e carregar os hashes obtidos em uma outra tabela da base.

3) A classificação dos arquivos poderá ser facilmente obtida com queries SQL a partir daí.


Note que:

- Há um notável ganho com essa solução, principalmente se levarmos em conta que o tempo levado para obter o resultado por uma segunda vez (uma repetição da classificação, por exemplo) é muito pequeno, compreendendo apenas a fase 3.

- A base de hashes da NSRL não é normalizada e repete arquivos com frequência, porque ela registra os arquivos conforme a aplicação que os arquivos pertencem, e é muito comum um arquivo pertencer a mais de uma aplicação ou versão.

- Na verdade, não nos importa saber de qual aplicação, versão ou SO específico é o arquivo em questão. Queremos apenas dizer se o arquivo é conhecido ou não. Isso vai nos facilitar bastante o tratamento, e a base NSRL ficará bastante reduzida.

- Vamos nos ater ao MD5, mas o SHA-1 poderá ser usado, a gosto ;)



Fase 1



Vamos criar a base de dados e carregar a base NSRL. Estou considerando que os quatro discos com a base NSRL já se encontram descompactados e disponíveis. Usarei como servidor de banco de dados o SQL Server, mas o processo pode ser facilmente adaptado para outros SGBDs.


1) Usando a ferramenta Enterprise Manager (ou o Query Analyser, para quem prefere usar DDLs SQL diretamente), crie uma base de dados. Escolha um nome para a base e use as opções default.

2) Abra a base, clique em tables com o botão direito, depois All Tasks e em seguida em Import Table.

3) Na primeira tela do Wizard, escolha para Data Source o text file. Informe, na caixa de texto Filename, o nome do arquivo NSRLFiles.txt. Clique em Next.

4) Deixe as opções default dessa tela, e marque também a check box First Row has Column Name. Clique em Next.

5) Nessa tela, novamente ficaremos com as opções default (delimiter = comma). Clique Next.

6) Na tela Destination, mantenha as opções default. Clique Next.

7) Na tela Select Source Table and Views, permaneça com o nome sugerido para a nova tabela (nsrlfile, o mesmo nome do arquivo a ser carregado). Clique Next.

8) Essa é a ultima tela. Clique Next.


O arquivo será carregado e gerará a tabela nsrlfile. Esse nome já aparecerá na relação de tabelas do banco.


Esse processo deverá ser repetido para o arquivo nsrlfile.txt de cada um dos quatro diretórios (ou discos) da base NSRL. A cada carga, o arquivo será importado e seus dados serão adicionados a tabela nsrlfile criada.


No final do processo, essa tabela estará com milhares de registros, muitos deles duplicados. Tenha em mente que é necessário ter bastante espaço em disco para essa carga inicial. Ela também consome bastante tempo.

Como nosso interesse é apenas indicar se o arquivo é conhecido ou não, podemos retirar todas as duplicações, e ainda por cima podemos retirar também alguns campos da tabela.

Entre no utilitário Query Analyser, conecte-se ao banco recem criado e digite a seguinte query:
Select distinct [md5], [sha-1], FileName into NSRL from nsrlfile

A query acima vai criar uma tabela nova somente com os campos de hash md5 e sha-1, mais o nome do arquivo. Cada registro só aparecerá uma única vez.

Para melhorar ainda mais o acesso no futuro, é interessante criar índices para os campos md5 e SHA-1. Esses índices podem ser criados diretamente com DDL SQL ou na interface do Entreprise Manager. Se optar por essa forma, você deve:
- Clicar com o botão direito sobre o nome da tabela NSRL e clicar no menu Design Table.
- Em seguida, clique no segundo botão da esquerda para direita (Table and Index Properties).
- Ao abrir a janela de propriedades, clique na aba Indexes/Keys e no botão NEW para criar um novo índice.
- Indique o campo MD5 na lista Column Name. Aceite o nome sugerido para o indice.
- Clique novamente no botão NEW, indique o campo SHA-1 na Column Name. O nome sugerido para o índice deve ser mantido.
- Clique em Close e logo em seguida no primeiro botão da esquerda para direita, para salvar as alterações.

Lembre-se que essa operação pode demorar bastante, já que a tabela é bem grande. Aqui, nós estamos criando dois índices distintos para facilitar as consultas posteriores.

Ao final dessa fase, temos a base NSRL completamente carregada, sem duplicações, e indexada na tabela NSRL. Vamos para a próxima fase, mas antes exclua a tabela nsrlfile.

Fase 2

O objetivo dessa fase é obter um conjunto de hashes da nossa imagem, e em seguida carregá-los para nosso banco. Na fase 3 faremos a classificação propriamente dita.

O conjunto de hashes é obtido através do uso do MD5Deep (ou o SHA1Deep). Vamos manter nosso foco para o MD5, mas os passos para o SHA-1 são análogos.

- Inicialmente, monte a imagem sendo analisada. Provavelmente, você estará com um Live CD de análise de forense computacional, como o Helix ou o FCCU.

- Vá para a raiz da imagem montada e use o comando MD5Deep -r * > resultado.txt

Esse comando faz com que todos os arquivos tenham seu hash calculado, desde a raiz, e de forma recursiva. Toda a saída do comando é jogada para o arquivo resultado.txt. Lembre-se que essa operação pode ser demorada, de acordo com o tamanho da imagem e do número de arquivos nela.

O próximo passo é carregar esse arquivo para uma tabela na nossa base. Não vou entrar em detalhes novamente, pois o processo é o mesmo de quando carregamos os arquivos nsrlfile.txt. Apenas leve em conta que, nesse caso, nao há nomes de campos na primeira linha e como separador de campo indique dois espaços. Observe que o próprio programa de carga já mostra as primeiras linhas carregadas, com nomes de colunas col001 e col002. Confira se está tudo certinho e indique aux como nome da tabela a ser criada com esse resultado. Novamente, essa operação será longa, dependendo do tamanho do arquivo a ser carregado.

Ao final dessa operação, teremos uma nova tabela chamada aux com duas colunas (Col001 e Col002). Vamos ao Query Analyser rodar um comando SQL que vai criar uma nova tabela a partir dessa, acrescentando um campo para o código do caso. Com esse código, sempre poderemos guardar as informações relativas ao caso e consultar quantas vezes quisermos.

Select [Caso] = '2007-001', [md5] = Col001, Arq = Col002 into Hashes from Aux

Confira se o conteúdo da tabela Hashes está igual ao da tabela Aux. Exclua a tabela Aux (vamos salvar espaço, certo ?) e crie índice para o campo MD5 da tabela Hashes.

Ao final dessa fase, nós temos uma base de dados com duas tabelas: a NSRL, com toda a base de hashes da nsrl, sem duplicações e campos desnecessários, e a tabela hashes, já carregada com os hashes da imagem do nosso primeiro caso. Todas devidamente indexadas.

Vamos para a próxima fase ...

Fase 3

Essa é a hora da verdade ... Vamos executar duas queries. Uma imprimirá os arquivos conhecidos e a outra os não conhecidos. Usando o Query Analyser:

Select CONHECIDOS=Arq from hashes h left outer join nsrl n on h.md5 = n.md5
where
caso = 'codigo do caso'
and
n.md5 is not null

Select DESCONHECIDOS=Arq from hashes h left outer join nsrl n on h.md5 = n.md5
where
caso = 'codigo do caso'
and
n.md5 is null



A saída de cada um pode ser usada em análises mais minuciosas. Ela equivale à saída do comando MD5Deep com as opções comentadas no último post sobre hashes.

Comentários e melhorias

- As duas queries acima podem ser gravadas como stored procedures, passando o código do caso por parâmetro. Ficará mais fácil para re-executar as classificações

- O tamanho da base ficará enorme, mas pouco utilizado. Um comando de Shrink Database é interessante para recuperar o espaço.

- Backup é fundamental. Faça um backup logo após o término de cada fase, para garantir.

- Uma abordagem alternativa é fazer o Shrink Database logo após o término da Fase 1. Faça um backup em seguida, e assim ganhará mais tempo e gastará menos espaço no backup.

- A fase 3 será executada todas as vezes que você quiser reclassificar os arquivos. Melhor do que fazer isso é gravar as duas saídas ...

- Se quiser adicionar os hashes de um novo caso/imagem, a operação é bem simples. Obtenha o arquivo com os hashes (como no caso do resultado.txt). Carregue-o para uma tabela aux, como no processo da fase 2. Logo em seguida, no Query Analyser, execute a seguinte query:

Insert hashes select Caso = 'codigo do novo caso', [md5] = Col001, Arq = Col002 from aux

Esse comando SQL vai inserir a tabela recem carregada para a tabela de hashes definitiva. Exclua a tabela aux, ao final. A partir daqui, execute as queries da fase 3 para classificar os arquivos.

- O processo explicado acima pode ser feito em uma passada só, diretamente na carga. Se você conhece o SQL Server, vá em frente !

- A NSRL libera versões novas 4 vezes por ano. A fase 1 precisará ser refeita todas as vezes, se você quiser se manter atualizado com as versões.

- Uma boa opção é montar uma base própria de hashes contendo figuras, musicas e outros itens. Recomendo colocar esses em uma tabela a parte, carregando-a da mesma forma que os arquivos anteriores. As queries da fase 3 precisarão de uma adaptação, pois a classificação será feita a partir de uma union da tabela NSRL com a tabela criada por você.

- É possível inserir mais um nível de classificação: Quebrar os arquivos conhecidos em bons e maus. Basta criar mais um campo na tabela NSRL com o default de ser bom. Na tabela acima, com seus próprios hashes como base, sempre que um arquivo for reconhecido como mau, o tal campo deve ser setado de acordo.

Finalmente ...

Demorou, mas chegamos ao fim dessa parte do artigo. Vou parar por aqui comentando o seguinte:

1) Você aprendeu que a classificação de arquivos é muito importante, pois com ela diminuímos os arquivos a serem analisados, tornando a investigação viável e mais focada.

2) Você aprendeu também que se modificamos apenas um mero bit em um arquivo, o resultado da computação do hash dele vai ser completamente diferente do original. Veja bem ... Estamos falando de mudar um mísero bit !

De posse das duas informações acima, pense junto comigo o que alguém poderia fazer para piorar a vida de um Investigador Computacional...

Certo, você percebeu ! Se um usuário mal intencionado trocar apenas um bit, ou byte, de todos os arquivos no HD, a classificação desse HD diria que todos os arquivos são desconhecidos. Isso inviabilizaria (ou tornaria muito difícil) a investigação. Essa técnica é conhecida como Anti-Forensics (é uma das técnicas usadas, na verdade), e pode atrapalhar um bocado a nossa investigação.

Mas nem tudo está perdido !

No próximo artigo sobre hash, vamos falar de uma solução bastante nova para esse problema.

Até o próximo post !


Nenhum comentário: