Blog

Forensics – imágenes de disco paso a paso

Existen distintas razones para que uno desee hacer una copia de un disco duro. Voy a describir los métodos para crear una copia bit a bit de un disco duro o bien en un dispositivo local o en una red.

No olvidar que Linux piensa en todo como un archivo. Así que el archivo con el nombre hda o sda en el directorio /dev es en realidad el disco duro.

Herramientas utilizadas.

  • Una distribución de Linux de live CD o USB booteable con Kali o Backtrack.
  • dd : es un comando de la familia de los Sistemas Operativos Unix que permite copiar y convertir datos de archivos a nivel bajo, dd copia el archivo especificado como origen hacia el archivo indicado como destino, teniendo en cuenta la conversión de los datos y el tamaño de bloque, si es que se especificó, para realizar tanto la lectura sobre el origen como la escritura en destino. En caso de que no se haya especificado un origen y/o destino, dd por defecto utiliza la entrada y salida estándar, respectivamente, para llevar a cabo la operación. La sintaxis general del comando dd es: # dd if=$input_data of=$output_data [options] input_data y output_data pueden ser discos, particiones, archivos, dispositivos… principalmente todo lo que usted pueda escribir a o leer.
  • nc : es una herramienta de red que permite a través de intérprete de comandos y con una sintaxis sencilla abrir puertos TCP/UDP en un HOST (quedando netcat a la escucha)
  • split : usada para partir un archivo en uno o más de menor tamaño.
  • md5sum : realiza un hash MD5 de un archivo. La función de hash devuelve un valor que es prácticamente único para cada archivo, con la particularidad que una pequeña variación en el archivo provoca una salida totalmente distinta, lo que ayuda a detectar si el archivo sufrió alguna variación.
  • cat : usado para concatenar y mostrar archivos.

Requerimientos.

  • 2 ordenadores o maquínas virtuales (si se crea una copia a través de una red)
  • Unidad flash USB
  • Disco duro USB (Si la creación de la imagen en un disco duro USB)

Para una copia en una red

Para hacer una copia a través de una red se necesitan 2 ordenadores, el equipo al que se le realizara una copia del disco, PC1, y el equipo que almacenara la copia, PC2.

  1. Inserte el disco de arranque de Linux en PC1 y arrancar el sistema en Linux.
  1. Inserte la unidad flash USB, si no se monta automáticamente se requerirá montaje. En el ejemplo a continuación voy a suponer que es /dev/sdb1 y se ha montado como /media/USB4.

Captura de pantalla 2013-08-30 a la(s) 12.03.56

  1. Busquen el disco que desean copiar en el directorio /dev, en el ejemplo, el disco duro se llama sda con particiones sda1, sda2, etc… y tal vez el vuestro algo similar o hda.
  1. Con el comando md5sum /dev/sda > /media/USB4/diskimage_md5hash.txt crear un hash MD5 de la unidad en la unidad USB montada para luego comprobar esto contra el archivo copiado, para verificar la integridad.

Captura de pantalla 2013-08-30 a la(s) 12.24.26

  1. En PC2 asegúrese de que tiene suficiente espacio en disco para dar cabida a un archivo del tamaño del disco que se va a copiar y con el netcat (nc), ejecute el siguiente comando

nc -l -p 8888 > /Users/mi-user/diskimage.img

Captura de pantalla 2013-08-30 a la(s) 13.24.10

Lo que se ha hecho aquí es colocar a escuchar de forma persistentemente (-l) netcat (nc) en el puerto 8888 (-p 6677) y envía el resultado a un archivo en /Users/mi-user/diskimage.img de PC2 (> /Users/mi-user/diskimage.img) esta ruta es normal en un ordenador con OS X.

  1. Desde PC1 ejecute el siguiente comando:

dd if=/dev/sda | nc 192.168.1.3 8888

Captura de pantalla 2013-08-30 a la(s) 13.23.48

Este comando asume que la dirección IP de PC2 es 192.168.1.3. Al ejecutar este comando se va a copiar el archivo de entrada /dev/hda (if=/dev/sda) de PC1 a /Users/mi-user/diskimage.img en PC2 utilizando netcat (nc).

