on

Resconstruyendo datos mediante el ingenio – Análisis forense en dispositivos móviles (II)

Existen situaciones en las que un investigador forense necesita sobrepasar las limitaciones técnicas intrínsecas a las herramientas existentes en la actualidad. Un claro ejemplo de esto sucede cuando el investigador necesita interpretar datos que contiene un teléfono móvil, los cuales pueden sufrir una fuerte fragmentación y, además, las entradas de la FAT también pueden estar completamente destruídas.

El presente artículo es una continuación del artículo Análisis forense en dispositivos móviles (I), en dónde repasamos diferentes métodos para realizar una adquisición de los datos contenidos en la memoria flash de dispositivos móviles. Para trabajar con datos tangibles, pongamos como ejemplo de adquisición un volcado de memoria NAND, descargable desde aquí. Dicho volcado de memoria corresponde al reto forense del 2010, realizado por la Digital Forensics Research Conference.

En dicho volcado de memoria, una vez filtrado el SPARE, tal y como se comentó en el artículo anterior, obtenemos una imagen limpia, a la que llamaremos: SonyEricsson_K800i_NAND_NAND512R3A_data.bin.

[sourcecode language=’bash’]
cosmic@bartolo:/tmp$ ./unspare SonyEricsson_K800i_NAND_NAND512R3A.bin SonyEricsson_K800i_NAND_NAND512R3A_data.bin SonyEricsson_K800i_NAND_NAND512R3A_spare.bin 512 16
cosmic@bartolo:/tmp$ ls -als SonyEricsson_K800i_NAND_NAND512R3A*
67656 -rwxr-xr-x 1 cosmic cosmic 69206016 2010-09-21 10:45 SonyEricsson_K800i_NAND_NAND512R3A.bin
65604 -rw-r–r– 1 cosmic cosmic 67108864 2010-09-21 11:02 SonyEricsson_K800i_NAND_NAND512R3A_data.bin
2052 -rw-r–r– 1 cosmic cosmic 2097152 2010-09-21 11:02 SonyEricsson_K800i_NAND_NAND512R3A_spare.bin
[/sourcecode]

Para los que tengáis la curiosidad de analizar superficialmente dicha imagen, veréis que existen dos particiones FAT16 y otras dos particiones FAT12, las cuales están fuertemente fragmentadas y las tablas de particiones FAT corrompidas. Este hecho hace que las aplicaciones habituales para realizar File Carving, como por ejemplo scalpel o foremost, no sean eficientes. Este tipo de herramientas extraen los ficheros en base a un catálogo de cabeceras preconfiguradas, siempre y cuando toda la información se encuentre almacenada de forma secuencial y sin fragmentación. En nuestro caso, la limitación reside en que, mediante este tipo de herramientas, sólo seremos capaces de recuperar ficheros siempre y cuando la distribución de los datos sea secuencial.

Para ejemplificar con estas herramientas, intentemos recuperar un fichero en concreto, aunque antes de esto, vayamos a transformar la imagen binaria a hexadecimal legible, para que nos sea más fácil identificar el fichero que queremos extraer.
[sourcecode language=’plain’]
cosmic@bartolo:/tmp$ hexdump -C SonyEricsson_K800i_NAND_NAND512R3A_data.bin > SonyEricsson_K800i_NAND_NAND512R3A_data.hex
[/sourcecode]

Abriendo el fichero SonyEricsson_K800i_NAND_NAND512R3A_data.hex con cualquier editor, podremos identificar, en el offset 03d0e000h, la siguiente información:
[sourcecode language=’plain’]

