sábado, 22 de setembro de 2007

Profiling

Um post recente na lista Pericia Forense, sobre como lidar com um possível cyber crime perfeito, me fez lembrar de um artigo interessante.

Na lista, argumentou-se sobre o que fazer caso um crime usasse como instrumento um computador inicializado a partir de um live CD, e além disso estivesse se protegendo com ferramentas como o TOR.

No fundo, essa argumentação indica uma preocupação que eu já vi em alguns blogs americanos e australianos, de que o pessoal que se aproxima demais da parte técnica da investigação e forense computacional sofre uma tentação enorme de ficar por ali, apenas. O assunto é mesmo instigante e envolvente. Eu costumo dizer que finalmente apareceu algo em TI que é tão interessante e instigante quanto programar. Opinião pessoal, claro, mas afinal é para isso que servem os blogs :D

O "fenômeno" observado pelos nossos colegas do Tio Sam e dos cangurus é que, ligados demais nos aspectos de tecnologia, o pessoal acaba não percebendo que há um mundo todo de artefatos e evidências fora dela, e que precisa ser explorado e, mais ainda, precisa corroborar o que analisamos e descobrimos no mundo digital.

O assunto da lista apontou para isso. O problema foi proposto como um crime beirando a perfeição, e que supostamente seria irrastreável. As respostas focaram sempre no ponto onde poderia ser possível achar alguma pista, talvez o provedor, ou ainda entradas do DHCP ... O que comentei lá, e que vou repetir aqui, é que apesar de existirem várias possibilidades de atrapalhar e obfuscar o trabalho de investigação computacional, com alguns mecanismos, há sempre que se considerar o todo, incluindo análises de motivações, entrevistas com suspeitos, acareações, e todo o resto que compõe já a caixa de instrumentos de um investigador.

Nessa linha, achei um trabalho muito interessante de um pesquisador da área de Forense Computacional. Dr Neil Krawetz, da Hacker Factor, fez uma exposição brilhante em uma das Black Hats, sobre Técnicas de Forense Não Convencional, e o assunto sobre Profiling foi muito bem abordado.

Em termos forenses, uma análise precisa trazer a verdade a luz, indicando fatos. Um investigador precisa cientificamente deduzir a arma do crime, a forma de atuar, baseado em fatos e evidências. Da mesma forma, um investigador de Forense Computacional o faz através de métodos científicos, levantando evidências para corroborar ou negar as hipóteses levantadas. Sempre baseada em fatos e artefatos que configuram-se em evidências. Em uma análise forense computacional, por exemplo, é muito difícil sem margem alguma de erro indicar que Fulano é o criminoso porque sua conta estava com a sessão aberta (logada) na máquina que foi usada para cometer um crime. É comum afirmarmos apenas que a máquina X foi usada para cometer o crime, que não foram encontrados indícios de códigos maliciosos na máquina que poderiam realizar as ações criminosas de forma automática e sem conhecimento do usuário corrente, em sessão, e que da conta em sessão partiram as ações criminosas. Esses são os fatos. Em resumo, a análise Forense Computacional deve ser direta.

Ainda assim, é possível usar técnicas não tão diretas e que podem contribuir para trazer a verdade a luz. São técnicas que, apesar de não serem determinísticas, podem direcionar uma investigação e ajudar a limitar o escopo, acelerando a busca pelo resultado. Essas técnica são chamadas de Profiling, e são comentadas na palestra. Krawetz, inclusive, disponibiliza uma de suas ferramentas diretamente na internet. Essa ferramenta realiza algumas análises estatísticas no estilo e nas palavras de um texto e identifica, com margem razoável de acertos, o sexo do autor do texto. Há análises semelhantes para deduzir se o texto tem mais de um autor, se foi adulterado, se foi copiado de outro local, etc.

Fiquei me perguntando se existe alguma pesquisa sobre esse assunto para textos em português. A técnica é parecida, mas obviamente as estruturas da linguagem pesam nos resultados.

Alguém se habilita ? Seria interessante algo assim para nossas polícias.

Até o próximo post !

domingo, 9 de setembro de 2007

Nosso Amigo Hash - Parte VI - Complemento

Hash Aplicado na Forense Computacional - Prática

Usando Banco de Dados e hash parcial