Captura de pantalla 2013-08-30 a la(s) 13.24.48

  1. Finalmente, después de terminar la copia puedes ejecutar md5sum en PC2 contra el archivo /Users/mi-user/diskimage.img en PC2 y comparar esto con la suma md5 adoptada anteriormente para verificar si las copias son idénticas.

Una copia local de un dispositivo de almacenamiento USB

En este ejemplo, usted necesitará sólo el PC de destino y un dispositivo de almacenamiento USB lo suficientemente grande como para contener la imagen.

  1. Inserte el disco de arranque de Linux en el ordenador y arrancar el sistema en Linux.
  2. Conecte el dispositivo de almacenamiento USB, si no se monta automáticamente se requerirá montaje. En el ejemplo a continuación voy a suponer que es /dev/sdb1 y se ha montado como /media/USB.
  1. Busquen el disco que desean copiar en el directorio /dev, en el ejemplo, el disco duro se llama sda con particiones sda1, sda2, etc… y tal vez el vuestro algo similar o hda.
  1. Con el comando md5sum /dev/sda > /media/USB/diskimage_md5hash.txt crear un hash MD5 de la unidad en el dispositivo USB montado para que pueda probar esto contra el archivo copiado, para verificar la integridad.
  1. Ejecute el siguiente comando:

dd if =/dev/sda of =/media/usb/diskimage.img

Esto copiará el disco como un archivo en el dispositivo de almacenamiento USB como diskimage.img.

  1. Crear otra hash MD5 de la imagen en el dispositivo de almacenamiento y comparar a la original para verificar la integridad de la copia.

El resultado de los dos ejemplos anteriores es una imagen válida a efectos legales del disco duro.

Uso avanzado de dd 

Durante el uso de los métodos anteriores puede encontrarse con problemas. Por ejemplo, si el PC no puede leer algunos de los sectores de la unidad que va a copiar, o si el archivo se debe dividir para que quepan en el CD. O si la imagen necesita corte para que quepa en un dispositivo que es FAT32 y requiere archivos sean más pequeños de 2 GB.

Copia de una imagen de un disco con sectores defectuosos

Cuando se generan imágenes de una unidad que empieza a tener algunos sectores dañados, el siguiente comando se puede utilizar:

dd if=/dev/hda of=/media/USB conv=noerror,sync

Esto permitirá a dd continuar en los errores de lectura, y en la pista del destino donde se encuentren 0 es donde se han producido errores en la unidad de origen (por lo que su tamaño y compensaciones coincidirán). Si lo hace, es posible que desee considerar redirigir los errores estándar a un archivo, por lo que tiene un registro de dónde se encuentran sus errores.

Dividir las imágenes

Esto se puede hacer usando un par de métodos diferentes.

El método más fácil es mediante el programa de división. La sintaxis del comando si usted tiene una imagen de 4GB para encajar en un CD sería:

dd if=/dev/hda | split –b 620m – /USB/sda/

Esto dividirá la imagen de salida en secciones de 620MB (-b 620m) en el directorio /USB/sda/. El nombre que les da a los fichero suele ser a* (* puede ser cualquier letra)

Estos archivos pueden ser reformados en un archivo de imagen con el comando cat.

cat a* > bigimage.img

A continuación, cree un hash del archivo usando md5sum y lo compare con el valor hash inicial.

md5sum bigimage.img

Alternativamente, si la división no está disponible puede utilizar dd por sí mismo, pero utiliza el skip, bs (tamaño de bloque) y el recuento interruptores para evitar que la lectura comience desde el principio.

dd if=dev/hda of=/media/USB/image1.img bs=1M count=620
dd if=dev/hda of=/media/USB/image2.img bs=1M count=620 skip= 621
dd if=dev/hda of=/media/USB/image3.img bs=1M count=620 skip= 1241
dd if=dev/hda of=/media/USB/image4.img bs=1M count=620 skip= 1861
dd if=dev/hda of=/media/USB/image5.img bs=1M count=620 skip= 2481

etc ……… hasta el final del archivo de entrada.

Lo que está sucediendo aquí es que se le está diciendo a dd que trabaje en bloques de 1 MB (bs = 1M), con sólo copiar 620MB a la vez (count=620) y en algunos casos para saltar a una parte específica del archivo de entrada (skip=621 etc …) creando varias imágenes que se pueden copiar a CD. Una vez en el sistema de destino y en el mismo directorio (yo asumo que el directorio es /home/me) que se puede poner de nuevo juntos en una sola imagen con el comando siguiente.

