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 !


E o Live Accquisition leva um TKO ...

Se estivéssemos em uma luta de boxe das boas entre a turma do Live X Dead acquisition (captura da imagem de um disco ativo e em uso pelo SO ou não), o artigo que acabei de ler representaria um bom direto de direita, daqueles de levantar a platéia e fazer o juiz abrir a contagem, com o lutador ainda se perguntando se anotaram a placa do caminhão ...

O artigo é uma apresentação do Darren Bilby, da Security Assessment, para a Ruxcon 2006. Sob o título de "Low Down and Dirty: Anti-Forensic Rootkits", o autor explora o que o mundo dos rootkits pode trazer e afetar ferramentas de captura de imagens forenses.

Na sua essência, um rootkit é um código (ou conjunto de) que tem por objetivo alterar o comportamento normal das rotinas, comandos e drivers do sistema operacional, na maioria das vezes para esconder a presença de outros códigos.
Os rootkits mais clássicos são aqueles em Unix que substituiam comandos e, dessa forma, conseguiam fazer passar despercebidos os arquivos e processos usados em ataques e invasões.

Por exemplo, o comando ps, que lista os processos executando na máquina, era substituído por um outro ps, parte do rootkit, que ao ser usado continuava listando realmente todos os processos em execução, MENOS os processos relativos ao ataque.

Rootkits mais complexos chegam a trocar e alterar códigos e device drivers diretamente no kernel do SO, e são cada vez mais difíceis de detectar. Eles se protegem de ferramentas de detecção, inclusive, interceptando chamadas e alterando o resultado, de forma a se manterem indetectáveis.

O artigo explora justamente o conceito de que um rootkit, se devidamente instalado e presente em um sistema, pode ser preparado para ser totalmente indetectável aos mecanismos usados em um software de captura de imagem. Mesmo o famoso DD poderia ser enganado com algumas técnicas, de forma a capturar não toda a mídia, mas apenas aquilo que o rootkit deixar.

O por que do nocaute técnico ? É que em uma live acquisition o rootkit estaria ativo, e portanto, alterando tudo que o DD está capturando. Em um sistema infectado por um desses, o Investigador de Forense Computacional poderia estar literalmente levando gato por lebre ...

Obviamente, na Dead Acquisition isso não acontece. O sistema não carregou o rootkit para memória, a captura ocorre normalmente e uma boa análise da imagem vai indicar a presença dos arquivos alterados que fazem parte do código maledito, como diriam alguns ... ;)

Continuo no débito do artigo do Hash com Database ...

Até o próximo post !

quarta-feira, 15 de agosto de 2007

CSO Meeting

Sei que estou devendo mais um artigo da série sobre hash. Devo, não nego. Pago quando puder; Ou seria Devo, não pago. Nego quando puder ? :)

O fato é que estarei nos próximos dias no CSO Meeting e por conta disso, o artigo vai demorar ainda mais um pouquinho. Apesar disso, a espera vai valer a pena. Digo isso porque o principal problema da técnica que apresentei no artigo de hashes passado, a de classificar os arquivos conhecidos e desconhecidos, é que o software que faz a classificação superlota a memória. Mesmo se executado em ambientes configurados com swap, a performance não será nada boa. Você vai colocar esse tipo de programa para rodar e ir dormir, porque o tal vai demorar mesmo. Provavelmente, você vai acordar e ele ainda estará lá, trabalhando.

Mais um pouco de paciência e estarei com o artigo terminado.

Para aqueles que forem no CSO Meeting, procurem-me por lá ! Vamos bater um bom papo sobre Forense Computacional e tudo o mais.

Até o próximo post !

quinta-feira, 9 de agosto de 2007

Dodging the Bullet

Esse é o título de um artigo muito interessante escrito pelo advogado e também Investigador Computacional Craig Ball.

De forma muito direta e clara, Ball entra nos aspectos do Cross-Examination, aquela famosa prática dos julgamentos americanos que todos já vimos em filmes. É no Cross-Examination que o perito computacional responde perguntas dos advogados de defesa e acusação, e o autor do artigo, bastante experiente nessas atividades, dá várias dicas excelentes.

Vou dizer por que estou falando disso aqui no blog, já que nossas leis são completamente diferentes e nosso sistema de julgamento é completamente diferente deles.

