Mostrando entradas con la etiqueta Esteganografía. Mostrar todas las entradas
Mostrando entradas con la etiqueta Esteganografía. Mostrar todas las entradas

sábado, 21 de enero de 2012

Esteganografía LSB en imágenes bitmap

Uno de los métodos más populares de Esteganografía consiste en modificar el valor del bit menos significativo de cada píxel, el LSB (Least Significant Bit). En este artículo vemos como hacerlo en imágenes de tipo bitmap, es decir, aquellas que estan estructuradas como matrices de números donde cada número representa un píxel (eso solo es cierto en imágenes en escala de grises. En imágenes en color existen varias representaciones como la RGB donde cada píxel está representado por tres valores, correspondientes a la cantidad de color rojo, la cantidad de color verde y la cantidad de color azul).

El motivo de usar el LSB es que su alteración no sueles ser perceptible visualmente (a menos que la imagen sea muy baja resolución)

Inserción secuencial:

El método más sencillo consiste en separar los bytes que forman el mensaje en bits individuales. A continuación se recorren los píxeles de la imagen modificando su LSB de manera que quede igual que el del mensaje. Supongamos que queremos esconder un mensaje que empieza por 'H'. El valor en binario de la letra 'H' es 1001000. Por lo tanto tendremos que insertar:

1 0 0 1 0 0 0

Imaginemos ahora que los primeros 8 píxeles de la imagen corresponden a los bytes:

100 101 101 102 102 101 103

El primer píxel, correspondiente al valor 100 se representa en binario como 1100100. Dado que tenemos que modificar su LSB y ponerlo a uno, como el primer bit del mensaje, tendremos 1100101, que corresponde al valor de píxel 101. La operación es muy sencilla, si tenemos un valor de píxel par y queremos insertar un cero, no modificaremos el valor del píxel, pero si queremos insertar un uno, le sumaremos uno. Si por el contrario tenemos un píxel impar y queremos insertar un uno, no modificaremos su valor, pero si queremos insertar un cero, le restaremos uno.

Así, el primer byte queda como 101, el segundo como 100, el tercero como 100, etc

101 100 100 103 102 100 102

Para leer el mensaje solo tendremos que extraer los LSB de todos los píxeles.



Inserción aleatoria:

Insertar el mensaje de forma secuencial no es una forma muy acertada de hacerlo. Esto permite al atacante extraer el mensaje, por lo que, si no está cifrado, solo tiene que verificar que es legible (en una imagen sin mensaje oculto no lo sería).

Por este motivo es más aconsejable usar un generador pseudoaleatorio PRNG basado en una clave o contraseña, que eliga aleatoriamente los píxels en los que incrustar datos. De esta manera no bastaría con una simple extracción de todos los LSB.


Reducción del bitrate:

Aún y la enorme dificultad de conseguir el mensaje que ha sido ocultado usando un PRNG (necessitaríamos adivinar la contraseña), el objetivo de la esteganografía es hacer el mensaje indetectable, no indescifrable (de eso se encarga la criptografía). Por ello tenemos que intentar que la distribución estadística de los píxeles de la imagen se vea alterada lo menos posible. Si usamos bitrate 1, es decir, si modificamos todos los píxeles de la imagen, la distribución estadística se verá tan alterada que sermoes detectados sin demasiada dificultad. Por ello es conveniente reducir en la medida de lo posible el bitrate de inserción.

Los ataques existentes en la actualidad a los sistemas LSB son tan sofisticados que detectan alteraciones por encima de bitrates de 0,03. Es decir, que si no queremos ser detectados, deberíamos modificar como mucho el 3% de la imagen y hacerlo de forma aleatoria.



jueves, 19 de enero de 2012

Esteganografía moderna


La primera aparición de la Esteganografía en medios digitales la realizó G. J. Simmons  en 1983 [1]. En el se habla de las posibles implicaciones políticas de enviar datos a través de canales encubiertos y se plantea el problema del prisionero.

El problema del prisionero: 

