Contenido principal

Solución Reto #1: Esteganografía con bit menos significativo

Septiembre 28, 2008

Ya venció el tiempo para entregar la solución del primer reto informático, y nadie envio sus soluciones, así que a continuación publico el ¿cómo? del reto.

Tenemos la siguiente imagen

Como la imagen está conformada por dos colores, pensamos que la solución se debe encontrar no en los colores, sino mirándolo con un editor hexadecimal.
Así que abrimos nuestra imagen con el editor hexadecimal (En mi preferencia Winvi), y vamos hasta el final de la imagen, que según el formato PNG debería ser IEND

Pero si miramos un poco mas arriba hay otro pie de PNG!


E inmediatamente reconocemos la cabecera del PNG, que según el formato es PNG. Relacionamos esta técnica con la descrita en la publicación Analizando JPEG
Entonces con el mismo editor hexadecimal sacamos ese último PNG que está escondido, y obtenemos la siguiente imagen

Demasiado fácil eh?, así que descartamos la posibilidad de que ese PNG oculto en el fichero de la imagen del reto sea la solución.

¿Pero qué nos queda?
Acá entra un término que puede ser nueva para muchos, y es la esteganografía por medio del bit menos significativo.
Las imágenes PNG se dividen en cinco tipos diferente de acuerdo al canal usado
:arrow: Color indexado, cada pixel está asociado a una paleta
:arrow: Escala de grises, al igual que muchos otros formatos de imagen
:arrow: Escala de grises con transparencias
:arrow: Todas las combinaciones posibles con los colores rojo, verde y azul (RGB)
:arrow: Todas las combinaciones posibles con los colores rojo, verde y azul (RGB) con transparencias

Los gráficos soportan una profundidad de color, determinada por el número de bits que hay en cada pixel (2n pixeles, donde n es el número de bits por pixel)
Sigue esta clasificación:
1-bit: 21 colores, color monócromo

2-bit: 22 colores, color usado por las tarjetas CGA

4-bit: 24 colores, color usado por las tarjetas VGA

8-bit: 28 colores, color usado por las tarjetas Super VGA

16-bit: 216 colores, color de alta resolución

24-bit: 224 colores, color verdadero (Donde no podemos diferenciar un color del otro si estos dos estan separados por un valor pequeño)

30/36/48-bit: Son colores usados por métodos que representan un número extremadamente largo de sombras, matices y luminocidades, y consiste en billones de posibles colores.