cat /home/me/imagen * > bigimage.img

md5sum se puede ejecutar en esta imagen y se compara con el hash md5 original para comprobar la integridad.

Crear una imagen comprimida

Puede canalizar dd través de gzip para ahorrar espacio en disco.

dd if = /dev/hda | gzip-f > /media/USB/ compressed_image.img.gz

Usando la división y Gzip Juntos

Para ayudar a hacer frente al tamaño se puede utilizar gzip y split juntos. Esto tiene el beneficio de la división de la imagen y comprimirla también para ahorrar espacio y requiere menos trabajo. A continuación se muestra la sintaxis utilizada para realizar este y una explicación del comando.

dd if =/dev/hda | gzip -c | split -b 2000m – /media/USB/image.img.gz.

  1. dd se utiliza para tomar una imagen del disco duro.
  2. Esto es pasado al gzip (-c es la salida estándar)
  3. La imagen comprimida se canaliza entonces a la herramienta de división (split continuación, crea los archivos image.img.gzaa, image.img.gzab, etc)

Para restaurar la copia de seguridad de varios archivos, ejecute el comando siguiente:

cat /USB/image.img.gz * | gzip -dc | dd of =/dev/hda

  1. cat muestra el contenido del zip y archivos de imágenes divididas en stdout en orden.
  2. Los resultados se canalizan a través de gzip y se descomprimen.
  3. Y se escriben en el disco duro con el comando dd.

La creación de imágenes de disco vacías

Para crear una imagen de disco vacía, se obtienen los datos de /dev/zero. Para crear una imagen o un archivo de 10 MB:

dd if = /dev/zero of =imagen bs=1M count=1024

O

dd of=image bs=1M count=0 seek=1024

En el segundo ejemplo no hay nada escrito, ni siquiera los ceros, sólo procuramos 10MB en el archivo y ciérrelo. El resultado es un archivo disperso que es implícitamente completo de 10 MB de ceros, pero que no ocupa espacio de disco. ls -la mostrará 10MB, tanto du y df mostrarán 0. Cuando el archivo se escribe, Linux asignará espacio en disco para los datos. ls seguirán mostrando 10MB, pero du se acercará gradualmente a 10MB.

Ejemplos variados de dd:

dd if=/dev/urandom of=/dev/sda bs=4k -» Llena el disco con datos aleatorios

dd if=/dev/sda of=/dev/sdb bs=4096 -» Duplicación disco-a-disco

dd if=/dev/zero of=/dev/sda bs=4k -» Limpia un disco duro (puede necesitar ser repetido)

dd if=inputfile of=/dev/st0 bs=32k conv=sync -» Copia de archivo a dispositivo de cinta

dd if=/dev/st0 of=outfile bs=32k conv=sync -» El anterior, invertido

dd if=/dev/sda | hexdump -C | grep [^00] -» Verifica si el disco está realmente puesto a cero

dd if=/dev/urandom of=/home/$user/hugefile bs=4096 -» Llena una partición (¡Cuidado con las particiones de sistema!)

dd if=/dev/urandom of=myfile bs=6703104 count=1 -» Codifica un archivo (tal vez antes de borrarlo)

dd if=/dev/sda3 of=/dev/sdb3 bs=4096 conv=notrunc,noerror -» Copia una partición hacia otra partición

dd if=/proc/filesystems | hexdump -C | less -»Visualiza los sistemas de ficheros disponibles

dd if=/proc/partitions | hexdump -C | less -» Visualiza las particiones disponibles en kb

dd if=/dev/sdb2 ibs=4096 | gzip > partition.image.gz conv=noerror -» Crea una imagen gzip de la segunda partición del segundo disco

dd bs=10240 cbs=80 conv=ascii,unblock if=/dev/st0 of=ascii.out -» Copia el contenido de una cinta a un archivo, convirtiendo de EBCDIC a ASCII

dd if=/dev/st0 ibs=1024 obs=2048 of=/dev/st1 -» Copia de un dispositivo de bloques de 1KB a un dispositivo de bloques de 2KB

dd if=/dev/zero of=/dev/null bs=100M count=100