Alice y Bob son encarcelados en celdas separadas. Pueden comunicarse y quieren planear una fuga, pero sus mensajes son monitorizados por el carcelero Eve. Si Eve descubre que Alice y Bob están intercambiando mensajes secretos no dejará que vuelvan a comunicarse. Por ello, Alice y Bob recurren a la Esteganografía para comunicarse.

En el problema el prisionero hay que destacar que Eve cortará la comunicación si detecta que Alice y Bob se comunican de manera secreta. No es necesario que Eve tenga acceso al mensaje, sólo que lo detecte. Así, un sistema de Esteganografía se considerará roto si puede ser detectada la existencia de un mensaje. No es necesario acceder a su contenido, esto formaría parte del Estegoanálsisis forense (extracción del mensaje) y del criptoanálisis (descifrado del mensaje).


En el problema del prisionero se asume que Eve conoce el algoritmo usado para esconder los datos pero no la clave. Este es un requisito tomado de la Criptografía, que forma parte de los conocidos Principios de Kerchhoff

Referencias: 

[1] G. J. Simmons. The prisoner's problem and the subliminal channel. D. Chaum editor, advances in Criptology, CRYPTO '83, pages 51-67, Santa Barbara, CA, August 22-24, 1983. New York: Plenum Press.

miércoles, 30 de julio de 2008

Esteganografía: El canal Alpha

En este primer artículo sobre esteganografía veremos como ocultar mensajes dentro de una imagen. Para ello usaremos el lenguaje C y accederemos a imágenes en formato PNG a través de la librería libpng.

Para probar los ejemplos es necesario descargar el programa steg.c que he desarrollado y la imagen de Tux que viene a continuación:

NOTA: Haz clic en la imagen para obtener la original, pues blogspot al redimensionar la imagen se carga su transparencia.




El canal Alpha:

Algunos formatos de imágen como puede ser PNG guardan cada píxel en RGBA. Lo que significa que se guarda información para R (cantidad de color rojo), G (cantidad de color verde), B (cantidad de color azul) y A (opacidad de la imagen).

Representar el color de un píxel mediante un formato RGB es algo ampliamente conocido, así que no entraremos en más detalles. Vamos a centrar nos en la A de RGBA, lo que se conoce como el canal Alpha.

El canal alpha contiene la información referente a la opacidad de la imagen, es decir, cuan transparente es.
En PNG, por ejemplo, se usa un byte en cada píxel para el canal alpha, de manera que, si este tiene valor 0, la imagen es completamente transparente, si tiene valor 255 la imagen no tiene transparencia y para valores entre 0 y 255 el nivel de transparecia cambia gradualmente.

Así pues, si un píxel de cierto color RGB tiene el canal alpha a cero, no se verá. Lo que nos permite ocultar datos en los bytes destinados a R, G y B siempre que sea un píxel transparente.


Acceso a la imagen PNG:

En el programa de ejemplo podemos ver dos funciones "read_png()" y "write_png()". No entraremos en detalle sobre estas dos funciones. Basta decir que la primera carga la imagen en las estructuras de datos de libpng y la segunda escribe el contenido de estas estructuras de datos en una nueva imagen.

Por lo tanto el procedimiento a seguir será leer la imagen, realizar las modificaciones pertinentes y escribir de nuevo la imagen.

Para acceder a los diferentes bytes que componen RGBA lo haremos a traves de las funciones "get_value()" y "set_value()". Mientras que la primera nos permite obtener el valor de R, G, B o A, "set_value()" nos permite modificarlo. Así pues:

- get/set_value(x, y, 0, ...) accede al byte que define R
- get/set_value(x, y, 1, ...) accede al byte que define G
- get/set_value(x, y, 2, ...) accede al byte que define B
- get/set_value(x, y, 3, ...) accede al byte que define A



Ocultando un fichero:

Para ocultar un fichero, el programa tendrá que leer cada byte del fichero a ocultar y escribirlo en un píxel de la imagen PNG donde el canal alpha este a cero. Como ejemplo pego parte de la función "hide_file()":

