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.
Ahora escondamos un mensaje misterioso en la foto de nuestro gatito:
Por si alguien tiene alguna duda, la forma de extraer el mensaje clandestino sería algo tal que así:
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?
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í.
■
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:
Creditos WikiMedia: https://commons.wikimedia.org/wiki/File:Gatito-1024x768.jpg
Licencia: CC-BY-SA (https://creativecommons.org/licenses/by-sa4.0/deed.en)
Licencia: CC-BY-SA (https://creativecommons.org/licenses/by-sa4.0/deed.en)
$ 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?

$ 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 IosaSe 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á
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.pngAhora, 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!


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)
■
CLICKS: 2612