Mensajes Clandestinos
SEGURIDAD
Mensajes Clandestinos
2016-09-04
Por
Yvil Yenius

Ahora que ya tenemos nuestro servidor clandestino en funcionamiento y podemos ponernos en contacto con nuestros secuaces de una forma fácil y super-secreta, es hora de idear un método para que nuestros mensajes de dominación del mundo sea también clandestino... es más, que esos mensajes diabólicos se confundan entre el inmenso océano de ruido que es Internet, y pasen totalmente desapercibidos... Ja, ja ja ja!!!!
Para conseguir esto, vamos a utilizar una antigua técnica ideada por los griegos, conocida como esteganografía. Así, a lo burro, la esteganografía nos permite ocultar una cosa, dentro de otra, de forma que la cosa oculta no sea perceptible a los ojos de la gente. Sí, la técnica se aplica en general a cualquier cosa, pero nosotros la vamos a utilizar para poder intercambiar mensajes secretos entre nuestros secuaces... sin que nadie se de cuenta.

Gatitos!

Puede que no lo sepas, pero los gatos son animales diabólicos, tradicionalmente relacionados con el mal y con el ocultismo y lo sobrenatural. Esas criaturas ya se han adueñado de Internet. Están por todas partes.... y todo el mundo los adora.

Así que, lo que vamos a hacer es utilizar fotos de gatitos para ocultar nuestros mensajes secretos y así poder dirigir nuestras hordas de secuaces en nuestra épica empresa para conquistar el mundo.

Como? ...

... os preguntaréis. Muy fácil, vamos a modificar sutilmente los bits bajos de cada pixel de una adorable imagen de un gatito y utilizarlos para almacenar nuestros mensajes secretos.

Como sabéis una imagen se puede ver como una matriz en la que cada entrada representa el color del punto correspondiente. Lo que llamamos pixels en la pantalla. Bueno, hay varias formas de codificar el color de cada pixel, y la que nos viene mejor para nuestro cometido es la conocida como True Color.

Una imagen en format True Color, utiliza 24 o 32 bits (3 o 4 bytes) por cada pixel. Los tres primeros bytes representan la intensidad de cada una de las componentes de color del pixel: Rojo, Verde y Azul, o como dirían los anglosajones Red, Green and Blue (RGB). El cuarto byte, si existe, se utiliza para indicar la transparencia del pixel.

Así que lo que vamos a hacer es:

  • Coger una imagen en formato True Color
  • Cada carácter de nuestro mensaje la representaremos con un byte, de hecho, solo necesitamos 7 bits para poder escribir mensajes sin acentos. Después de todo, a quién le interesa la ortografía?.
  • Esos 7 bits los vamos a "esparramar" por las componentes del pixel. Almacenaremos 3 bits en la componente azul, 2 bits en la verde y 2 bits en la roja. De esta forma podemos almacenar una letra por pixel
1234567
LLLLLLL

123456_78   123456_78   12345_678
RRRRRR_RR   GGGGGG_GG   BBBBB_BBB
RRRRRR_LL   GGGGGG_LL   GGGGG_LLL
123456_12   123456_34   12345_567

Un programita

Bueno, ahora que ya sabemos lo que queremos hacer, escribamos un programa para que nuestra brillante idea se haga realidad. Lo llamaremos (al programa) el_codificador_clandestino... bueno, mejor ecc que así tenemos que escribir menos.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gd.h>

