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:)


sábado, 26 de julio de 2008

Criptograma Semanal 26/07/08


NE XEGQUWE HR NEB WHREB OAPHEXRPLENRB HR NE CWRPCWE BQP RBRPCWENXRPLR BRPCWNNEB G, ZQU URSNE SRPRUEN ZARHRP BRU RVZURBEHEB RP AP NRPSAEIR CQXZURPBWDNR ZEUE LQHQB.

ENDRUL RWPBLRWP

jueves, 24 de julio de 2008

Superado bsgame#1 de Blind Security

El 1 de Julio Blind Security empezaba el I Torneo de Seguridad Informática BlindSec.

Despues de varias intentonas y de encallarme considerablemente en los niveles 9 y 10 he superado el bsgame#1 entre los 10 primeros, lo que me hace ganador de una bonita camiseta ;)

A todo el que le guste romperse el coco con retos informáticos y quiera aprender, le recomiendo encarecidamente que lo intente, dado que el reto continuará abierto.

A mi me ha servido, entre otras cosas, como perfecta excusa para entrar en el terreno de la esteganografía. De hecho, tan pronto como el torneo sea superado (10 finalistas) publicaré un artículo sobre el tema a partir de algunos programas que desarrollé para pasar el nivel 9.





Insisto, si te gusta la seguridad informática y el hacking ético, no lo dudes, pásate por el torneo.

domingo, 20 de julio de 2008

Los cifrados de Feynman

El conocido físico Richard Feynman recibió tres mensajes codificados de los científicos de Los Alamos, y después de no poder descifrarlos el mismo, los compartió con sus alumnos de Caltech. Actualmente solo se ha conseguido descifrar el primero de los mensages.

Los tres mensajes cifrados son:
1. Easier
MEOTAIHSIBRTEWDGLGKNLANEA
INOEEPEYSTNPEUOOEHRONLTIR
OSDHEOTNPHGAAETOHSZOTTENT
KEPADLYPHEODOWCFORRRNLCUE
EEEOPGMRLHNNDFTOENEALKEHH
EATTHNMESCNSHIRAETDAHLHEM
TETRFSWEDOEOENEGFHETAEDGH
RLNNGOAAEOCMTURRSLTDIDORE
HNHEHNAYVTIERHEENECTRNVIO
UOEHOTRNWSAYIFSNSHOEMRTRR
EUAUUHOHOOHCDCHTEEISEVRLS
KLIHIIAPCHRHSIHPSNWTOIISI
SHHNWEMTIEYAFELNRENLEERYI
PHBEROTEVPHNTYATIERTIHEEA
WTWVHTASETHHSDNGEIEAYNHHH
NNHTW

2. Harder
XUKEXWSLZJUAXUNKIGWFSOZRAWURO
RKXAOSLHROBXBTKCMUWDVPTFBLMKE
FVWMUXTVTWUIDDJVZKBRMCWOIWYDX
MLUFPVSHAGSVWUFWORCWUIDUJCNVT
TBERTUNOJUZHVTWKORSVRZSVVFSQX
OCMUWPYTRLGBMCYPOJCLRIYTVFCCM
UWUFPOXCNMCIWMSKPXEDLYIQKDJWI
WCJUMVRCJUMVRKXWURKPSEEIWZVXU
LEIOETOOFWKBIUXPXUGOWLFPWUSCH

3. New Message
WURVFXGJYTHEIZXSQXOBGSV
RUDOOJXATBKTARVIXPYTMYA
BMVUFXPXKUJVPLSDVTGNGOS
IGLWURPKFCVGELLRNNGLPYT
FVTPXAJOSCWRODORWNWSICL
FKEMOTGJYCRRAOJVNTODVMN
SQIVICRBICRUDCSKXYPDMDR
OJUZICRVFWXIFPXIVVIEPYT
DOIAVRBOOXWRAKPSZXTZKVR
OSWCRCFVEESOLWKTOBXAUXV
B

Veamos como resolver el primero de los mensajes.
Se trata de un cifrado de transposición, el cual colocaremos en grupos de cinco letras:

M E O T A
I H S I B
R T E W D
G L G K N
L A N E A
I N O E E
P E Y S T
N P E U O
O E H R O
N L T I R
O S D H E
O T N P H
G A A E T
O H S Z O
T T E N T
K E P A D
L Y P H E
O D O W C
F O R R R
N L C U E
E E E O P
G M R L H
N N D F T
O E N E A
L K E H H
E A T T H
N M E S C
N S H I R
A E T D A
H L H E M
T E T R F
S W E D O
E O E N E
G F H E T
A E D G H
R L N N G
O A A E O
C M T U R
R S L T D
I D O R E
H N H E H
N A Y V T
I E R H E
E N E C T
R N V I O
U O E H O
T R N W S
A Y I F S
N S H O E
M R T R R
E U A U U
H O H O O
H C D C H
T E E I S
E V R L S
K L I H I
I A P C H
R H S I H
P S N W T
O I I S I
S H H N W
E M T I E
Y A F E L
N R E N L
E E R Y I
P H B E R
O T E V P
H N T Y A
T I E R T
I H E E A
W T W V H
T A S E T
H H S D N
G E I E A
Y N H H H
N N H T W


Ahora podemos leer el mensaje de abajo a arriba empezando por el final.

El mensaje resultante es:

Whan that Aprill, with his shoures soote
The droghte of March hath perced to the roote
And bathed every veyne in swich licour,
Of which vertu engendred is the flour;
Whan Zephirus eek with his sweete breeth
Inspired hath in every holt and heeth
The tendre croppes, and the yonge sonne
Hath in the Ram his halfe cours yronne,
And smale foweles maken melodye,
That slepen al the nyght with open eye-
(So priketh hem Nature in hir corages);
Thanne longen folk to goon on pilgrimag


.