Entramos entonces a estudiar el formato del archivo PNG (http://www.w3.org/TR/PNG), y vamos directamente a esta sección (http://www.w3.org/TR/PNG/#11IHDR). Allí vemos que en la cabecera IHDR, en el byte número diez (10) se encuentra el tipo de color (0=Escala de grises, 2=Color verdadero, 3=Color indexado, 4=Escala de grises con transparencia, 6=Color verdadero con transparencias). Así que abrimos nuestra imagen, y nos damos cuenta que el tipo de imagen es de color verdadero con transparencias, y recordamos que este tipo de imagen soporta millones de colores. También recordamos que si uno de ellos está en un rango mínimo, no puede ser diferenciado por el ojo humano.

Entonces lo que sigue es obtener el color de los pixeles que veamos que en la imagen son diferentes. Yo lo hago con un programa gratuito para visualizar imágenes llamado Irfanview (http://www.irfanview.com/).
Abrimos la imagen con Irfanview, y damos click sostenido en el fondo, como lo indica la siguiente figura:

Luego hacemos el mismo paso con el color rojo

Ahora que tenemos todos los datos, procedemos a resolver el reto, pero ¿Cómo, si no sabemos lo del bit menos significativo?. Es bastante simple.
Ahora hablabamos de la profundidad de los colores, supongamos que la imagen del reto soporta 224 colores, hablamos de 16777216 colores exactamente. ¿Cómo hace entonces el computador para representar cada pixel?
Cada pixel es representado por una combinación de colores, está combinación está dada por los colores rojo, verde y azul, mas conocidos como RGB.
El rojo, verde y azul representan cada uno 1 byte (8 bits), así que cada uno de estos puede ir desde 00000000 hasta 11111111, lo que representa un total de 256 combinaciones posibles.
R x G x B
256 * 256 * 256 = 16777216
Una equivalencia para los colores más conocidos puede ser esta
Rojo = 255,0,0
Azul = 0,255,0
Verde = 0,0,255
Negro = 0,0,0
Blanco = 255,255,255
Amarillo = 255,255,0
Cyan = 0,255,255
Magenta = 255,0,255

Un ejemplo gráfico de lo que sucede

Ahora, sabemos que cada RGB forma un pixel, y que cada color tiene 256 combinaciones posibles, ¿qué ocurre si del anterior ejemplo variamos el color verde?, y en vez de poner 128, ponemos 129. Observemos que es lo que cambia.

¿Y cuál es la diferencia?

Para el ojo humano no existe diferencia alguna, pero si tomamos los colores con Irfanview, el primer pixel nos muestra un color de RGB(0,128,259) y el segundo de RGB(0,129,258), por lo que para la máquina si existe una diferencia, mínima, pero existe.

¿Y dónde está eso del bit menos significativo?
Si vemos los colores como un número binario tenemos esto:
Primer pixel
R = 00000000
G = 10000000
B = 11111111

Segundo pixel
R = 00000000
G = 10000001
B = 11111111

Lo que hemos hecho entonces, es modificar el bit menos significativo (El bit ubicado en la posición más a la derecha del binario), para poder lograr que la imagen conserve su color para el ojo humano, pero que ciertamente lleva una diferencia.

Aplicándolo al reto, tenemos todos los datos suficientes para lograr sacar las diferencias.
El reto está compuesto solo de dos colores, el negro (0,0,0) y el rojo (255,0,0), y otro que no sabemos cual es.
El siguiente paso para continuar con el reto es desarrollar un script en PHP que haga el trabajo sucio por nosotros.

<?php
// @titulo: Script solucionador reto #1
// @autor: http://www.sinfocol.org
$img   = imagecreatefrompng('reto_muchacho.png'); //Creamos la imagen apartir del archivo
$x     = imagesx($img);
$y     = imagesy($img);
$nueva = imagecreate($x,$y); //Creamos una nueva imagen que almacenará las diferencias

for ($i = 0; $i < $x; $i++) {
    for ($j = 0; $j < $y; $j++) {
        $color = imagecolorsforindex($img, imagecolorat($img, $i, $j));
        //Si el color es igual a blanco o a rojo ponemos un pixel blanco
        //El color de una imagen transparente, como el caso de este reto
        //y que no contiene datos, es representado por el color blanco
        //Con el irfanview se determino que el color era negro pero es
        //Por configuraciones del programa. La librería GD lo interpreta como blanco
        if ($color['red'] == 255 && ($color['blue'] == 255 && $color['green'] == 255 || $color['blue'] == 0 && $color['green'] == 0)) {
            $f = imagecolorexact($nueva, 255, 255, 255);
            imagesetpixel($nueva, $i, $j, $f);
        } else {
            //Si es diferente ponemos un pixel negro
            $f = imagecolorexact($nueva, 0, 0, 0);
            imagesetpixel($nueva, $i, $j, $f);    
        }
    }
}
//Mostramos la imagen con las diferencias
header('Content-Type: image/png');
imagepng($nueva);

La salida de este script es otra imagen

Cabe aclarar, que los puntos negros representan los colores que no son ni rojos ni negros. Efectivamente se estaban ocultando datos en la imagen.
Pero ahora ¿qué hacemos con estos puntos? ¿Los unimos y vemos si forma una casita? No!, lo que hacemos ahora es sobreponer la imagen original, con los puntos y obtenemos lo siguiente

Para finalizar, si observamos cada uno de estos pixeles donde hay diferencia, se posicionan sobre diferentes letras que estan en la imagen original. Si formamos una cadena con cada pixel y su letra respectiva, la frase oculta es: "HOLA mundo célebre" (Sean testigos del primer hola mundo en esteganografía xD)

Aprovecho de paso para resolver el reto planteado en Analizando JPEG
La imagen es esta:

Lo único que hacemos es abrirlo con un editor hexadecimal, localizar el final del archivo jpeg (ffd9), y copiar el contenido que hay de ahí en adelante en un nuevo archivo. La pista nos dice que es un archivo .ico, así que le ponemos la extensión .ico, y la imagen nueva es esta:

El proceso es el mismo explicado en la publicación.

Espero dudas y comentarios acerca del reto!

Archivado en: Esteganografía, Retos informáticos |

26 comentarios

  1. kmykc Septiembre 28, 2008 @ 1:53 pm

    Simplemente me quede sin palabras, me hace falta estudiar demaciado sobre exteganografia y si que es todo un arte, creo que con esto podre ahora si trabajar sobre los retos de algunas paginas que no he podido hacer.

    Aunque debo decir que estuve esperando el 28 para poder ver la solucion, ya que no tenia ni la menor idea de como hacerlo.

    Lo del pequeño reto de la imagen de rammstein solo se trata de sacar la imagen .ico o tambien contiene mensaje subliminal ?

    P.D.: El correo con 5 es el real.

  2. Sysroot Septiembre 28, 2008 @ 5:27 pm

    Con respecto a que la esteganografía es todo un arte, pues estoy de acuerdo, aunque todavía faltan muchas cosas por estudiar.
    La imagen de rammstein solo contenía ese icono.
    Y se me hacía raro el correo con ese cinco :P

  3. Zeratul Septiembre 29, 2008 @ 12:07 am

    feo feo... la verdad un reto feo feo :P

  4. Sysroot Septiembre 29, 2008 @ 5:24 pm

    Feo tú :mad:
    Poco a poco voy subiendo mas cosas para completar la web, voy a ver si coloco a parte una sección de retos, o ya se me ocurrirá algo. Por lo pronto estos retos temporales me parecen una muy buena idea, ya que nadie se va a quedar con la duda de como se resuelve :P

  5. yop Abril 10, 2009 @ 1:21 pm

    Mis conocimientos en cuanto a esteganografía son muy limitados. Aunque he de decir que estudiando acerca del tema me quedo boca abierta...Está interesante si...Pero mi pregunta es: Conocen ustedes algun rincón web o algo del estilo donde poder encontrar más información acerca del tema?..Gracias!

  6. Sysroot Abril 10, 2009 @ 1:31 pm

    La verdad no sé si existe alguna página que se dedique 100% a este tipo de tema, acá podes encontrar varias publicaciones que he hecho acerca del tema, y pienso seguir haciéndolo: http://www.sinfocol.org/category/esteganografia/

  7. hecky Abril 11, 2009 @ 5:40 pm

    Hola grandioso este tutorial, una tremenda felicitacion, sabia algo de esteganografia, peor la verdad que no habia encontrado informacion tan concisa como esta. muchas gracias y felicidades.

    Solo una pregunta...en lo del script como ejecuto eso para que me de la imagan de vuelta??? la verdad no pude hacer eso, agradezco su orientacion...

    Y una cosita mas, usted dice que en el PNG en el byte 10 se especifica el color, pero en la imagen se señala como el byte 26. ahi no entendi...

    Ojala me puedan guiar. Gracias de antemano y un saludo

  8. Sysroot Abril 11, 2009 @ 8:03 pm

    Hola Hecky, el script está realizado en PHP, así que debes disponer de tales ejecutables para poder ejecutarlo, podes descargar PHP de http://www.php.net/downloads.php, descomprimir los ejecutables y ejecutar el binario "php.exe" desde la consola, no necesariamente debes disponer de un servidor web para ejecutar PHP.
    Inicio :arrow: Ejecutar :arrow: cmd
    Te abre una ventana negra, allí copias

    cd c:\ruta_del_php
    

    Y luego ejecutas mi script de esta forma:

    php.exe -f script.php
    

    Con respecto a la duda del bytes 10, me refería a que, los archivos PNG contienen una cabecera llamada IHDR, la estructura de esta cabecera es:

    IHDR
    Width               4 bytes
    Height 	            4 bytes
    Bit depth           1 byte
    Colour type         1 byte
    Compression method  1 byte
    Filter method       1 byte
    Interlace method    1 byte
    

    Los primeros 4 bytes indican el ancho de la imagen, los 4 siguientes indican el alto, los cinco siguientes bytes indican la profundidad del bit, el tipo de color, el método de compresión, el método de filtrado y el método de entrelazado respectivamente.

    Así nuestra imagen tiene los siguientes datos:
    Ancho: 00 00 01 8b = 395 pixeles de ancho
    Alto: 00 00 01 81 = 385 pixeles de alto
    Profundidad del bit = 08
    Tipo de color = 06 (Indica color verdadero con transparencias, es el byte número 10 = 4ncho+4alto+1profunidad+1tipodecolor)
    Método de compresión = 0
    Método de filtrado = 0
    Método de entrelazado = 0

  9. hecky Abril 11, 2009 @ 11:26 pm

    Muchas gracias por la atencion tan pronta ya me a quedado claro todo, la verdad que buenisimos los recursos de aqui, y todo muy bien explicado, aunque me falta todavia para captar algunas cosas en sus otros tutoriales de esteganografia.

    Ojala siga publicando de esteganografia como la de su video de ADS es de lo mas interesante.

    Espero aprender mucho de usted, aunque usted maneja ya universos distantes para mi. XD, si usted kiere considereme como su fiel pupilo...

    Saludos y aqui estare visitando y aprendiendo todos los dias

    Saludos y grax

  10. Sysroot Abril 12, 2009 @ 12:00 am

    Gracias, estoy armando un sitio aparte para colgar todo lo que tengo de esteganografía, y unos videos que subí a youtube y que todavía no los he publicado acá, espero terminarlo pronto.
    Si tienes alguna duda mas, me la comunicas, y seguramente pronto estaremos en contacto.

    Saludos

  11. hecky Abril 12, 2009 @ 2:33 pm

    Woow perfecto, estoy ansioso, la esteganografia me gusta mucho...

    Y estare esperando ansioso,por lo mientras todos sus otros videos de esteganografia ya me los chute...el unico q no le capte muy bien es el de ADS.

    Y pss no sabre mucho de muchas cosas pero si necesita algo, le ayudo. espero estemos en contacto.

    Saludos ;)

  12. hecky Abril 12, 2009 @ 3:56 pm

    Hola disculpa que te moleste otra vez pero tengo un problema.

    Me descargue php, los instale y ya hice lo que me dijiste.

    Abro consola me ubico en php y ejecuto "php.exe -f script.php"

    para esto tu codigo lo copie en block de notas y lo guarde como script.php y eso lo movi a la carpeta de php, asi tambien movi la imagen a la carpeta de php poniendole de nombre a la imagen reto_muchacho.png (asi como esta en el codigo)

    pero al ejecutar "php.exe -f script.php" me salta en consola el siguiete error

    "C:\Program Files\PHP>php.exe -f script.php

    PHP Fatal error: Call to undefined function imagecreatefrompng() in C:\Program
    Files\PHP\script.php on line 4"

    Ojala pueda orientarme por que como yo no se de php :'( no puedo avanzar. espero no estarlo molestando mucho...

  13. Sysroot Abril 13, 2009 @ 3:39 pm

    Tenes que habilitar la librería GD que es la que uso para la esteganografía, lo haces de la siguiente forma:
    Vas a tú consola, te ubicas en el directorio del PHP y escribis

    php.exe --ini
    Configuration File (php.ini) Path: C:\WINDOWS
    Loaded Configuration File:         C:\WINDOWS\php.ini
    Scan for additional .ini files in: (none)
    Additional .ini files parsed:      (none)
    

    Sale algo así, entonces abris con el bloc de notas el archivo de configuración del PHP, el mío por ejemplo se encuentra en "C:\WINDOWS\php.ini", y ubicas las siguientes líneas:

    ...
    ;extension=php_dbase.dll
    ;extension=php_exif.dll
    ;extension=php_fdf.dll
    ;extension=php_gd2.dll
    ...
    

    Por defecto el archivo comprimido de PHP trae todas estas librerías, así que te vas específicamente a la que dice "php_gd2.dll", y eliminas el punto y coma ";" del inicio, quedaría así:

    ...
    ;extension=php_dbase.dll
    ;extension=php_exif.dll
    ;extension=php_fdf.dll
    extension=php_gd2.dll
    ...
    

    Y volves a ejecutar el PHP y no te debería dar ningún tipo de problema.

    Otra observación, mira este código que está en el script:

    header('Content-Type: image/png');
    imagepng($nueva);
    

    Debes comentar la línea que dice "header()", y en la función imagepng agregale el parámetro del nombre del archivo que quieres crear, así:

    //header('Content-Type: image/png');
    imagepng($nueva,'archivonuevo.png');
    

    El header sirve para mandar cabeceras a nuestro navegador, con el fin de que interprete el contenido, en el caso del script con la cabecera "Content-Type: image/png", el navegador interpreta el contenido recibido con "imagepng" como una imagen PNG.

    Comentamos esa línea ya que en la consola no sale nada, y el parámetro sirve para enviar el contenido de la imagen a un archivo, ya que no disponemos de un navegador para visualizar el resultado.

  14. hecky Abril 13, 2009 @ 9:12 pm

    Ohh si ohh yeah!! por fin!!! jeje muchas gracias maestro por contestar todas mis preguntas y enseñarme...se lo agradezco, ahora ya solo queda de mi tratar de aprender php y ver como funciona el script....grax.......de vdd se lo agradezco por esta grandiosa clase...

  15. YOP Abril 14, 2009 @ 4:11 pm

    Perdonad!!He estado un poco ausente estos dias...Gracias por el tutorial!Le echaré un vistazo ahora mismo.Ya te comentaré que tal.Mil gracias!

  16. hecky Mayo 13, 2009 @ 1:05 am

    Hola maestro de nuevo a molestarlo...pss ya ve usted me a estado ayudando con todas estas cosa pero ahora me entro una duda.

    Como hizo este reto???

    Me supongo que hizo un script para hacerlo asi como un script se uso para resolverlo...

    podria sacarme de esa duda y publicar el script (si asi lo hizo)

    Y en todo caso que se tomo en cuenta para el script??
    .-El tamaño de la imagen??
    .-Como hizo para que esos puntos negros estuvieran exactamente sobre esas letras???

    Yo siempre e leido sobre LSB y como en que consiste y e visto algunos scripts para analizar los colores RGB pero jamas e visto la manera encomo lo hacen?? como hacer la tecnica LSB??

    Saludos y disculpe la curiosidad.

  17. Fabricando retos parte 1 | Seguridad Informática Colombiana Julio 6, 2009 @ 4:14 am

    [...] el problema que plantea el reto y su solución, te recomiendo que le eches un vistazo en este link: Solución Reto #1: Esteganografía con bit menos significativo (Esta lectura es esencial para entender el fundamento de la esteganografía con bit menos [...]

  18. Explicación de los valores retornados por imagecolorat() | Seguridad Informática Colombiana Septiembre 21, 2009 @ 2:00 am

    [...] valores y el porque de esas operaciones binarias. Como escribía en una publicación anterior (http://www.sinfocol.org/2008/09/solucion-reto-1-esteganografia-con-bit-menos-significativo/), para representar el color en un pixel del monitor, se usan tres posibles valores, los cuales son [...]

  19. Rosario Enero 3, 2010 @ 11:05 am

    Está muy bueno.. yo soy media bruta, pero me di cuenta simplemente pintando las letras rojas con blanco en paint si te fijas se pinta toda la letra menos un puntito debajo de la letra :)

  20. Sysroot Enero 3, 2010 @ 5:12 pm

    :D así es, una forma mas sencilla de hacer el reto es pintar cada letra de otro color, el programa automáticamente detecta el color proximo a pintar, y si es diferente entonces para.
    La ventaja de la forma que propones es la sencillez, y la ventaja de la forma que yo propongo es la automatización, así que cualquier método es válido.

  21. leo Febrero 23, 2010 @ 10:50 pm

    hla necesito todo acerca del Método del Bit Menos Significativo. LSB. y de la Trasformada discreta del coseno (DCT).

  22. JuanEscobar.org » Esteganografía Media: Tutorial Least significant bit (LSB) en PNG Julio 24, 2010 @ 11:25 am

    [...] http://www.sinfocol.org/2008/09/solucion-reto-1-esteganografia-con-bit-menos-significativo/ http://www.sinfocol.org/2009/09/explicacion-de-los-valores-retornados-por-imagecolorat/ r {color: [...]

  23. Videotutorial de Esteganografía con LSB en una imagen PNG | Parte 1 | blog Marzo 27, 2011 @ 2:37 am

    [...] http://www.sinfocol.org/2008/09/solucion-reto-1-esteganografia-con-bit-menos-significativo/ [...]

  24. Xornor Enero 9, 2012 @ 4:30 pm

    Cordial Saludo.

    Para aprender cual es el camino inicial?, que es lo mas básico, para poder ir incrementando en el conocimiento?

    Gracias,

  25. ganjacs Mayo 6, 2012 @ 11:48 pm

    Hola soy nuevo en este mundo de la esteganografía y me encontré con este fabuloso sitio que me dejo muy en claro algunos conceptos que tenía en duda , ademas con la claridad que explicas las cosas y la paciencia que se tiene para responder las preguntas de los lectores no tiene precio , espero que se sigan compartiendo estos tipos de conocimientos y experiencia para aumentar el crecimiento en este arte.

    Saludos!

  26. DR3-K4N Julio 5, 2012 @ 1:25 pm

    Woow.. La verdad que yo soy completamente nuevo en el tema, y no tenia idea de lo que la esteganografia era.. me ha impactado tu explicacion y lo complejo que era la solucion(comparado con lo que tenia en mente jaja..)

    Que buena tu pagina, seguire pendiente de lo que saques a ver que aprendo :) ..

Deja un comentario