Recuperando arquivos removidos (ext2/ext3)

 
Removemos um arquivo indesejado. Ou pior. Removemos um diretório importante. O sistema de arquivos é ext2/ext3? O que ainda pode ser feito?

O primeiro passo é cessarmos a execução do maior número de programas possível. Isto porquê, quando removemos um arquivo ele não é removido do disco. Mas pode ser que uma aplicação necessite escrever em disco e sobrescreve o que desejamos recuperar e naturalmente não desejamos isto. 
Como teste, vamos criar um arquivo chamado importante dentro de um diretório chamado teste

$ mkdir teste
$ cd teste
$ echo "Este conteudo e importantissimo" > importante

Agora, removamos o arquivo importante "acidentalmente"

$ rm importante

Agora vamos recuperá-lo. Como root, vamos usar o debugfs na partição onde este diretório foi montado. No meu caso, /dev/hdc1.

# debugfs /dev/hdc1

na interface do debugfs vamos até o diretório em questão:

debugfs: cd /home/davelino/teste
debugfs: ls -d 

A saída aqui foi a seguinte:

 1966199  (12) .    1935262  (4084) ..   <1966200> (4072) importante

O que indica que o arquivo ainda está aí e o número do inode correspondente a ele é 1966200. Para saber a qual bloco este arquivo pertence, podemos usar o imap

debugfs:  imap <1966200>

A saída foi

 debugfs:  Inode 1966200 is part of block group 240
        located at block 7864329, offset 0x0700

Esta informação ainda não é o bastante. Isto porquê este número representa a localização do início do arquivo. Temos que saber ainda onde ele termina, ou seja, determinar a extensão de blocos que este arquivo ocupa. A conta é simples. Esta extensão vai do número obtido multiplicando-se o número do "block group" pelo tamanho do bloco até o número obtido multiplicando-se o número do "block group" mais 1 pelo número de blocos por grupo menos 1. O número de blocos por grupo é obtido através do comando stats:

debugfs: stats

Dentre outras informações, temos a seguinte linha:

 Blocks per group:         32768

Então, vamos às contas:
(240 x 32768) até ((240 +1) x (32768 - 1)) que nos fornece o intervalo 7864320-7896844.
Agora, podemos sair do debugfs:

debugfs: quit

Importante: Para garantir que não vamos sobreescrever o conteúdo removido, é interessante criarmos um diretório fora da partição onde o arquivo foi removido. Num pendrive sería o ideal.

$ cd /mnt/pendrive
$ mkdir  recuperacao_arquivos

Para copiar o conteúdo do intervalo encontrado, podemos usar o comando dls, fornecido pelo  The Sleuth Kit (TSK).

# dls /dev/hdc1 7864320-7896844 > /mnt/pendrive/recuperacao_arquivos/arquivos.data

Vamos examinar este arquivo. Nosso arquivo removido continha a seguinte frase: "Este conteudo e importantissimo". Será que ela se encontra neste arquivo? Vejamos:

# cat arquivos.data | strings | grep "Este conteudo e importantissimo"

A saída foi:

kEste conteudo e importantissimo

Interessante, não? Agora, façamos algumas considerações:

  • O que fizemos aqui?

O procedimento descrito aqui pode ser sumarizado da seguinte maneira:

  1. removemos um arquivo
  2. encontramos onde este arquivo estava escrito em disco
  3. criamos uma imagem do setor ao qual este arquivo pertence
  4. extraimos o arquivo deste setor
  • Por que isto funciona?

Isto funciona porquê quando removemos um arquivo, ele não é apagado definitivamente do disco, por vários motivos, dentre ele, performance. Então, ao removermos um arquivo, a informação contida nele ficará em disco até que um outro arquivo sobrescreva aquela região do disco. Então, teoricamente, ainda temos uma chance de recuperar os arquivos removidos lendo aquele setor em busca da informação desejada.

  • Isto funciona para qualquer tipo de arquivo?