É que, ao ler um artigo tão interessante sobre esse tema, me dei conta de que não temos nada parecido (ou pelo menos nunca li nem fiquei sabendo) por aqui. Não temos nenhum artigo com foco a preparar os peritos, nenhum que fale de como fazer um bom relatório de perícia, ou ainda um texto que explique como transcorre o envolvimento do investigador Computacional com os trâmites legais. Só para exemplificar, há uma verdadeira confusão de conceitos quando se necessita realizar uma perícia litúrgica, seguindo alguns procedimentos com fins a levar o assunto à Justiça.

Vou um pouco mais além no exemplo. Imagine que você acabou de ser chamado para uma investigação em um servidor de uma empresa. O objetivo é levantar todas as evidências que comprovem intencionalidade no fato de um funcionário, às vésperas de sair da empresa, ter apagado vários conteúdos importantes do disco do servidor. A empresa espera, se confirmado a intenção, processar o ex-funcionário.

Você chega perto da máquina, está se preparando para entrar em ação, seu kit ferramentas está a postos para iniciar a captura de uma imagem forense e, de repente, você dá de cara com um mega storage. Respira fundo, vê que não há a menor chance de fazer imagem daquele monstro de Terabytes, e então se pergunta: E agora ? Faço o quê ?

Certamente que há respostas para isso. Se a investigação não fosse litúrgica, seria moleza ... Mas assim ...

Sei que temos contra nós o fato de não termos leis específicas, mas seria muito interessante que os advogados que já militam nessa área pudessem dar uma luz com temas como esses.

Fica aqui o pedido e o desafio de contribuirmos, todos, para a formação dessa nova ciência no nosso Brasil.

Abraços e até o próximo post !

quarta-feira, 1 de agosto de 2007

Nosso Amigo Hash - Parte IV

Hash aplicado na Forense Computacional - Prática

Quinto exemplo: Determinando e Selecionando Arquivos Conhecidos e Desconhecidos

Já comentei em um dos posts passados sobre um grande problema para os investigadores computacionais: O enorme número de arquivos e artefatos para serem analisados.

A técnica mais comum para diminuir a quantidade de arquivos é aplicar filtros que separem a mídia analisada, destacando os arquivos que são conhecidos dos desconhecidos. Dessa forma, esquecemos os conhecidos e mantemos o foco da análise nos desconhecidos, na busca de evidências.

Para ajudar nessa classificação (conhecido e desconhecido), entra em cena nosso amigo hash. A técnica consiste em:
1) Computa-se o hash do arquivo
2) Busca-se na base pelo hash computado. Se achou, o arquivo é classificado como conhecido
3) Se não achou, o arquivo é classificado como desconhecido e vai receber maior atenção durante a análise.

Dando nomes aos bois

Continuaremos usando o CD do Helix nos nossos exemplos.

Para aplicar a técnica, usamos o utilitário MD5Deep. Esse utilitário é muito semelhante ao já apresentado MD5Sum. Ele calcula o hash MD5 do arquivo indicado (ou do diretório), mas tem algumas vantagens sobre o MD5Sum:
  • O MD5Deep tem a opção de calcular hashes para cada arquivo em um diretório indicado, podendo descer na estrutura dos subdiretórios, de forma recursiva.
  • É possível passar ao MD5Deep uma lista de hashes e, através de parâmetros, fazê-lo verificar se o hash computado está ou não na lista passada.

A lista citada possui um formato conhecido e pode ser tanto gerada pelo próprio MD5Deep/MD5Sum ou então obtida fazendo o download das bases conhecidas como Hashsets.

Uma das mais acessíveis é a disponibilizada pela NSRL. Essa base, produzida e mantida pelo NIST, é uma grande lista de arquivos contendo o hash computado em MD5 e SHA-1, devidamente separados por Sistema Operacional, Pacote, versão de Software, etc. Ela é atualizada trimestralmente e está na versão 2.17 enquanto escrevo esse post.

Vamos a prática

Primeiro, vamos baixar e montar as bases da NSRL:

1) Faça o download dos 4 arquivos disponibilizados no site da NSRL, nesse link. Verifique que há quatro downloads para se ter a base completa (disc 1 a disc 4) . Lembre-se que os arquivos são muito grandes e podem levar bastante tempo.