Este é um complemento do artigo anterior, onde estudamos o uso do utilitário ssdeep, que calcula hashes parciais dos arquivos, para fazer a classificação dos arquivos entre conhecidos e desconhecidos, ou ainda para localizar na imagem forense possíveis arquivos maliciosos ou criminosos, mas que receberam algum tipo de alteração para serem descaracterizados.

A técnica, inicialmente, seria substituir o uso da base NSRL (que só contém hashes MD5 e SHA-1) por uma criada por nós, onde o hash dos arquivos seriam computados pelo ssdeep. Essa base tem a tendência de crcescer cada vez mais (e quanto maior melhor, certo ?), porém o utilitário teria problemas de performance e de memória para realizar a operação. Esses problemas já são conhecidos nossos e falamos deles em um artigo passado (Parte V).

A idéia agora é aplicar o mesmo princípio, mas com algumas dificuldades a mais, porque enquanto a comparação com hashes MD5 ou SHA-1 é imediata (se são ou não iguais), a comparação dos hashes parciais precisa de um cálculo entre ambos, indicando o score de proximidade entre os arquivos. Por conta disso, estudei os fontes do ssdeep e converti as partes correlacionadas à nossa necessidade do C para o Transact SQL.

Vamos ao procedimento.

1) Montando uma base de hashes ssdeep:

A base pode ser obtida executando o utilitário ssdeep sobre os arquivos que quisermos catalogar. O comando é:
C:\catalogar>ssdeep -l * > base.txt

Esse comando deve ser usado na primeira vez que estiver carregando a base, e em todas as vezes que for necessário adicionar hashes a base.

2) Importando a base de hashes parciais:

O procedimento de importação é o seguinte (Antes de iniciar, remova a tabela Aux, se existir):

1) Clique com o botão direito sobre Tables e em seguida, clique na opção Import Tables.
2) Indique que o Data Source é um arquivo texto, e indique o arquivo base.txt
3) Deixe as opções default do File Format, mas marque First Row Has Column Names, pois a prmeira linha do arquivo base.txt é um cabeçalho.
4) Clique em Next, e marque Comma como delimitador.
5) Clique em Next e em Next novamente. Troque o nome da tabela destino para Aux.
6) Clique em Next e finalize o processo, importando os dados.

A tabela Aux será criada com os registros importados. Logo em seguida, faça o seguinte:

a) Se essa for a primeira importação da base, execute as seguintes queries no Query Analyser:

select
block=left(ssdeep,charindex(':',ssdeep)-1),
outro=substring(ssdeep, charindex(':',ssdeep)+1, 255),
nome=[1.0--blocksize:hash:hash]
into
#x
from
aux

select
block,
hash1=left(outro,charindex(':',outro)-1),
hash2=substring(outro, charindex(':',outro)+1, 255),
nome
into
sshash
from
#x

Após ser executado, o código acima cria a tabela sshash com a primeira importação dos hashes parciais.

b) Se essa NÃO for a primeira importação da base, execute as seguintes queries no Query Analyser:

select
block=left(ssdeep,charindex(':',ssdeep)-1),
outro=substring(ssdeep, charindex(':',ssdeep)+1, 255),
nome=[1.0--blocksize:hash:hash]
into
#x
from
aux


Insert
sshash
select
block,
hash1=left(outro,charindex(':',outro)-1),
hash2=substring(outro, charindex(':',outro)+1, 255),
nome
from
#x

Após ser executado, o código acima adiciona à tabela sshash os hashes parciais recém importados.

3) Calculando os hashes ssdeep de uma imagem:

Após a imagem montada, deve-se ir para o diretório raiz da mesma e executar o seguinte comando:
/media/mnt>ssdeep -r * > /reports/sshashes.txt

Esse comando calculará os hashes de todos os arquivos em todos os diretórios da imagem.

4) Importando o arquivo de hashes

Esse processo é idêntico ao procedimento 2 em relação a Importação do arquivo para a tabela Aux.

As queries a serem aplicadas logo após são:

a) Caso seja a primeira vez que esse processo estiver sendo usado:

select
block=left(ssdeep,charindex(':',ssdeep)-1),
outro=substring(ssdeep, charindex(':',ssdeep)+1, 255),
nome=[1.0--blocksize:hash:hash]
into
#x
from
aux


