Escondiendo Datos en los “Padding Bytes” del Formato BMP

Escondiendo Datos en los “Padding Bytes” del Formato BMP

El formato de imágenes BMP es ampliamente conocido y soportado por muchos sistemas operativos, además de ser el formato nativo de imágenes en Windows. En la estructura de archivo del formato BMP notamos que los primeros 54 Bytes corresponden a la cabecera BMP y la cabecera DIB, que son obligatorias en el archivo y en la cual van los datos de tamaño del archivo, tamaño de la imagen, etc. Correspondientes a los metadatos, y distribuidos de la siguiente manera:

  • 2 bytes – contienen siempre ‘BM’, para poder identificar que es un BMP
  • 4 bytes – tamaño del archivo (en bytes)
  • 4 bytes – Reservados, contienen ceros (reservados para usos futuros)
  • 4 bytes – offset de inicio de los datos de la imagen
  • 4 bytes – Tamaño de la cabecera del bitmap (tamaño de esta estructura = 40)
  • 4 bytes – Ancho (numero de píxeles horizontales)
  • 4 bytes – Alto (numero de pixeles verticales)
  • 2 bytes – Numero de planos de color (Valdrá 1)
  • 2 bytes – Profundidad de color (24 bits para nuestro caso)
  • 4 bytes – Tipo de compresión (valdrá 0, ya que es descomprimido)
  • 4 bytes – Tamaño de la Imagen en Bytes 4 bytes – Píxeles por metro horizontal (No lo usaremos)
  • 4 bytes – Píxeles por metro vertical (No lo usaremos)
  • 4 bytes – Cantidad de colores usados (No lo usaremos)
  • 4 bytes – Cantidad de colores importantes (No lo usaremos)

Teniendo en cuenta la estructura que debe seguir la cabecera del archivo BMP, construiremos una “BASE”  para un Bitmap de dimensiones 2×2 pixeles y de color Blanco (FF, FF, FF).

Notaremos cada una de las partes que componen la cabecera del BMP, separadas por colores, y a partir del OFFSET 36h empiezan los datos de la imagen (sombreados en Gris).

Los archivos BMP de 24bits usan 3Bytes (8bits x 3 = 24) para representar un pixel, y en cada Byte se representa el valor de uno de los canales de color RGB, y en este caso el orden de los canales es invertido, luego estarán en orden azul-verde-rojo (B, G, R).

Estos pixeles son organizados en filas y guardados “boca-abajo”, lo que significa que el primer pixel en el archivo corresponde al de la esquina inferior, seguido por el de la derecha (leídos de izquierda a derecha) hasta finalizar dicha fila, para continuar con la fila superior a la anterior, y así sucesivamente hasta llegar a la primera fila de pixeles de la imagen, con el ultimo pixel de la esquina superior derecha.

Cada “fila” debe tener una longitud en bytes que sea múltiplo de 4, ósea cuyo modulo 4 sea igual a 0, si esta propiedad no se cumple, se agregaran (padding) cuantos bytes nulos (00) sean necesarios para completar la fila y que se cumpla esta regla.

Bytes Nulos = (Pixeles Ancho MOD 4)

Así en un archivo de 2×2 pixeles (véase imagen) contendrá en cada fila 6 bytes de color mas 2 bytes nulos complementarios para cumplir esta regla. Un archivo de 4×4 pixeles no necesitara de estos bytes nulos puesto que la cantidad de bytes de sus pixeles es múltiplo de 4, luego el resultado de la formula anterior será 0.

La especificación del formato dice que no es necesario que estos bytes sean nulos (00) sino que pueden contener cualquier valor, puesto que sirven de “separador” entre las “filas” de pixeles, y son ignorados por los visualizadores de imágenes.

Entonces, he aquí el truco, será en esos “bytes nulos” en donde podremos insertar nuestro contenido o mensaje oculto, sin afectar la visualización de la imagen, y así pasar desapercibido.

La capacidad de almacenamiento estará determinada por el ancho y alto de la imagen, siguiendo esta simple formula:

Bytes Disponibles = ((Pixeles Ancho MOD 4) * Pixeles Alto)

Así, una imagen de 20×20 pixeles no tendremos espacio para almacenar datos, y una imagen de 21×21 pixeles tendrá capacidad para guardar 63 Bytes de datos, sin ver alterado su contenido visual.

En estos Bytes disponibles podremos insertar cualquier tipo de contenido, de forma binaria, que no sobrepase el límite, y podrá ser visualizado mediante análisis hexadecimal o con un software especializado (por desarrollar aun).

Cabe aclarar que esta técnica es totalmente diferente a LSB (Least Significant Bit) puesto que se usan “Bytes Nulos” al final de cada fila de pixeles, y no se modifican los datos del pixel en el ultimo Bit.

Dejo un ejemplo de un BMP normal, y el mismo BMP con contenido insertado, un mensaje secreto que han de descubrir.

Logo Original  – Logo Modificado con Mensaje


Artículos Relacionados

4 Comentarios

  1. Calantra. - junio 13, 2012, 5:31 am Responder

    Buenas, revisa el ejemplo modificado, me parece que están mal insertados los bytes ocultos. Si no me equivoco, la imagen tiene un byte de padding al ser (315*3) mod 4 = 1. Este primer byte aparece en la posicion 54 (cabecera)+ (315*3) (en el jemplo una ‘R’) y el siguiente debiría aparecer en la posición ((315*3)*2)+1(byte oculto)+54(cabecera), y en este caso aparece 0xFF. He creado un programa para esto y lo he comprobado, el ejemplo de 2×2 sale sin problema, pero el otro no sale ningún mensaje que se entienda.
    Un slaudo.

  2. Germaniac - junio 13, 2012, 9:42 pm Responder

    Buena idea SmartGenius, ya empezaste a hacer pruebas con el formato bmp.

    Solo una observación, la formula para sacar el número de bytes de relleno no es (ancho*3) mod 4, sino simplemente ancho mod 4.

    P. D. “El veloz murciélago hindú comía feliz cardillo y kiwi. La cigüeña tocaba el saxofón detrás del palenque de paja”.

  3. SmartGenius - junio 14, 2012, 3:56 pm Responder

    Hola, gracias por tu comentario, he revisado bien, y pues si fue un pequeño error de mi parte en la redaccion, las ecuaciones como tal son estas:

    1ra – Bytes Nulos = (Pixeles Ancho MOD 4)

    2da – Bytes Disponibles = ((Pixeles Ancho MOD 4) * Pixeles Alto)

    Corregire eso en la entrada, y en base a esto puedes revisar de nuevo el BMP 😛

    Saludos.

  4. Javier - abril 7, 2016, 3:39 am Responder

    Dado que el método ya es conocido habría que encriptar además esos butes. Combinar criptografía con estaganografía.

Deja un comentario

Tu email no será publicado.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*