lunes, 8 de abril de 2013

Recuperando información totalmente sobreescrita


Hace un par de días comencé un posgrado en seguridad de la información y se dió una charla muy interesante. El punto de la conversación era la posibilidad de recuperar archivos de una memoria flash que había sido COMPLETAMENTE sobreescrita, esto dio lugar básicamente a dos opiniones:

-NO, no es posible recuperar nada si la memoria fue completamente sobre escrita.
-SI, si es posible.

En particular yo estaba en el primer grupo, aunque alguna vez leí que en los soportes magnéticos esto podría ser cierto por la naturaleza magnética de los mismos. Pero ahora estabamos hablando de memorias de tipo FLASH.

En la mayoría de los casos (por no decir todos, aunque posiblemente sean todos) las memorias flash a.k.a. pendrives, tienen particiones de tipo FAT. Este tipo de sistema de archivos son mundialmente conocidos por su mecanismo de borrado que, mmm digamos, no borra. Suena loco, pero si, técnicamente lo que borramos NO se elimina del dispositivo, sino que solamente se marca como espacio libre disponible nuevamente.

Como prueba plantee el siguiente escenario:

-Cree en mi pendrive una partición de 128Mbytes (por una cuestión de tiempo, no valía la pena hacerla mas grande).
-Formatee la partición con un sistema de archivos tipo FAT.
-Copié a la partición una serie de archivos, archivos de texto, binarios, documentos de office, sin llegar a ocupar la totalidad del dispositivo.
-Luego eliminé todos los archivos y con dd generé un archivo que ocupara la totalidad de la partición (128Mbytes).
-Use las herramientas de sleuthkit forensic analysis para intentar recuperar los archivos eliminados y sobreescritos.

Estado inicial del pendrive

root@moon:/home/juan# fdisk -lu /dev/sdb

Disco /dev/sdb: 4063 MB, 4063232000 bytes
125 cabezas, 62 sectores/pista, 1024 cilindros, 7936000 sectores en total
Unidades = sectores de 1 * 512 = 512 bytes
Tamaño de sector (lógico / físico): 512 bytes / 512 bytes
Tamaño E/S (mínimo/óptimo): 512 bytes / 512 bytes
Identificador del disco: 0x00091593

Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sdb1   *          62     5750499     2875219    b  W95 FAT32
/dev/sdb2         5750500     7935999     1092750   83  Linux
root@moon:/home/juan# 

Inicialmente el pendrive tiene 2 particiones, una FAT32 y una partición linux. Elminé la partición FAT y volví a crearla en 128Mbytes.

root@moon:/home/juan# fdisk -u /dev/sdb

Orden (m para obtener ayuda): d
Número de partición (1-4): 1

Orden (m para obtener ayuda): w
¡Se ha modificado la tabla de particiones!

Llamando a ioctl() para volver a leer la tabla de particiones.
Se están sincronizando l1os discos.

Partición eliminada:

root@moon:/home/juan# fdisk -l /dev/sdb

Disco /dev/sdb: 4063 MB, 4063232000 bytes
125 cabezas, 62 sectores/pista, 1024 cilindros, 7936000 sectores en total
Unidades = sectores de 1 * 512 = 512 bytes
Tamaño de sector (lógico / físico): 512 bytes / 512 bytes
Tamaño E/S (mínimo/óptimo): 512 bytes / 512 bytes
Identificador del disco: 0x00091593

Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sdb2         5750500     7935999     1092750   83  Linux
root@moon:/home/juan# 

Ahora creo la partición de 128Mbytes,

root@moon:/home/juan# fdisk -u /dev/sdb

Orden (m para obtener ayuda): n
Acción de la orden
e   Partición extendida
   p   Partición primaria (1-4)
p
Número de partición (1-4, valor predeterminado 1): 1
Primer sector (2048-7935999, valor predeterminado 2048): 
Se está utilizando el valor predeterminado 2048
Último sector, +sectores o +tamaño{K,M,G} (2048-5750499, valor predeterminado 5750499): +128M

Orden (m para obtener ayuda): p

Disco /dev/sdb: 4063 MB, 4063232000 bytes
125 cabezas, 62 sectores/pista, 1024 cilindros, 7936000 sectores en total
Unidades = sectores de 1 * 512 = 512 bytes
Tamaño de sector (lógico / físico): 512 bytes / 512 bytes
Tamaño E/S (mínimo/óptimo): 512 bytes / 512 bytes
Identificador del disco: 0x00091593

Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sdb1            2048      264191      131072   83  Linux
/dev/sdb2         5750500     7935999     1092750   83  Linux

Orden (m para obtener ayuda): w
¡Se ha modificado la tabla de particiones!