select
[case] = 'Codigo-do-caso',
block,
hash1=left(outro,charindex(':',outro)-1),
hash2=substring(outro, charindex(':',outro)+1, 255),
nome
into
sshashComp
from
#x


b) Se essa NÃO for o primeiro caso a ser verificado, execute as seguintes queries no Query Analyser:

select
block=left(ssdeep,charindex(':',ssdeep)-1),
outro=substring(ssdeep, charindex(':',ssdeep)+1, 255),
nome=[1.0--blocksize:hash:hash]
into
#x
from
aux

Insert
sshashComp

select
[Case] = 'Codigo-do-caso'
block,
hash1=left(outro,charindex(':',outro)-1),
hash2=substring(outro, charindex(':',outro)+1, 255),
nome
from
#x

5) Comparando os arquivos da imagem:

Execute no Query Analyser a rotina sscompara. O primeiro parâmetro é o código do caso e o segundo é o score mínimo que desejamos acusar como arquivos próximos.
Ex:
exec sscompara '2007-001', 80

O comando acima vai separar os arquivos do caso 2007-001 que tenham no mínimo 80 de score de proximidade com os arquivos cadastrados, indicando qual é o arquivo na imagem e qual é o arquivo cadastrado.

Ilustrando ...

Imagine que você trabalhe para algum órgão de investigação contra a pedofilia e tenha um diretório cheio de imagens e vídeos com esse conteúdo, capturados e catalogados. Seguindo os passos acima, você poderá criar e manter uma base de hashes parciais, e ao analisar uma imagem forense de um hard disk suspeito, verificar se há algum arquivo na imagem que se assemelhe aos existentes em sua base. Note que se o suspeito usou algum tipo de descaracterização dos vídeos e imagens (troca de bits, crop, etc), ainda assim o método descrito irá indicar a semelhança.

Sugestões de melhoria

- Criar índices nas tabelas
- Criar stored procedures para os comandos após a carga, listados acima.
- Adaptar a rotina sscompara para dar como saída os arquivos da imagem que não tem proximidade nenhuma com a base. Essa alteração é bem simples e vai permitir anular a técnica de Anti-Forense comentada no artigo Parte VI.

Um estudo interessante seria apurar a média do score obtido entre uma imagem original e imagens alteradas a partir dessa, para situações onde apenas um bit é modificado, uso de crops diversos, modificações na resolução, tamanho, ou até mesmo inserção de informações por esteganografia. Alguém se habilita ?

Até o próximo post !

Fontes dos SQLs e Stored Procedures:

CREATE Procedure dbo.eliminate_sequences @seq varchar(255) OUTPUT
as

Declare @ret varchar(255),
@i int,
@j int,
@len int

Set @ret = substring(@seq,1,3)

IF (@ret ='')
return

Set @len = Len(@seq)

Set @i = 4
Set @j = 4

While (@i <= @len) Begin
IF (substring(@seq,@i,1) <> substring(@seq,@i-1,1)) Or
(substring(@seq,@i,1) <> substring(@seq,@i-2,1)) Or
(substring(@seq,@i,1) <> substring(@seq,@i-3,1)) Begin
Set @ret = @ret + substring(@seq, @i,1)

Set @j = @j + 1
End


Set @i = @i + 1
End

Set @seq = @ret

Return

GO

----------------------------------------------------------------------------
Create Procedure dbo.has_common_substring @s1 varchar(255), @s2 varchar(255)

as

