Mostrando postagens com marcador md5deep. Mostrar todas as postagens
Mostrando postagens com marcador md5deep. Mostrar todas as postagens

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 !


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 !

segunda-feira, 30 de julho de 2007

Nosso Amigo Hash - Parte III - Continuação

Hash aplicado na Forense Computacional - Prática

Quarto exemplo: Comprovando a integridade de uma imagem de um HD ou outra mídia

Comprovar a integridade de uma imagem através de hash é uso comum em dois momentos: quando se quer comprovar que a imagem é cópia exata da mídia original ou quando se quer comprovar que a manipulação aplicada sobre a imagem não introduziu qualquer mudança na mesma.

Neste exemplo, vamos trabalhar com algumas ferramentas fornecidas pelo live CD Helix.

Capturando imagem

A primeira situação, descrita acima, ocorre quando se faz a captura da imagem de uma mídia.
O procedimento de captura requer que a imagem obtida seja cópia fiel da mídia original (cópia bit a bit). Dessa forma, a análise da mídia, buscando evidências, garantidamente será feita sem prejuízo de sua integridade, como se fosse na própria mídia original.

É importante ressaltar que uma simples cópia ou uma imagem não-forense deixaria algumas partes da mídia original de fora (não seriam copiadas), e tais partes podem conter informações relevantes. Nesse tipo de imagem, a área não alocada da mídia não é copiada, por exemplo.

Somente com a comprovação da integridade da imagem podemos ter certeza de que o procedimento de captura não inseriu ou removeu artefatos que modificaram as conclusões.

Imagine:

1) Um caso onde um computador foi supostamente usado para cometer um crime. Imediatamente antes do computador ser confiscado, os arquivos (artefatos) que comprovariam o ocorrido são deletados. Se o procedimento de captura de imagem utilizado não for um procedimento forense, os dados contidos nas áreas não alocadas serão perdidos e não será possível comprovar a situação. Também podemos ter o contrário, onde os dados que refutariam a hipótese de participação (ou de culpabilidade) poderiam estar em arquivos recém apagados, prejudicando assim as conclusões.

2) Um caso onde um arquivo foi propositalmente adicionado à imagem para fraudulentamente indicar o envolvimento de alguém inocente em uma situação. Se o procedimento de captura utilizado incluir a verificação de integridade, essa manipulação fraudulenta será detectada.

Se fossemos fazer um paralelo da Forense Computacional com outras investigações não digitais, a captura de uma mídia através de procedimentos de imagem forense bit a bit é equivalente à exigência ao investigador de se usar luvas na cena de um crime para colher as impressões digitais.

dd

Existem várias formas de capturar uma imagem forense, mas sem dúvida a mais usada e difundida é o comando dd. Esse comando realiza a cópia exata (bit a bit) da origem para o destino. É possível, portanto, indicar como origem a path da mídia a ser capturada, e como destino um arquivo. Ao final da cópia, todo o conteúdo da mídia estará refletido nesse arquivo destino, incluindo ali seus espaços não alocados (arquivos deletados).

Ex: Para copiar um pendrive que está localizado em /dev/sda para um arquivo chamado imgblog.dd, usamos o seguinte:
dd if=/dev/sda of=/media/hda1/imagens/imgblog.dd conv=noerr bs=512

O comando acima criará a imagem, capturando-a de forma forense. Entretanto, ele está incompleto porque não faz a verificação de integridade. Essa verificação vai comprovar que a mídia não foi alterada durante o procedimento de cópia, e que o arquivo de saída (destino) é realmente a cópia exata da origem.

Para fazer a verificação de integridade, fazemos uso do utilitário de hash md5deep, que a semelhança do md5sum, computará o hash:

md5deep /dev/sda
dd if=/dev/sda of=/media/hda1/imagens/imgblog.dd conv=noerr bs=512
md5deep /media/hda1/imagens/imgblog.dd

Se o procedimento capturou a imagem corretamente, os valores de saída do primeiro md5deep, sobre a mídia, e do terceiro md5deep, sobre a imagem, serão idênticos e a integridade do procedimento está garantida.

Interface gráfica

Apesar de ser sempre interessante conhecer os pormenores das opções de linhas de comando, há boas interfaces gráficas para realizar a tarefa acima.

O utilitário Adepto, incluído no Helix, pode ser configurado para a captura através de uma tela amigável. O melhor disso é que o Adepto já traz opção para fazer a validação usando hash, sem necessidade de inserir comandos específicos. Basta um clique para acionar a opção e o hash da mídia será computado antes da captura e depois automaticamente comparado com o hash computado sobre a imagem. Uma mensagem de alerta será exibida no log caso os valores não coincidam. O log de utilização é bastante detalhado e traz detalhes da máquina onde o Adepto está sendo executado também.

Comprovando a integridade após a manipulação da imagem

Todo cuidado deve ser tomado durante a análise da imagem, para que a mesma não sofra qualquer tipo de alteração. Write-blockers são úteis, e para quem tem uma imagem a partir do dd, pode-se montá-la usando o loopback device com as opções de read-only.

Ainda assim, a comprovação de que a integridade da imagem continua preservada é feita através do cálculo do hash antes de montar a imagem, e imediatamente após. Os valores calculados precisam ser os mesmos se a imagem continua integra.

md5deep arquivoimagem.dd
mount arquivoimagem.dd /media/imagem -o ro,loop
... Faz as operações e análises ...
umount /media/imagem
md5deep arquivoimagem.dd

Uma advertência: O comando de montar imagem como read-only não previne alterações na imagem em caso de uso de sistemas de arquivo com journaling. O ext3, segundo li recentemente, tem esse recurso e introduz modificações na imagem mesmo quando montado com as opções read-only. Nesse caso, só mesmo um write-blocker.

Na próxima, vamos falar do uso prático de hashes na separação de arquivos conhecidos e desconhecidos.

Até o próximo post !