Llamando a ioctl() para volver a leer la tabla de particiones.
Se están sincronizando los discos.
root@moon:/home/juan# 

Formateo la partición con FAT32:

root@moon:/home/juan# mkfs.vfat -F 32 /dev/sdb1
mkfs.vfat 3.0.9 (31 Jan 2010)
root@moon:/home/juan# mount /dev/sdb1 /media/
root@moon:/home/juan# mount|grep vfat
/dev/sdb1 on /media type vfat (rw)
root@moon:/home/juan# df -h|grep media
/dev/sdb1             127M   512  127M   1% /media
root@moon:/home/juan# 

Listo, ahora copiamos los archivos:

root@moon:/home/juan# ll /media/
total 10969
drwxr-xr-x  2 root root     512 2013-04-07 22:20 ./
drwxr-xr-x 25 root root    4096 2013-02-18 15:44 ../
-rwxr-xr-x  1 root root 3252736 2013-04-07 22:20 04030-SlippingInTheWindow_v1.0.doc*
-rwxr-xr-x  1 root root 4163672 2013-04-07 22:20 dopdf-7.exe*
-rwxr-xr-x  1 root root    5036 2013-04-07 22:20 france1.jpg*
-rwxr-xr-x  1 root root   20480 2013-04-07 22:20 strings.txt*
-rwxr-xr-x  1 root root  160256 2013-04-07 22:20 TARIFAS.doc*
-rwxr-xr-x  1 root root 3624496 2013-04-07 22:20 ZTEDrvSetup.exe*
root@moon:/home/juan# df -h|grep media
/dev/sdb1             127M   11M  116M   9% /media
root@moon:/home/juan# 

Desmontamos y volvemos a montar la unidad para que las operaciones pendientes se hagan si o si.

Borramos todos los archivos de la partición:

root@moon:/media# rm *
root@moon:/media# df -h|grep media
/dev/sdb1             127M   512  127M   1% /media
root@moon:/media# 

Escribimos ahora un archivo gigante que ocupe toda la partición:

root@moon:/media# dd if=/dev/zero of=archivo_gigante bs=1024
dd: escribiendo «archivo_gigante»: No queda espacio en el dispositivo
129039+0 registros leídos
129038+0 registros escritos
132134912 bytes (132 MB) copiados, 0,706763 s, 187 MB/s
root@moon:/media# 

Ocupé toda la partición con archivo_gigante, lleno de zeros obtenidos de "/dev/zero".

root@moon:~# df -h|grep media
/dev/sdb1             127M  127M   512 100% /media
root@moon:~# 

Para averiguar un poco de nuestra partición utilizamos fsstat,

root@moon:~# fsstat /dev/sdb1
FILE SYSTEM INFORMATION
--------------------------------------------
File System Type: FAT32

OEM Name: mkdosfs
Volume ID: 0xb01a12a4
Volume Label (Boot Sector):            
Volume Label (Root Directory):
File System Type Label: FAT32   
Next Free Sector (FS Info): 25995
Free Sector Count (FS Info): 1

Sectors before file system: 0

File System Layout (in sectors)
Total Range: 0 - 262143
* Reserved: 0 - 31
** Boot Sector: 0
** FS Info Sector: 1
** Backup Boot Sector: 6
* FAT 0: 32 - 2048
* FAT 1: 2049 - 4065
* Data Area: 4066 - 262143
** Cluster Area: 4066 - 262143
*** Root Directory: 4066 - 4066

METADATA INFORMATION
--------------------------------------------
Range: 2 - 4129254
Root Directory: 2

CONTENT INFORMATION
--------------------------------------------
Sector Size: 512
Cluster Size: 512
Total Cluster Range: 2 - 258079

FAT CONTENTS (in sectors)
--------------------------------------------
4066-4066 (1) -> EOF
4067-25994 (21928) -> EOF
25996-262143 (236148) -> 4067

Fsstat nos muestra que tenemos dos entradas en la FAT, la primera es la correspondiente al directorio raiz, en la posición sector 4066. Y la segunda ocupa los sectores desde el sector 25996 hasta el 262143 y luego continua en el sector 4067 hata el 25994.

Podemos ver el contenido del sector correspondiente al directorio raíz y su contenido:

root@moon:~# dd if=/dev/sdb1 bs=512 skip=4066 count=1 > RAIZ
1+0 registros leídos
1+0 registros escritos
512 bytes (512 B) copiados, 0,001339 s, 382 kB/s
root@moon:~# cat RAIZ 
Bte����k����������������archikvo_giganARCHIV~1    d��B�B��B�U8��4030-~1DOC d���B�B���B�1�dopdf�-7.exe���OPDF-7 EXE d���B�B���B�▒X�?�francVe1.jpg���RANCE1 JPG d���B�B���B�8��strin gs.txt���TRINGS TXT ���B�B���B�8P�TARIFaAS.doc���ARIFAS DOC d���B�B���B�8r�xe����������������������ZTEDr�vSetup.e�TEDRV~1EXE ���B�B���B:0N7
root@moon:~# 

Podemos ver en la entrada de directorio que aún se preservan los nombres de los archivos que habíamos copiado en el dispositivo.
Si hacemos unos cálculos podemos asumir que nuestro archivo_gigante ocupa 258076 (236148 + 21928) sectores es decir unos 132134912 bytes, que CASUALMENTE es el número de bytes que escribió nuestro dd. Por lo pronto podemos asumir que la totalidad del dispositivo fue sobre escrito por este archivo y no podríamos recuperar ninguno de los otros.

Bueno, a intentar recuperar. Para esto voy a usar autopsy, un GUI web para sleuthkit.


Luego de agregar la imagen a autopsy la analizamos:


Y vemos:


A simple vista vemos que autopsy fue capaz de reconocer la previa existencia de todos los archivos e incluso sus tamaños. Por lo tanto intentamos recuperar france1.jpg.


Autopsy nos indica que france1.jpg tenia un tamaño de 5036 bytes y que comenzaba en el sector 18553. Por lo tanto esto significa que salvo que haya estado fragmentado el sistema de archivo, los sectores desde 18553 al 18563 pertenecian a france1.jpg (5036 bytes entran en 10 sectores de 512 bytes).

root@moon:/home/juan/borrar# dd if=/dev/sdb1 of=france1.jpg bs=512 skip=18553 count=10
10+0 registros leídos
10+0 registros escritos
5120 bytes (5,1 kB) copiados, 0,002215 s, 2,3 MB/s
root@moon:/home/juan/borrar# file france1.jpg 
france1.jpg: data
root@moon:/home/juan/borrar# 

Lamentablemente ya no es posible recuperar el archivo, solo obtuvimos 5120 bytes con ceros...

root@moon:/home/juan/borrar# hexdump -v france1.jpg 
0000000 0000 0000 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
0000040 0000 0000 0000 0000 0000 0000 0000 0000
0000050 0000 0000 0000 0000 0000 0000 0000 0000
0000060 0000 0000 0000 0000 0000 0000 0000 0000
0000070 0000 0000 0000 0000 0000 0000 0000 0000
...
00013f0 0000 0000 0000 0000 0000 0000 0000 0000
0001400
root@moon:/home/juan/borrar# 

Probemos ahora con ZTEDrvSetup.exe, según autopsy se trataba de un ejecutable de windows que pesaba 3624496 bytes y que comenzaba en el bloque 18916. Asumiendo lo mismo que en el archivo anterior, extraemos los datos desde el sector 18916 al sector 25996 (18916+7080).

root@moon:/home/juan/borrar# dd if=/dev/sdb1 of=ZTEDrvSetup.exe bs=512 skip=18916 count=7080
7080+0 registros leídos
7080+0 registros escritos
3624960 bytes (3,6 MB) copiados, 0,196779 s, 18,4 MB/s
root@moon:/home/juan/borrar# file ZTEDrvSetup.exe
ZTEDrvSetup.exe: data
root@moon:/home/juan/borrar# hexdump ZTEDrvSetup.exe
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0374e00 ae12 25be 6b96 5383 fbe3 51b5 db26 8c30
0374e10 b291 8f4a 8715 ab6c a46a 389a 8ff4 6c0c
0374e20 b926 2552 f303 cdbc 4bee c8a3 0b9d 0000
0374e30 0000 0000 0000 0000 0000 0000 0000 0000
*
0375000
root@moon:/home/juan/borrar#

Sin éxito nuevamente.

Al parecer por métodos de software no es posible recuperar archivos en particiones FAT que fueron sobreescritas completamente. Esto tiene sentido ya que al escribir en todo el espacio disponible los archivos que fueron previamente eliminados son tratados como espacio libre y por lo tanto sobreescritos.

Si bien en principio no podemos recuperar los archivos, todavía contamos con información interesante como su tamaño y sus datos MAC (Modified, Accessed and Created).

Este mismo comportamiento es de esperarse en soportes magnéticos que tengan FAT como sistema de archivo. Por lo tanto la recuperación por software debería ser idéntica en ambos medios. De todas manera, podrían existir métodos de recuperación mas específicos para cada tecnología, donde no se analizaría solamente el sistema de archivo, sino también buffers y hasta el propio soporte (hardware).