int 
main(int argc, char *argv[])
{
  FILE        *f;
  gdImagePtr  image;                                   
  int         i, l, x, y, w, h,k;
  int         size;
  int         rgb, color, r, g, b, cr, cg, cb, c, cnt;

  if (argc < 3)
    {
      fprintf (stderr, "usage:%s input_image.png file.txt\n", argv[0]);
      exit (1);
    }
  f = fopen (argv[1], "rb");

  image = gdImageCreateFromPng (f);
  w = image->sx;
  h = image->sy;
  size = w * h;
  fprintf (stderr, "Tamaño: %dx%d (Capacidad: %d bytes)\n", 
	   w , h, size);
  fclose (f);

  if (argv[2][0] == '-')
    f = stdin;
  else
    f = fopen (argv[2], "rt");

  l = 0;
  cnt = 0;
  for (y = 0; y < h; y++)
    {
      for (x = 0; x < w; x++)
	{
	  if (!l)
	    {
	      fread (&c, 1, 1, f);
	      if (feof (f))
		{ l = 1 ; c=0;}
	      cnt++; 
	    }
	  else
	    goto listo;

	  /* Get pixel value */
	  rgb = gdImageGetPixel (image, x, y);
	  
	  r = ((gdImageRed(image, rgb)) & 0xfc )
	    + (c & 0x03);
	  g = ((gdImageGreen(image, rgb)) &0xfc)
	    + ((c >> 2) & 0x03);
	  b = (gdImageBlue(image, rgb) & 0xf0)
	    + ((c >> 4) & 0x0f);
	  color = gdTrueColor (r, g, b);
	  gdImageSetPixel (image, x, y, color);
	  i++;
	}
    }
 listo:
  gdImagePng (image, stdout);
  fprintf (stderr, "Encoded %d bytes out of %d bytes (%6.2f %% used)\n",
	   cnt, size, (float)cnt * 100.0 / (float)(size));
}

Nuestro pequeño programa usa una librería llamada libgd. Esta librería, es un clásico para generar imágenes y fue muy utilizada en páginas web dinámicas al principio de Internet (todavía se usa, pero ya no tanto). En cualquier caso... usamos libgd... y usamos goto.... sí, somos muy malos!. Podríamos evitar el goto fácilmente... pero después de todo no se puede dominar el mundo sin hacer cosas diabólicas... no?

El programa lee una imagen en memoria y luego un fichero de texto, el cual procesa carácter a carácter "esparramando" los bits de cada letra en los píxeles de la imagen. Una vez que se han procesado todos los ficheros volcamos la imagen en el disco y listo.

Como habréis comprobado, si especificamos como fichero de texto el carácter -, el programa leerá la entrada estándar. Pulsad, CONTROL + D cuando hayáis terminado de escribir.

Otro Programita

Bueno, para poder probar si nuestro Codificador Clandestino funciona, tendremos que programar.... EEELLL DEEEECOOOODIIIIFFIIIICAAAADOOOOOOR CLAAAAAAANDESTINO!. Si, en un despilfarro de originalidad, lo hemos llamado edc. Ya sabéis, para escribir menos.

Este es el código, básicamente deshace el "esparramao" del ecc.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gd.h>

char *s = "This is a secret message in a image!!!\n\0";

int 
main(int argc, char *argv[])
{
  FILE        *f;
  gdImagePtr  image;                                   
  int         i, l, x, y, w, h;
  int         rgb, color, r, g, b, cr, cg, cb, c;

  if (argc != 2)
    {
      fprintf (stderr, "usage:%s input_image.png\n", argv[0]);
      exit (1);
    }

  f = fopen (argv[1], "rb");
  
  image = gdImageCreateFromPng (f);
  w = image->sx;
  h = image->sy;
  fprintf (stderr, "+ Tamaño: %dx%d\n", w, h);
  fclose (f);

  i = 0;
  l = strlen (s);
  for (y = 0; y < h; y++)
    {
      for (x = 0; x < w; x++)
	{
	  rgb = gdImageGetPixel (image, x, y);

	  r = gdImageRed(image, rgb);
	  g = gdImageGreen(image, rgb);
	  b = gdImageBlue(image, rgb);
	  c = (r & 0x03) + ((g & 0x03) << 2) + ((b &0x0f )<< 4);
	  if (c == 0) exit (1);
	  putchar (c);
	}
    }

}

Bueno, no hay mucho que rascar no?. Extraemos las componentes de cada pixel en la imagen y juntamos los bits que nos hacen falta para recomponer nuestro carácter original. Cuando el resultado sea 0, paramos.

Vamos a probarlo.