100+0 records in

100+0 records out

10485760000 bytes (10 GB) copied,

5.62955 s, 1.9 GB/s

Copia 10 GB de ceros a la papelera de reciclaje.

dd if=/dev/zero of=/dev/sda bs=512 count=2

fdisk -s /dev/sda

dd if=/dev/zero of=/dev/sda seek=(number_of_sectors – 20) bs=1k

Borra GPT del disco. Como GPT escribe los datos al principio

Y al final del disco, después de borrar desde el principio, tenemos que encontrar el número de sectores (el segundo comando), y entonces borrar los 20 últimos sectores.

dd if=/home/$user/bootimage.img of=/dev/sdc -» Crea un disco USB booteable (mostrado aquí como /dev/sdc)

dd if=/dev/sda of=/dev/null bs=1m -»Una buena manera de buscar bloques malos. Relacionados con respaldos y sistemas

dd if=/dev/sda of=/dev/fd0 bs=512 count=1 -» Copia el MBR a un disco flexible

dd if=/dev/sda1 of=/dev/sdb1 bs=4096 -» Duplicación disco-a-disco

dd if=/dev/sr0 of=/home/$user/mycdimage.iso\ bs=2048 conv=nosync -» Crea una imagen de un CD

mount -o loop /home/$user/mycdimage.iso /mnt/cdimages/ -» Monta localmente la imagen mencionada

dd if=/dev/sda of=/dev/sdb bs=64k conv=sync -» Útil cuando se reemplaza un disco por otro de idéntico tamaño.

dd if=/dev/sda2 of=/home/$user/hddimage1.img bs=1M count=4430

dd if=/dev/sda2 of=/home/$user/hddimage2.img bs=1M count=8860

[…]

Crea imágenes en DVD de una partición (útil para hacer respaldos)

dd if=/$location/hddimage1.img of=/dev/sda2 bs=1M

dd if=/$location/hddimage2.img of=/dev/sda2 seek=4430 bs=1M

dd if=/$location/hddimage3.img of=/dev/sda2 seek=8860 bs=1M

[etc…]

Restaura del respaldo anterior

dd if=/dev/zero count=1 bs=1024 seek=1 of=/dev/sda6 -» Destruye el superbloque

dd if=/dev/zero count=1 bs=4096 seek=0 of=/dev/sda5 -» Otra forma de destruir el superbloque

dd if=/home/$user/suspicious.doc | clamscan -» Verifica el archivo en busca de virus (necesita ClamAV)

dd if=/home/$user/binary file | hexdump -C | less -» Ver el contenido de un archivo binario (necesita hexdump)

dd if=/home/$user/bigfile of=/dev/null

dd if=/dev/zero of=/home/$user/bigfile bs=1024 count=1000000

Realiza un benchmark de la velocidad de lectura/escritura del disco duro

dd if=/dev/sda of=/dev/sda -» Da nueva vida a viejos discos duros que no han sido usados por un tiempo (los discos deben estar “unmounted”)

dd if=/dev/mem | strings | grep ‘string_to_search’ -» Examina el contenido de la memoria (legible para humanos, es decir)

dd if=/dev/fd0 of=/home/$user/floppy.image bs=2x80x18b conv=notrunc -» Copia un disco flexible

dd if=/proc/kcore | hexdump -C | less -» Muestra la memoria virtual

dd if=/proc/filesystems | hexdump -C | less -»Visualiza los sistemas de ficheros disponibles

dd if=/proc/kallsyms | hexdump -C | less -» Muestra los módulos cargados

dd if=/proc/interrupts | hexdump -C | less -» Muestra la tabla de interrupciones

dd if=/proc/uptime | hexdump -C | less -»Muestra el tiempo de actividad en segundos

dd if=/proc/partitions | hexdump -C | less -» Visualiza las particiones disponibles en kb

dd if=/proc/meminfo | hexdump -C | less -» Muestra el estado de la memoria

dd if=/dev/urandom of=/home/$user/myrandom bs=100 count=1 -» Crea un archivo de 1kb de jerigonza aleatoria

dd if=/dev/mem of=/home/$user/mem.bin bs=1024 -» Crea una imagen del estado actual de la memoria del sistema

dd if=/home/$user/myfile -» Imprime el archivo a stdout