FILE *f = fopen(msg_file, "r");
if(!f)
error("[hide_file] fopen()");

for(y = 0; y < height; y++)
{
for(x = 0; x < width; x++)
{
if(get_value(x, y, 3)==0)
{
char c1=0;
char c2=0;
char c3=0;

if(!feof(f)) c1 = fgetc(f);
if(!feof(f)) c2 = fgetc(f);
if(!feof(f)) c3  = fgetc(f);

set_value(x, y, 0, c1);
set_value(x, y, 1, c2);
set_value(x, y, 2, c3);
}
}
}

fclose(f);



Extraer el fichero oculto:


De manera similar a cómo hemos ocultado el fichero en el apartado anterior, podemos extraer la información oculta. Veamos un pedazo de "unhide_file()":

FILE *f = fopen(msg_file, "w+");
if(!f)
error("[unhide_file] fopen()");

for(y = 0; y < height; y++)
{
for(x = 0; x < width; x++)
{
if(get_value(x, y, 3)==0)
{
char c1 = get_value(x, y, 0);
char c2 = get_value(x, y, 1);
char c3 = get_value(x, y, 2);

if(c1==0 || c2==0 || c3==0)
{
fclose(f);
return;
}

fprintf(f, "%c%c%c", c1, c2, c3);
set_value(x, y, 0, 0);
set_value(x, y, 1, 0);
set_value(x, y, 2, 0);
}
}
}

fclose(f);






Ejemplo de uso del programa:

Visto el código básico utilizado, podemos empezar a ocultar ficheros. Veamos un ejemplo.

Primero ocultamos un mensaje:

$ gcc steg.c -o steg -lpng
$ echo "Esto es un mensaje de ejemplo" > msg.txt
$ ./steg hide tux.png tux_steg.png msg.txt

Si abrimos la imagen tux_steg.png veremos que nuestros ojos no detectan ninguna modificación.

Ahora obtenemos el mensaje oculto:

$ ./steg unhide tux_steg.png tux_clean.png msg2.txt
$ cat msg2.txt
Esto es un mensaje de ejemplo


Un poco de cifrado:

Actualmente el mensaje esta oculto, pero no es difícil extraerlo, por lo que no estaría mal añadir un poco de cifrado. Lo haremos con la herramienta openssl.

Primero ciframos el archivo:

$ openssl enc -blowfish -in msg.txt -out msg.ciph
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:


A continuación lo codificamos en base64 y lo ocultamos:

$ openssl base64 -in msg.ciph -out msg.cb64
$ ./steg hide tux.png tux_steg.png msg.cb64

En este punto podemos verificar que la imagen con el mensaje oculto no muestra información adicional.


Extraemos el mensaje oculto y lo descodificamos en base64:

$ ./steg unhide tux_steg.png tux_clean.png msg2.cb64
$ openssl base64 -d -in msg2.cb64 -out msg2.ciph


Desciframos el archivo:

$ openssl enc -blowfish -d -in msg2.ciph -out msg2.txt
enter bf-cbc decryption password:

y voilà:

$ cat msg2.txt
Esto es un mensaje de ejemplo


Debilidades del sistema:

Ocultar la información en el canal alpha de la imagen no es precisamente la mejor técnica que se puede usar en esteganografía. De hecho tiene un inconveniente importante: la facilidad con la que se puede saber que hay un mensaje oculto.

Por ejemplo, simplemente poniendo el byte del canal alpha a 255, al visualizar la imagen veríamos las zonas de información con píxeles de diferentes colores.

A continuación dejo un ejemplo de la imagen de Tux, con un fichero oculto y con el canal alpha a 255. En ella vemos la existencia de información oculta en la primera mitad de la imagen.




El mensaje está cifrado, por lo que el atacante no podrá acceder a su contenido. Pero sí podrá detectar el uso de esteganografía, lo que no deja al sistema en muy buen lugar:)