Gatitos Clandestinos

Como adelantamos al principio, la mejor forma de enviar mensajes esteganográficos clandestinos es utilizando fotos de gatitos... Están hasta en la sopa, así que nadie va a desconfiar de esas fotos con adorables y pizperetas criaturas..

Esta es la que vamos a utilizar nosotros... que mono... ooohh:

Ahora escondamos un mensaje misterioso en la foto de nuestro gatito:

$ ecc el_gatito.png - > el_gatito_clandestino.png
+ Tamaño: 640x480 (Capacidad: 307200 bytes)
Este es un mensaje super clandestino para todos nuestros secuaces
Esta tarde a las 5 birras en el Bar Gas Iosa
^D
+ Codificados 112 bytes de 307200 bytes disponibles (  0.04 % usado)

Esta es la imagen resultado... Podéis descargarla si queréis, y pasar la por el edc, para comprobar que la cosa funciona... Por cierto, nos vemos en el Bar Gas Iosa a eso de las 5. Vale?

Por si alguien tiene alguna duda, la forma de extraer el mensaje clandestino sería algo tal que así:

$ edc el_gatito_clandestino.png
+ Tamaño: 640x480
Este es un mensaje super clandestino para todos nuestros secuaces
Esta tarde a las 5 birras en el Bar Gas Iosa

Se ve que funciona que te pasas... ahora junto con lo que hemos aprendido sobre Servidores Clandestinos ya podríamos escribir un programa super secreto de chat clandestino... Lo llamaríamos: Le Chat Caché.

Detectando Mensajes Clandestinos

Ahora que podemos esconder nuestros mensajes dentro de imágenes, no estaría mal saber como poder averiguar si una imagen contiene algún mensaje oculto. Esto es algo bastante sencillo, cuando el criptoanalista dispone de la imagen original...

En estos casos, la cosa es muy fácil, resta ambas imágenes, y si el resultado no es cero, es que algo hay ahí. Para nuestro ejemplo del gatito de más arriba, podéis probarlo siguiendo los pasos que enumeramos a continuación:

  • Cargad ambas imágenes en GIMP
  • Pegad una sobre la otra como una nueva capa
  • En la lista de modos seleccionar Diferencia
  • Mezclad las capas visibles
  • Seleccionar Ajuste de Curvas de color en el menu Colores
  • Moved la gráfica hacia arriba y... Voilá. Deberíais ver algo como esto

Detectando mensajes clandestinos con GIMP :)... ZOOM al 800% ahí es ná

Como podéis apreciar, toda la imagen es negra, excepto una parte de la primera línea, que, vaya por dios, es justo donde nuestro mensaje clandestino está almacenado.

Pero... y si no tenemos la imagen original?

Detectando y II

Bien, si no tenemos la imagen original las cosas son un poco más complicadas, especialmente si los mensajes son muy cortos en relación con el tamaño de la imagen... lo cual, por otra parte, es un desperdicio de ancho de banda... pero bueno.... somo malos no?

Así que lo que vamos a hacer es generar un fichero con un mensaje de mayor tamaño. Vamos a ocultar a nuestro gatito dentro de otro gatito. El segundo gatito tiene que ser una imagen mucho mayor que la primera. Obviamente.

Debido a que nuestro codificador clandestino es muy cutre y solo funciona con cadenas de texto, convertiremos nuestra imagen en texto para poder codificarla. Base64 al rescate!

$ base64 el_gatito.png | ./ecc el_gatazo.png - > el_gatazo_clandestino.png
$  ./edc el_gatazo_clandestino.png | base64 -d > el_gatito_secreto.png

Ahora, lo que haremos será escribir un sencillo programa que lo que hará será modificar la imagen de forma que los bits más bajos de cada componente de cada pixel (donde almacenamos nuestro mensaje) se copien en los más altos. Vamos estamos amplificando los bits de menor peso de la imagen.

Este sería el código:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gd.h>