03d0e000 ff d8 ff e1 1d fc 45 78 69 66 00 00 49 49 2a 00 |……Exif..II*.|
03d0e010 08 00 00 00 0a 00 0f 01 02 00 0e 00 00 00 86 00 |…………….|
03d0e020 00 00 10 01 02 00 06 00 00 00 a6 00 00 00 12 01 |…………….|
03d0e030 03 00 01 00 00 00 01 00 00 00 1a 01 05 00 01 00 |…………….|
03d0e040 00 00 de 00 00 00 1b 01 05 00 01 00 00 00 e6 00 |…………….|
03d0e050 00 00 28 01 03 00 01 00 00 00 02 00 00 00 31 01 |..(………..1.|
03d0e060 02 00 27 00 00 00 b6 00 00 00 32 01 02 00 14 00 |..’…….2…..|
03d0e070 00 00 ee 00 00 00 13 02 03 00 01 00 00 00 02 00 |…………….|
03d0e080 00 00 69 87 04 00 01 00 00 00 02 01 00 00 76 02 |..i………..v.|
03d0e090 00 00 53 6f 6e 79 20 45 72 69 63 73 73 6f 6e 00 |..Sony Ericsson.|

[/sourcecode]

El string “Exif II” nos está indicando que se trata de un fichero JPEG. Pues bien, vamos a intentar extraerla. Sobre nuestra imagen de trabajo SonyEricsson_K800i_NAND_NAND512R3A_data.bin vamos a comprobar el resultado obtenido por la herramienta foremost:
[sourcecode language=’bash’]
cosmic@bartolo:/tmp$ foremost SonyEricsson_K800i_NAND_NAND512R3A_data.bin Processing: SonyEricsson_K800i_NAND_NAND512R3A_data.bin
|*|
[/sourcecode]

El comando anterior permite, mediante el uso de la herramienta foremost, extraer una gran cantidad de información parcial, para identificar cual de los ficheros incompletos corresponde con nuestra imagen, editaremos el fichero audit.txt generado por foremost y buscaremos por la entrada de nuestro JPG. El offset 03d0e000h corresponde con 64020480d, de modo que identificamos rápidamente la siguiente línea:

15: 00125040.jpg 7 KB 64020480

Esto significa que foremost ha sido capaz de extraer 7 KB de nuestro fichero JPG, y lo ha guardado como 00125040.jpg. Lamentablemente, vemos que el fichero recuperado es completamente inútil, puesto que deben existir otros fragmentos del mismo en otras ubicaciones no secuenciales.

Un investigador forense deberá replantearse la estrategia, puesto que en este caso las herramientas de Data Carving no han sido ni eficaces. En este caso entran en juego una evolución de las herramientas anteriormente mencionadas, las cuales se basan en Smart Carving. Esta nueva generación de herramientas suelen ser más eficientes, especialmente cuando se trata de extraer imágenes y fotografías.

La teoría del Smart Carving es que, utilizando técnicas de procesado digital de imagen, es posible de identificar otros fragmentos que enlacen con una imagen o fotografía. Esto significa que, hasta cierto punto, la extracción es robusta ante ficheros fragmentados en disco. En la práctica, la experiencia nos demuestra que tampoco es la panacea. Como ejemplo de herramienta que utilice Smart Carving, vamos a destacar Revit, cuyos resultados vemos a continuación.

[sourcecode language=’bash’]
cosmic@bartolo:/tmp$ revit -b 4096 –c /usr/local/etc/file_types.conf -e -F -t revit_output / SonyEricsson_K800i_NAND_NAND512R3A_data.bin
[/sourcecode]

Nota: El tamaño del clúster, en este el ejemplo utilizado, es de 4096 bytes.

Esta herramienta llama a los resultados igual al offset donde comienza el fichero extraído (esta vez en hexadecimal), por lo que rápidamente podremos identificar el fichero 03d0e000.jpg:

Como podemos observar, aunque mediante Smart Carving se ha conseguido encontrar ciertas partes de la fotografía, mejorando sensiblemente los resultados obtenidos mediante un simple Data Carving, todavía queda información dispersa, relativa a la fotografía que queremos recuperar, y que no ha podido ser recuperada.

Una vez agotadas las posibilidades que permiten las herramientas confeccionadas para tal efecto, no nos queda más remedio que recurrir al ingenio. Lo primero que se nos podría ocurrir es realizar un sencillo cálculo estadístico para catalogar la información, basado en medias y desviaciones en la secuencia de bytes del fichero SonyEricsson_K800i_NAND_NAND512R3A_data.bin. Para esto, hemos diseñado una prueba de concepto:

[sourcecode language=’C’]
/*****************************************/
/******** medias by blueliv 2010 ********/
/*****************************************/

#include
#include
#include

#define CLUSTER_SIZE 4096

main (int argc, char** argv) {
FILE *flash_image_file;
int imprime,cuantos,ultcluster;
unsigned char buffer[CLUSTER_SIZE];

int n,total,cluster,desviacion;
cluster=0;
flash_image_file = fopen(argv[1], “rb”);

if (flash_image_file) {
while (!feof(flash_image_file)) {
n=fread(buffer, CLUSTER_SIZE, 1, flash_image_file);
total=0;
desviacion=0;
for (n=0;n<CLUSTER_SIZE;n++) {
desviacion=desviacion+abs(buffer[n]-buffer[n-1]);
total=total+buffer[n];
}
imprime=0;
total=total/4096;
desviacion=desviacion/4096;
if (strncmp(buffer+6,”Exif”,4)==0) {
printf (“File: Exifn”);
imprime=1;
}
if (strncmp(buffer+6,”JFIF”,4)==0) {
printf (“File: JFIFn”);
imprime=1;
}
if (strncmp(buffer,”PK”,2)==0) {
printf (“File: ZIPn”);
imprime=1;
}
if (strncmp(buffer+1,”PNG”,3)==0) {
printf (“File: PNGn”);
imprime=1;
}

if ((total<140) && (total>100) && (desviacion<90) && (desviacion>60)) {
imprime=1;
printf(“**”);
}

printf (“Cluster:%d, offset:%x, average:%d, desv:%dn”,cluster,cluster*CLUSTER_SIZE,total,desviacion);
ultcluster=cluster;
cluster=cluster+1;
}
}
else {
printf (“Error abriendo ficheron”);
}
}
[/sourcecode]

Este programa permite obtener, cluster a cluster, el valor medio de los bytes, así como la desviación media existente entre los bytes de un mismo cluster. De modo que manos a la obra, vamos a ejecutar el programa:

[sourcecode language=’bash’]
cosmic@bartolo:/tmp$./medias SonyEricsson_K800i_NAND_NAND512R3A_data.bin estudio_medias.txt
[/sourcecode]

Recordemos que nuestra intención es recuperar un fichero JPG, el cual comienza en el offset 03d0e000h. O lo que es lo mismo, en el cluster 15630d, para lo que se muestra un extracto de dicho entorno en el fichero estudio_medias.txt obtenido:

[sourcecode language=’plain’]

Cluster:15627, offset:3d0b000, average:181, desv:116
Cluster:15628, offset:3d0c000, average:254, desv:0
Cluster:15629, offset:3d0d000, average:201, desv:9
Exif
**Cluster:15630, offset:3d0e000, average:101, desv:63
**Cluster:15631, offset:3d0f000, average:122, desv:76
**Cluster:15632, offset:3d10000, average:117, desv:84
Cluster:15633, offset:3d11000, average:119, desv:104
Cluster:15634, offset:3d12000, average:226, desv:1
Cluster:15635, offset:3d13000, average:255, desv:0
Cluster:15636, offset:3d14000, average:226, desv:1
Cluster:15637, offset:3d15000, average:226, desv:1
Cluster:15638, offset:3d16000, average:226, desv:1
Cluster:15639, offset:3d17000, average:226, desv:1
Cluster:15640, offset:3d18000, average:166, desv:113
**Cluster:15641, offset:3d19000, average:122, desv:86
**Cluster:15642, offset:3d1a000, average:123, desv:87
**Cluster:15643, offset:3d1b000, average:123, desv:88
**Cluster:15644, offset:3d1c000, average:118, desv:85
**Cluster:15645, offset:3d1d000, average:120, desv:86
**Cluster:15646, offset:3d1e000, average:118, desv:84
**Cluster:15647, offset:3d1f000, average:121, desv:86
**Cluster:15648, offset:3d20000, average:119, desv:84
**Cluster:15649, offset:3d21000, average:122, desv:82
**Cluster:15650, offset:3d22000, average:120, desv:86
**Cluster:15651, offset:3d23000, average:120, desv:83
**Cluster:15652, offset:3d24000, average:122, desv:83
**Cluster:15653, offset:3d25000, average:123, desv:85
**Cluster:15654, offset:3d26000, average:126, desv:84
**Cluster:15655, offset:3d27000, average:127, desv:83
**Cluster:15656, offset:3d28000, average:127, desv:82
**Cluster:15657, offset:3d29000, average:128, desv:82
**Cluster:15658, offset:3d2a000, average:127, desv:83
**Cluster:15659, offset:3d2b000, average:127, desv:84
**Cluster:15660, offset:3d2c000, average:128, desv:84
**Cluster:15661, offset:3d2d000, average:128, desv:82
**Cluster:15662, offset:3d2e000, average:129, desv:85
**Cluster:15663, offset:3d2f000, average:126, desv:84
**Cluster:15664, offset:3d30000, average:125, desv:83
**Cluster:15665, offset:3d31000, average:128, desv:86
**Cluster:15666, offset:3d32000, average:126, desv:83
**Cluster:15667, offset:3d33000, average:125, desv:83
**Cluster:15668, offset:3d34000, average:125, desv:82
**Cluster:15669, offset:3d35000, average:126, desv:81
**Cluster:15670, offset:3d36000, average:126, desv:82
**Cluster:15671, offset:3d37000, average:128, desv:82
**Cluster:15672, offset:3d38000, average:126, desv:83
**Cluster:15673, offset:3d39000, average:126, desv:82
Cluster:15674, offset:3d3a000, average:162, desv:112
Cluster:15675, offset:3d3b000, average:140, desv:101
Cluster:15676, offset:3d3c000, average:140, desv:101

[/sourcecode]

Prestando algo de atención a estos valores estadísticos, sorprende comprobar que, en función del tipo de fichero que contiene la información, los valores medios y desviaciones se encuentran dentro de unas horquillas fácilmente identificables.
Para la tipología de ficheros JPG funciona muy bien filtrar aquellos clusters cuyos valores medios residen entre 100 y 140, y que además tienen unas desviaciones entre bytes, también para cada cluster, de entorno a 60 y 90. Estos valores pueden ser modificados sobre el código fuente del programa medias, concretamente en la siguiente porción de código:

[sourcecode language=’C’]
if ((total<140) && (total>100) && (desviacion<90) && (desviacion>60)) {
imprime=1;
printf(“**”);
}
[/sourcecode]

Para trabajar con otras extensiones de ficheros se deberá ajustar la horquilla de valores al filtrar. De hecho, en otras pruebas realizadas en nuestros laboratorios, se ha comprobado que es trivial detectar los datos correspondientes a la tabla de particiones FAT, JPEG, PNG, Root Directory, etc. Pero volvamos a lo que nos atañe, que es la obtención del fichero JPG que comienza en el offset 03d0e000h.

Como puede verse en el extracto del fichero estudio_medias.txt, se ha marcado con un “**” cada cluster que, en base a los cálculos estadísticos, es susceptible de contener datos relativos a ficheros JPG. Este filtrado es una ayuda enorme para el analista forense, puesto que le permite descartar información inútil, así como ponerle sobre la información potencialmente sensible de pertenecer al fichero que queremos obtener.

Mediante esta técnica, limitamos enormemente el conjunto de clusters con datos tipificados como JPG, así como saltos propios de la fragmentación del fichero. Esta técnica puede ser con lo que se maximiza la eficiencia de las herramientas de Smart Carving, gracias a poder identificar y eliminar todo el ruido innecesario, o incluso la recuperación manual del fichero que se desea recuperar.

Volviendo a analizar el fichero estudio_medias.txt, vemos claramente que el fichero comienza con los tres clusters del offset 15630. Tras estos tres clusters, vemos claramente 8 clusters de “ruido”, que comienza en el cluster 15633. Estos clusters de “ruido” no nos interesan lo más mínimo puesto que no están identificados como datos relativos a un fichero JPG. De igual modo, identificamos la existencia de 33 clusters, comenzando por el cluster 1541, potencialmente sensibles de pertenecer a nuestro fichero.

La recomposición de los distintos fragmentos del fichero que queremos recuperar podría realizarse manualmente:

[sourcecode language=’bash’]
cosmic@bartolo:/tmp$ dd bs=4096 count=3 skip=15630 if=SonyEricsson_K800i_NAND_NAND512R3A_data.bin
of=prueba.jpg
3+0 registros de entrada
3+0 registros de salida
12288 bytes (12 kB) copiados, 0,000234178 s, 52,5 MB/s
cosmic@bartolo:/tmp$ dd bs=4096
count=33 skip=15641 if=SonyEricsson_K800i_NAND_NAND512R3A_data.bin >>
prueba.jpg
33+0 registros de entrada
33+0 registros de salida
135168 bytes (135 kB) copiados, 0,00177578 s, 76,1 MB/s
cosmic@bartolo:/tmp$ dd bs=1
count=495661 skip=25165824 if=SonyEricsson_K800i_NAND_NAND512R3A_data.bin >>
prueba.jpg
495660+0 registros de entrada
495660+0 registros de salida
495660 bytes (496 kB) copiados, 15,6082 s, 31,8 kB/s
[/sourcecode]

Y con el siguiente resultado exitoso:

Con el presente artículo se concluye que, en situación de particiones altamente fragmentadas y las tablas de particiones FAT corrompidas, no siempre es posible recuperar los ficheros mediante técnicas de Smart Carving. De hecho, este tipo de herramientas necesitan madurar mucho todavía. Dada esta situación, se recomienda filtrar la información mediante análisis estadístico, con el objeto de “quitar todo el ruido posible” y aumentar la eficiencia de dichas herramientas. Incluso me atrevería a decir que, en el caso en que se quiera recuperar un número asequible de ficheros, puede resultar más exitosa la reconstrucción manual de dichos ficheros, gracias a la utilización de las técnicas descritas.

Saludos,

Demo Free Trial MSSP
Program