2) Após os downloads, use o MD5Sum ou o MD5Deep para calcular o hash do arquivo baixado com o hash declarado no link signatures.

3) Cada arquivo é uma imagem de CD. Extraia dessa imagem os arquivos compactados que no final terão as bases de hashes.

4) Mantenha as bases em um diretório único, divididas nos respectivos subdiretórios, para facilitar.

Ao final dessa etapa, você deverá ter um diretório com 4 subdiretórios, e em cada um deles os arquivos descompactados e extraídos das imagens .iso baixadas. Vamos supor que temos /NSRLFILES com os subdiretórios A, B, C e D.

Na nossa prática, faremos a classificação dos arquivos do diretório /Arquivos de Programas e todos os seus subdiretórios. Todos os arquivos desconhecidos, isto é, que não estiverem na base NSRL, serão exibidos.

cd /Arquivos de Programas
MD5Deep -r -x /NSRLFILES/A/NSRLFile.txt -x /NSRLFILES/B/NSRLFile.txt -x /NSRLFILES/C/NSRLFile.txt -x /NSRLFILES/D/NSRLFile.txt *

A opção -r junto com o * no final do comando faz com que o MD5Deep calcule o hash de todos os arquivos do diretório /Arquivos de Programas e seus subdiretórios.

A opção -x passa uma base de hashes para o utilitário e indica a ele que liste o arquivo se ele não estiver relacionado na base. Como a base NSRL é dividida em 4, adicionamos todas as 4 através dos parâmetros -x. Todos os arquivos que forem listados a partir desse comando são arquivos desconhecidos que receberão maior foco na investigação.

Variações

Podemos, ao invés de classificar todos os arquivos de um diretório, classificar apenas um arquivo (ARQUIVO.EXE, no nosso exemplo). Nesse caso, o comando seria:

cd /Arquivos de Programas
MD5Deep -x /NSRLFILES/A/NSRLFile.txt -x /NSRLFILES/B/NSRLFile.txt -x /NSRLFILES/C/NSRLFile.txt -x /NSRLFILES/D/NSRLFile.txt ARQUIVO.EXE

Outra variação desse uso é carregar apenas a base específica do NSRL. Se você prestou bastante atenção, percebeu que a NSRL dividiu suas bases (non-English sw, operationg systems, application sw, images & graphics) e assim é possível passar para o utilitário MD5Deep apenas a base que se aplica.

Também é possível usar o MD5Deep para criar sua própria base de hashes, bastando redirecionar a saída do comando para um arquivo:

MD5Deep * > novabase.txt

Problemas

Um ponto muito ruim nessa técnica é que as bases são muito grandes e o utilitário carrega para a memória todas as bases passadas para ele antes de começar as comparações. Dessa forma, a memória rapidamente é exaurida com o comando acima que carrega várias bases. Esse problema ficou ainda pior se usado no Helix 1.8, pois nessa versão não há suporte ao swapon/swapoff, comandos que acionam a memória virtual (swap). Nesse caso, a RAM é usada até sua exaustão e o Helix trava.

Além de tentar carregar apenas uma base específica, uma opção para esse problema seria usar esse comando fora do Helix, em um sistema com a memória virtual devidamente configurada.

Ainda assim, há uma opção melhor através do uso de banco de dados, e estaremos falando nisso nos próximos posts.

Uma ultima observação

Os exemplos tratados aqui fazem referência a classificação entre arquivos conhecidos e desconhecidos. Algumas instituições, ao contrário da NSRL, oferecem bases classificadas entre conhecidos bons e conhecidos maus. Exemplos disso seriam uma base com hashes de códigos maliciosos ou hashes de imagens com conteúdo sobre pedofilia. Entretanto, nesses casos nosso interesse maior na investigação é justamente descobrir na imagem analisada os arquivos que tiverem hash coincidindo na base. O comando seria:

cd /Arquivos de Programas
MD5Deep -m /BASEVIRUS/base.txt *

Todos os arquivos do diretório que estiverem classificados na base serão listados. O investigador, a partir daí, intensifica sobre esse resultado sua análise.

Até o próximo post !