dd if=/dev/sda2 bs=16065 | hexdump -C | grep ‘text_to_search’ -» Busca una cadena en una partición entera; incluso si está asegurada, usted puede bootear un liveCD

dd if=/home/$user/file.bin skip=64k bs=1 of=/home/$user/convfile.bin -» Copia file.bin a convfile.bin saltándose los primeros 64 kb

dd if=/dev/mem bs=1k skip=768 count=256 2>/dev/null | strings -n 8 -» Lee la BIOS.

dd bs=1k if=imagefile.nrg of=imagefile.iso skip=300k -» Convierte una imagen de Nero en una imagen ISO estándar.

Esto es posible porque la única diferencia entre las dos son los 300 kB de encabezamiento que Nero adiciona a una imagen ISO estándar.

echo -n “hello vertical world” | dd cbs=1 conv=unblock 2> /dev/null -» Inténtalo, es seguro. :-)

dd if=/dev/sda1 | gzip -c | split -b 2000m – \ /mnt/hdc1/backup.img.gz -» Crea una imagen gzip de una partición utilizando división

cat /mnt/hdc1/backup.img.gz.* | gzip -dc | dd of=/dev/sda1 -» Restaura el respaldo anterior

dd if=/dev/zero of=myimage bs=1024 count=10240 -» Crea una imagen vacía del disco

dd ibs=10 skip=1 -» Divide los primeros 10 bytes de stdin

dd bs=265b conv=noerror if=/dev/st0 of=/tmp/bad.tape.image -» Hace una imagen de una cinta con sitios malos

dd if=/dev/sda count=1 | hexdump -C -» Visualiza su MBR

dd if=/dev/sda | nc -l 10001 nc $system_to_backup_IP 10001 | dd of=sysbackupsda.img -» Respaldo rápido de la red usando netcat

dd if=/dev/zero of=/dev/sdX bs=1024000 count=1 -» Limpia los primeros 10MB de la partición

dd if=/dev/zero of=tmpswap bs=1k

count=1000000

chmod 600 tmpswap

mkswap tmpswap

swapon tmpswap

Crea un espacio temporal de intercambio

dd if=/dev/sda of=/dev/null bs=1024k count=1024

1073741824 bytes (1.1 GB) copied,

24.1684 s, 44.4 MB/s

Determina la velocidad secuencial de I/O de su disco.

dd if=/dev/random count=1 2>/dev/null | od -t u1 |\ awk ‘{ print $2}’ | head -1 -»Genera un número aleatorio

dd if=/dev/mem of=myRAM bs=1024 -» Copia la memoria RAM hacia un archivo

dd if=/dev/sda bs=512 count=1 | od -xa -» Ver el contenido de su MBR en formato hex y ASCII

dd if=/my/old/mbr of=/dev/sda bs=446 count=1 -» Restaura el MBR sin alterar el registro de la tabla de partición el cual está entre 447 – 511 bytes

dd if=/dev/sda1 | split -b 700m – sda1-image -»Crea una copia de la partición y salva imágenes donde el tamaño máximo del volumen es 700MB

ls -l | dd conv=ucase -» Convierte la salida de un comando en mayúsculas

echo “MY UPPER CASE TEXT” | dd conv=lcase -» Convierte cualquier texto a minúsculas

dd if=/etc/passwd cbs=132 conv=ebcdic of=/tmp/passwd.ebcdic -» Convierte el archivo de contraseñas del sistema a un archivo de longitud fija de formato EBCDIC

dd if=text.ascii of=text.ebcdic conv=ebcdic -» Convierte de ASCII a EBCDIC

dd if=myfile of=myfile conv=ucase -»Convierte un archivo a mayúsculas (simple SED o reemplazo tr)

Nos vemos el próximo viernes.

Un saludo a todos

“La curiosidad mato al gato y a un hacker le dio su ZeroDay”
Sebastian Cornejo.

@CuriositySec sebastian@highsec.es

  1. BTshell
    BTshell08-31-2013

    Estupenda Entrada Sebas 😉

  2. fanta
    fanta09-12-2013

    Pues justo esto me viene al pelo ahora mismo. Se agradece la pedazo de entrada y todo el trabajo.
    🙂

Leave a Reply

*

    No Twitter Messages