int 
main(int argc, char *argv[])
{
  FILE        *f;
  gdImagePtr  image;                                   
  int         i, l, x, y, w, h,k;
  int         size;
  int         rgb, color, r, g, b, cr, cg, cb, c, cnt;

  if (argc < 2)
    {
      fprintf (stderr, "usage:%s input_image.png\n", argv[0]);
      exit (1);
    }

  f = fopen (argv[1], "rb");

  image = gdImageCreateFromPng (f);
  w = image->sx;
  h = image->sy;
  fclose (f);

  for (y = 0; y < h; y++)
    {
      for (x = 0; x < w; x++)
	{
	  /* Get pixel value */
	  rgb = gdImageGetPixel (image, x, y);
	  
	  r = g =b =0;

	  g = ((gdImageGreen(image, rgb)) &0x03) << 6;

	  color = gdTrueColor (0, g, 0);
	  gdImageSetPixel (image, x, y, color);
	}
    }

  gdImagePng (image, stdout);
}

Hemos escogido solo la componente verde por que es la que mejor se ve, y en este caso es suficiente para mostrar lo que queremos.

El Mensaje Clandestino al Descubierto

Vamos allá. Esta el la imagen original del gatazo. Suficientemente grande para poder desparramar a nuestro gatito. Bien!

Cuando pasamos esta imagen por nuestro programa detector vemos algo tal que así:

Pero, si generamos nuestra imagen del gatazo clandestino como os hemos contado más arriba y ejecutamos nuestro programa detector... veríamos algo como esto:

Como podéis ver, hay algo al principio del fichero que parece distinto al resto de la imagen, y que ocupa unos 2/3 de la imagen original. Ahora ya es cosa del pobre hombre que lo esté analizando, el encontrar como sacar lo que sea que está escondido ahí.

Detalles, detalles

Antes de concluir algunos detalles. La técnica que hemos utilizado se conoce como modificación LSB (least significat bit) y que consiste precisamente en modificar los bits más bajos de los pixels (eso no lo esperabais eh?). La idea es que un cambio en esos bits produce una variación de color tan pequeña que el ojo no percibe ninguna diferencia.

Precisamente por que la técnica modifica los bits bajos, amplificarlos (copiarlos en la parte alta), va a poner de manifiesto las diferencias entre la pixels que han sido modificados y los que no. En realidad dependerá de las propiedades estadísticas de ambos grupos de datos, pero en general alguna pista nos dará. Hay otros test más sofisticados, pero no vamos a hablar de ellos en este artículo.

Como os podéis imaginar, esta técnica funciona mejor con imágenes realistas. Imágenes con areas de color plano, como dibujos animados, logotipos, o similares van a hacer más fácil detectar esas variaciones de color, incluso para el ojo desnudo.

Por último, esta técnica, para funcionar, necesita que la imagen se almacene con un formato sin compresión, o con compresión pero sin pérdidas. Formatos de compresión con pérdidas como JPG van a cambiar los colores de los píxeles y por tanto destruir nuestro mensaje oculto.

COLOFON

Un pequeño paso para el genio diabólico, pero un gran paso para la dominación del mundo. Ahora que disponemos de un servidor clandestino, y un sistema de comunicaciones imperceptible para nuestros rivales, podemos controlar nuestra organización clandestina totalmente desde las sombras. Ja, ja, ja! (ruido de trueno)

P.S.: Estamos seguros de que, a partir de ahora, cada vez que veáis una foto de un gatito vais a comprobar si hay algún mensaje secreto oculto en ella... Ja, ja, ja!. La semilla está plantada!... Ja, ja, ja

Descarga el código fuente de este artículo: mensajes_clandestinos.tgz (14392 bytes)


SOBRE Yvil Yenius
Cuando se trata de dominar el mundo, Yvil es la referencia. Su privilegiada mente para el mal y su carisma para ganarse la lealtad de secuaces a diestro y siniestro, la han convertido en una de las más grandes mentes malvadas de la historia. En su tiempo libre, hornea deliciosas tartas que lanzar a sus enemigos.

 
Tu publicidad aquí :)