Teoricamente, sim. Praticamente, não. E por uma razão que não tem nada à ver com o que descrevemos aqui. O motivo é que para encontrarmos a informação perdida, precisamos varrer a imagem que criamos com o dls (ou alguma outra imagem do disco), e procurar pelo início e fim do arquivo. No nosso caso foi simples, tivemos que procurar apenas uma linha de texto e nossa estrutura de arquivos não escreveu este arquivo em vários blocos não contínuos, como pode ser o caso quando se usa RAID com espelhamento, por exemplo.

  • Quando funciona?

As técnicas para se recuperar arquivos removidos são conceitualmente estas descritas aqui. A maioria dos arquivos possui um cabeçalho que os identifica. É usando esta informação que a maioria destas ferramentas de recuperação de arquivos utiliza para encontrar os arquivos removidos. É comum vermos artigos sobre recuperação de arquivos que utilizam como exemplos, arquivos texto, jpg, gif, tar, doc, e por ai vai. Mas é incomum vermos artigos que utilizam em seus exemplos .bz2. Já pararam para pensar sobre isto? A razão disto é que estes arquivos possuem tanto um cabeçalho quanto um rodapé como metadados. Então, encontrados os cabeçalhos, em geral basta copiar a informação desde este cabeçalho até a ocorrência do primeiro rodapé e na maioria dos casos, toda a informação é recuperada. No caso do bz2, isto não acontece. Ele não possui um rodapé, o que torna praticamente impossível saber onde este arquivo termina. Para ilustrar, criei dois arquivos bzip2. Usando o comando strings, podemos ver o conteúdo dos arquivos incluindo o tal cabeçalho

BZh91AY&SY
M5=5
d4      $S
U{)o
5tX+
(R7B
^LKB{

o outro arquivo é

BZh91AY&SY
xh<c
>ds9
[TN)-
{;-6`7a%
b.!.
TUaDQ0JF
[}rTr
r8Y\
I%W6H
$ItT
,/nGs
WX74
g&2N

A primeira linha é o cabeçalho do bzip2. Mas note que não há nenhum padrão que possa ser explorado para determinarmos onde estes arquivos terminam. No caso de um arquivo gif, temos um cabeçalho

GIF87a

e um rodape

#;??

No caso dos arquivos png, o cabeçalho é

IHDR

e o rodapé

IEND

e é destas informações que vem o sucesso dos recuperadores de arquivos.

Os bzip2 são arquivos difíceis de recuperar por este motivo. Infelizmente, os gzip também. Então, vale como dica. Nunca tenha uma única cópia de um arquivo importante compactado com o bzip2, gzip ou qualquer outro formato de compactação sem rodapé. O bzip2 permite recuperação fácil para arquivos de tamanho menor que 900k. Isto se deve ao algorítmo utilizado na compressão. Para arquivos maiores a recuperação se torna extremamente difícil. Fizemos vários testes com várias ferramentas disponíveis no mercado e nenhuma delas obteve sucesso na recuperação de arquivos bzip2 maiores do que 900k.

  • Moral da história:

Dê sempre preferência para formatos de arquivo que possuam um cabeçalho e um rodapé para armazenamento de informações importantes. A diferença entre a recuperação e a perda total de seus dados pode estar aí. Uma busca pela RFC de um dado formato é muito útil para se saber se um arquivo possui ou não cabeçalhos e rodapés.

  • Alguns programas para recuperação:

Agora que temos a imagem do setor onde os arquivos se encontram, algumas ferramentas podem ser utilizadas para facilitar a recuperação dos arquivos. Algumas delas são:

O uso destas ferramentas é bastante simples. Em geral, basta selecionar o tipo dos arquivos desejados e deixar que eles façam a busca. Lembrando que eles fazem busca pelos cabeçalhos então, o problema descrito anteriormente se aplica a eles.