If (Len(@s1) <>
Return 0

If (Len(@s2) <>
Return 0

Declare
@i int

Set @i = 1

While (@i <= (Len(@s1)-6)) Begin
If (charindex(substring(@s1,@i,7), @s2) > 0)
Return 1

Set @i = @i + 1
End

Return 0
go


-------------------------------------------------------------------------------
CREATE PROCEDURE dbo.edit_distn @from varchar(255), @from_len int,

@to varchar(255), @to_len int
as

Declare
@row int,
@col int,
@indice int,
@radix int,
@low int,
@swp_int int,
@swp_char varchar(255),
@menor int,
@valor int,
@prim int,
@seg int,
@ter int

Declare @buf table (indice int, valor int)

/* Handle trivial cases when one string is empty */
If ((@from = '') Or (@from_len = 0)) Begin

If ((@to = '') Or (@to_len = 0))
Return 0
Else
Return @to_len
End
Else
If ((@to = '') Or (@to_len = 0))
Return @from_len

Set @radix = 2 * @from_len + 3

If ((@from_len > @to_len) And (@from_len > 2000)) Begin
Set @swp_int = @to_len
Set @to_len = @from_len
Set @from_len = @swp_int

Set @swp_char = @to
Set @to = @from
Set @from = @swp_char
End


Set @indice = 0
If (substring(@from,1,1) = substring(@to,1,1))

Set @menor = 0
Else
Set @menor = 2

Insert @buf values (@indice, @menor)

Set @indice = @indice + 1
Set @low = @menor


Set @col = 1
While (@col < @from_len) Begin
If (substring(@from,@col+1,1) = substring(@to,1,1))

Set @menor = @col
Else
Set @menor = @col + 3

If (@menor > (@col+2))
Set @menor = @col+2

Select @valor = valor from @buf where indice = (@indice-1)

If (@menor > (@valor+1))
Set @menor = @valor + 1

Insert @buf values (@indice, @menor)

If (@menor < @low)
Set @low = @menor

Set @indice = @indice + 1
Set @col = @col + 1
End

/* Now handle the rest of the matrix */

Set @row = 1
While (@row < @to_len) Begin

Set @col = 0
While (@col < @from_len) Begin

If (@row = 0)
Set @prim = @col
Else
If (@col = 0)
Set @prim = @row
Else
Select @prim = valor from @buf where indice = ((@indice + @from_len + 2) % @radix)

If (substring(@from,@col+1,1) != substring(@to, @row+1,1))
Set @prim = @prim+3

If (@row = 0)
Set @seg = @col+1
Else
Select @seg = valor from @buf where indice = ((@indice + @from_len + 3) % @radix)

Set @seg = @seg+1

If (@col = 0)
Set @ter = @row+1
Else
Select @ter = valor from @buf where indice = ((@indice + @radix - 1) % @radix)

Set @ter = @ter+1
Set @menor = @prim


If (@seg < @menor)
Set @menor = @seg

If (@ter < @menor)
Set @menor = @ter

Insert @buf values (@indice, @menor)

If ((substring(@from,@col+1,1) = substring(@to,@row,1)) And
(@col > 0) And
(substring(@from, @col, 1) = substring(@to, @row+1,1))) Begin
If ((@row-1) = 0)
Set @prim = @col-1
Else
If ((@col-1) = 0)
Set @prim = @row-1
Else
Select @prim = valor from @buf where indice = ((@indice + 1) % @radix)

Set @prim = @prim+5

If (@menor > @prim)
Set @menor = @prim

Insert @buf values (@indice, @menor)
End


Select @valor = valor from @buf where indice = @indice

If ((@valor < @low) Or (@col = 0))
Set @low = @valor

Set @indice = (@indice+1) % @radix
Set @col = @col + 1

End

If (@low > 100)
Break
Set @row = @row+1
End

Select @row = valor from @buf where indice = ((@indice+@radix-1) % @radix)

Return @row

Go
---------------------------------------------------------------------------------
CREATE PROCEDURE dbo.score_strings @s1 varchar(255), @s2 varchar(255), @bloco int

as

Declare
@score int,
@len1 int,
@len2 int,
@menor int,
@ret int

Set @len1 = len(@s1)
Set @len2 = len(@s2)

if (@len1 > 64) Or (@len2 > 64)
Return 0

exec @ret = has_common_substring @s1, @s2

If (@ret = 0)
Return 0

exec @score = edit_distn @s1, @len1, @s2, @len2

Set @score = (@score * 64)/(@len1+@len2)

Set @score = (100 * @score) / 64

If (@score >= 100)
return 0

Set @score = 100 - @score
Set @menor = @len1

If (@len2 < @len1)
Set @menor = @len2

if (@score > (@bloco/3 * @menor))
Set @score = (@bloco/3 * @menor)

Return @score
go


----------------------------------------------------------------
CREATE PROCEDURE dbo.spamsum @bloco1 int, @hash11 varchar(255), @hash12 varchar(255), @bloco2 int, @hash21 varchar(255), @hash22 varchar(255)
as

Declare @score int,
@score1 int,
@score2 int

Set @score = 0

IF ((@bloco1 <> @bloco2) AND
(@bloco1 <> (@bloco2*2)) AND
(@bloco2 <> (@bloco1*2)))
return 0

exec eliminate_sequences @hash11 OUTPUT
exec eliminate_sequences @hash12 OUTPUT
exec eliminate_sequences @hash21 OUTPUT
exec eliminate_sequences @hash22 OUTPUT

IF (@hash12 = '') OR (@hash22 = '')
Return 0

If (@bloco1 = @bloco2) BEGIN
exec @score1 = score_strings @hash11, @hash21, @bloco1
exec @score2 = score_strings @hash12, @hash22, @bloco2

Set @score = @score1

IF (@score2 > @score)
Set @score = @score2

END
ELSE
IF (@bloco1 = @bloco2*2)
exec @score = score_strings @hash11, @hash22, @bloco1

ELSE
exec @score = score_strings @hash12, @hash21, @bloco2

return @score
go


------------------------------------------------------------------------------------
-------------------------------------------------------------------
Create Procedure dbo.sscompara @caso varchar(255), @minscore int
as
-- Separa quem tem algum match, obedecendo o score mínimo

Declare @tabCaso Cursor,
@tabBase Cursor,
@score int,
@lbloco1 int,
@lhash11 varchar(255),
@lhash12 varchar(255),
@filename varchar(255),
@lbloco2 int,
@lhash21 varchar(255),
@lhash22 varchar(255),
@nome varchar(255)

Declare @saida table (score int, arq1 varchar(255), base varchar(255))

Set @tabBase = Cursor Fast_Forward
For
Select block, hash1, hash2, [nome] from sshash

Set @tabCaso = Cursor Scroll Read_only
For
Select block, hash1, hash2, nome from sshashComp where [case] = @caso

Open @tabBase
Open @tabCaso


Fetch Next from @tabBaseinto @lbloco1, @lhash11, @lhash12, @filename
While (@@Fetch_Status = 0) Begin


Fetch First from @tabCaso
into @lbloco2, @lhash21, @lhash22, @nome
While (@@Fetch_Status = 0) Begin
exec @score = spamsum @lbloco1, @lhash11, @lhash12, @lbloco2, @lhash21,

@lhash22

if (@score >= @minscore)
Insert @saida values (@score, @nome, @filename)

Fetch Next from @tabCaso
into @lbloco2, @lhash21, @lhash22, @nome
End

Fetch Next from @tabBase
into @lbloco1, @lhash11, @lhash12, @filename

End

Close @tabBase
Close @tabCaso

Deallocate @tabBase
Deallocate @tabCaso

Select * from @saida

go

sábado, 1 de setembro de 2007

Nosso Amigo Hash - Parte VI

Hash Aplicado na Forense Computacional - Prática

Contra-ataque contra técnicas de Anti-Forense


Estamos chegando ao final da nossa série sobre o uso de hash nas investigações computacionais. Mas vamos fechar a série com chave de ouro. A idéia desse último artigo é falar de como podemos contra-atacar uma técnica de Anti-Forense de descaracterização bastante discutida em alguns seminários da Black Hat.


Classificando os arquivos - Anti-Forense.


Primeiro, vamos a uma definição. O que é exatamente Anti-Forense ?


Anti-Forense são técnicas que tem por finalidade reduzir a quantidade ou a qualidade das evidências. Na prática, para cada técnica conhecida para análises e investigações, pode haver uma técnica contrária, montada para quebrar a análise em algum ponto.


Vou exemplificar isso fora da Forense Computacional. Um indivíduo que, logo após cometer um crime, limpa todos os materiais presentes na cena para retirar suas digitais, está usando uma técnica de Anti-Forense, justamente porque isso vai reduzir ou eliminar a existência de digitais, e isso é uma das técnicas usadas na análise da cena do crime. Usar luvas para manipular a arma também seria outro bom exemplo.


Saindo do CSI e voltando a nossa realidade de Investigadores Computacionais (será que algum dia lançam uma série sobre a gente ? :D ), há várias técnicas conhecidas hoje com o objetivo de eliminar artefatos ou criar condições artificiais que atrapalhem as técnicas de análise mais conhecidas.

Uma das técnicas mais conhecidas é fazer a Linha de Tempo (Timeline) dos arquivos na imagem e a técnica Anti-Forense criada contra a Linha de Tempo é fazer uso de softwares que alteram ou destroem as informações conhecidas como MAC times. Essas informações são a base para a montagem da Linha de Tempo dos arquivos.


Falamos nos posts passados sobre como classificar os arquivos entre conhecidos e desconhecidos. Essa técnica, baseada em comparar o hash dos arquivos da imagem contra uma base de hashes, é muito útil porque nos permite reduzir sensivelmente o número de arquivos a analisar, focando nos arquivos desconhecidos. Na maioria das vezes, a redução ocorre porque um percentual grande dos arquivos de um HD é composto por arquivos executáveis e arquivos de suporte a aplicações e/ou ao sistema operacional.


Pois bem. Existe uma técnica de Anti-Forense que pega todos os arquivos executáveis, DLLs, etc e altera uma pequena porção deles, em geral inócua para a execução. Ou seja, o executável continua funcionando normalmente. No entanto, mesmo com a mudança de um mero byte, o hash do arquivo muda completamente.

Um exemplo: Os arquivos executáveis de Windows têm em seu header algumas palavras em inglês, indicando que o executável é para ser rodado apenas em Windows ("This program cannot be run in DOS mode"). É possível construir um utilitário para alterar especificamente o byte onde se lê "in DOS mode" para "on DOS mode". Não muda nada para o programa, mas o hash fica completamente diferente.

O resultado disso, se aplicado em todos os executáveis, é que a operação de classificação por hashes vai gerar um número de arquivos desconhecidos muito grande, aumentando o tempo necessário para a análise; em alguns casos, tornando-a inviável por questões de prazo.


Vamos a um pouco de prática:

Calculamos o hash do arquivo md5deep.exe

C:\Forensics\SoftwareWin\teste>md5deep md5deep.exe

7b17a3c9c31de090e59e275795b68df3 C:\Forensics\SoftwareWin\teste\md5deep.exe

Agora calculamos o hash de uma cópia do arquivo md5deep.exe com uma alteração de apenas um byte:

C:\Forensics\SoftwareWin\teste>md5deep md5deep2.exe

17dd22393903da269e54bb5b086dc32f C:\Forensics\SoftwareWin\teste\md5deep2.exe

Repare como o resultado (hash) é completamente diferente.


Uma Nova Esperança ...


Há pouco tempo um pesquisador da área de Resposta a Incidentes - Jesse Kornblum, o mesmo criador do md5Deep - lançou um utilitário que faz um cálculo de hash levando em consideração apenas partes do arquivo. Além de calcular o hash usando essa nova técnica, esse utilitário, conhecido como ssdeep, permite comparar o hash calculado contra uma base de hashes, fornecendo um score entre 0 e 100 que indica o grau de proximidade dos arquivos. Quanto maior o score, mais parecidos serão os arquivos. Score 100 significa que os arquivos são completamente iguais.


Vamos a alguns exemplos:

Primeiro, vamos calcular o hash do arquivo md5deep.exe:


C:\Forensics\SoftwareWin\teste>ssdeep md5deep.exe

ssdeep,1.0--blocksize:hash:hash,filename
768:lHNpDqU/EDXgEzayDYldcJummjytKBNjTe6wV8:FWuEz5kGOytKBNne6w6,"C:\Forensics\SoftwareWin\teste\md5deep.exe"


Agora, vamos verificar o hash do arquivo md5deep2.exe, que conforme já comentamos, é cópia do md5deep.exe com um byte modificado, apenas:


C:\Forensics\SoftwareWin\teste>ssdeep md5deep2.exe

ssdeep,1.0--blocksize:hash:hash,filename
768:bHNpDqU/EDXgEzayDYldcJummjytKBNjTe6wV8:LWuEz5kGOytKBNne6w6,"C:\Forensics\SoftwareWin\teste\md5deep2.exe"



Veja que o resultado é expresso em dois blocos de hash, e nos dois blocos, o valor de saída para md5deep.exe e md5deep2.exe são muito semelhantes.


Agora vamos criar uma forma do próprio utilitário indicar o grau de proximidade entre os dois arquivos.
Primeiro, vamos calcular o hash do md5deep.exe e vamos gravar o resultado no arquivo hash.txt:

C:\Forensics\SoftwareWin\teste>ssdeep md5deep.exe > hash.txt

Agora, vamos calcular o hash do arquivo md5deep2.exe, comparando-o com o hash calculado anteriormente, armazenado no arquivo hash.txt:


C:\Forensics\SoftwareWin\teste>ssdeep -m hash.txt md5deep2.exe

C:\Forensics\SoftwareWin\teste\md5deep2.exe matches C:\Forensics\SoftwareWin\teste\md5deep.exe (99)



O resultado indica que os arquivos são 99% similares, o que comprova a situação, já que modificamos apenas um byte.

Vamos fazer o mesmo teste, agora com o arquivo md5deep.exe (o próprio):

C:\Forensics\SoftwareWin\teste>ssdeep -m hash.txt md5deep.exe


C:\Forensics\SoftwareWin\teste\md5deep.exe matches C:\Forensics\SoftwareWin\teste\md5deep.exe (100)



O resultado indica que ambos são iguais (de fato).



Aplicabilidade do ssdeep



Esse utilitário pode ser aplicado na classificação de arquivos da imagem quando há suspeita de que técnicas anti-forenses foram utilizadas para descaracterizar os arquivos. O único problema para isso hoje é que não há (bem, pelo menos ainda não conheço nenhuma) bases distribuídas de hashes para os arquivos conhecidos, como a base NSRL, que contém hashes MD5, SHA-1.
Se não houver uma referência para os arquivos, precisaremos criar nossas próprias bases. Isso não é tão difícil assim, mas é trabalhoso. Basta usar como base o seu próprio sistema e digitar no raiz:
ssdeep -r -l * > basehash.txt

A opção -r vai caminhar recursivamente pelos diretórios e o -l vai eliminar a path do nome dos arquivos.

Logicamente, convém retirar linhas relativas aos arquivos que não pertecem ao SO ou às aplicações.



Essa base pode ser calculada para vários SOs e softwares e os arquivos concatenados. Porém, há um problema com essa abordagem. Esse utilitário tem a mesma estrutura de comparação que o md5deep (não é a toa, já que foram feitos pelo mesmo desenvolvedor). Por conta disso, o arquivo que funciona como base será carregado para a memória primeiro antes da comparação efetivamente começar. Se você tem acompanhado os artigos sobre hash aqui no blog, vai lembrar do que estamos falando. A memória estoura antes da brincadeira começar ...

Há pelo menos mais duas aplicações interessantes para o ssdeep. É sabido que os códigos maliciosos existentes na internet tem seus fontes disponíveis em vários locais. Isso faz com que muitos lammers editem pequenas partes de códigos de worms e relancem o tal, como uma variação. Em muitas vezes, por ser lançado em pequena escala (em âmbito local), restrito a apenas um país ou estado, as assinaturas dos anti-virus demoram para chegar, e é bem possível que o novo código malicioso, recém modificado, não seja detectado pelo anti-virus. Para resolver isso, podemos criar uma base com os hashes calculados pelo ssdeep sobre os virus, worms e outros códigos maliciosos existentes. Com essa base, poderíamos classificar/detectar os arquivos com códigos maliciosos em uma imagem, mesmo que eles tenham sofrido alterações do virus/worm original.

Outra aplicação interessante, principalmente para nossos colegas da Polícia Federal, seria manter uma base de hashes para cada fotografia apreendida na internet com algo sobre pedofilia. É sabido que localização desse tipo de fotografia através de algoritmos de hash convencionais não é adequada, pois facilmente o usuário pode alterar um simples byte e tornar o hash da figura totalmente diferente. É provável que já existam utilitários que façam essas pequenas alterações. Se a figura for usada em esteganografia, ela continuará praticamente igual, e seu hash será completamente diferente. Por outro lado, se montarmos uma base com os hashes calculados a partir do ssdeep, as figuras alteradas ainda serão detectadas pelo utilitário.

Em ambas as sugestões, teremos o problema de performance e estouro de memória quando a base começar a ficar grande.

A solução para isso virá no próximo capítulo dessa série Nosso Amigo Hash. Será um bônus, já que eu tinha me programado a fechar a série com esse artigo aqui.

Até o próximo post !