miércoles, 6 de agosto de 2014

Esteganografía del bit menos significativo [LSB] Parte I

Buen día.

Disculpad nuestra ausencia y aparente desarraigo de este mundo, el mundo que nos vio nacer, el mundo informático, pero resulta que por estas fechas hemos estado un poco ocupados, pues tenemos diferentes compromisos personales ya sea universidad, trabajo, proyectos y un gran etc...

Hoy por hoy y con muchos temas en los que investigar, vamos a hacer una introducción a la esteganografía y con ello, a la técnica del bit menos significativo (LSB -> Least Significant Bit), y pues, como ya lo imaginaron, también haremos nuestra propia tool en Python para poder realizar esto.


¿Qué es Esteganografía?



Durante los inicios de este blog hemos hablado mucho acerca de Criptografía, la cual nos brinda distintas técnicas para poder cifrar mensajes y dejarlos inteligibles a menos que se apliquen métodos especiales y en algunos casos también aplicando cierta clave secreta; la criptografía nos brinda la seguridad de que una persona externa no pueda entender o tener acceso a la información ya cifrada, pero eso no significa que el atacante no sepa de su existencia, me explico:


Si a nuestras manos cae un mensaje que aparentemente no tiene sentido alguno y que esta compuesto de muchos caracteres desorganizados, según el contexto en el que estemos, podemos intuir fácilmente que se trata de un texto cifrado y aunque no sepamos descifrarlo, al saber que el mensaje existe podemos intentar muchas técnicas para poder recuperar el mensaje original, así que la seguridad depende esencialmente del cifrado utilizado (seguridad basada en matemáticas o nivel de procesamiento) pues muchas personas se darán cuenta de su existencia. Ahora, por el contrario tenemos la esteganografía, ella se encarga no de cifrar la información sino de ocultarla a la vista de las personas, así nuestros mensajes pasarán desapercibidos por las manos de los atacantes o espías y ellos no se enterarán de su existencia; por tanto, nadie puede atacar algo que no sabe que existe o que no puede percibir.

  • Se encarga de que nadie se entere de la existencia de la información.
  • ¿De qué secreto me hablas?, aquí no hay nada.
  • Imágenes
  • Audio
  • Vídeos
  • Log's de red
  • Documentos
  • Etc..

Después de todos estos puntos anteriormente mencionados, es importante recalcar que cada uno de ellos, ya sea una imagen, un audio, un vídeo, un documento, etc... tiene una representación en un estándar ya definido, del cual encontraremos información en los protocolos y formatos de Internet, con los que podemos obtener mucha más información de cada archivo según su composición, lo cual desemboca en muchas técnicas más de Esteganografía que trataremos en artículos posteriores. Para nuestro caso puntual de la técnica LSB es necesario tener presente que todo en nuestro computador funciona muy internamente como una combinación de unos (1) y ceros (0), lo cual es definido como sistema binario y hago especial énfasis a esto, dado que trabajaremos sobre ellos.

  • Bit ---> Es la mínima expresión que representa información, en este caso cero (0) ó uno (1).
  • Byte ---> Es la unidad estándar de información, consta de 8 bit's (00000001).

Hoy trabajaremos exclusivamente en imágenes, los demás tópicos los trataremos más adelante en posteriores publicaciones, así que les explicaré un poco el cómo están hechas las imágenes y cómo podemos empezar a tratarlas con un lenguaje de programación.


Una imagen esta conformada por píxeles (pixel: picture element), la combinación de dichos píxeles es lo que le da color y forma a la imagen terminada, como lo podemos observar, cuando le hacemos mucho zoom a una imagen, generalmente vamos a encontrarnos con que todo esta conformado por pequeños cuadritos y son estos a los que nosotros llamamos píxeles, pues son la unidad mínima de representación para una imagen.


¿Pero de qué están hechos los Píxeles?



Un píxel esta conformado por una tripleta de datos que seguramente muchos han escuchado, algo muy conocido como RGB (Red, Green, Blue), esta tripleta de datos es la que conforman el color final del píxel, por ejemplo, los tres colores se mezclan en diferentes proporciones generando distintos colores:

Como podemos observar, distintas combinaciones en RGB generan distintos tipos de colores, unos muy diferentes y otros muy parecidos. El rango de cambió en los valores RGB es de 0 a 255 para cada valor, entonces podemos ver a un píxel como un vaso donde mezclamos pintura, pero donde solo tenemos 3 tipos de pinturas primarias, la roja, la verde y la azul, al mezclar en el vaso distintas proporciones de esos colores vamos a obtener toda una paleta de colores, por ejemplo, el color blanco como todos sabemos (efecto del prisma) esta compuesto de todos los colores, por ende en RGB se consigue con la tripleta (255, 255, 255) y en contraposición, el color negro es la ausencia de color o de luz, en este caso se forma con la mezcla de (0,0,0).

Una vez entendida esta parte, es momento de centrarnos un poco más en las imágenes, pues veremos que manipular o al menos ir recorriendo la información de la imagen es algo muy intuitivo pues esta relacionado con muchas cosas de nuestro diario vivir. Como ustedes saben, el hombre en su infinita sabiduría (y estupidez) siempre trata de etiquetar las cosas y también trata de ajustar todo a un marco de referencia estándar con el cual todos puedan trabajar sin problema alguno, y esto ocurre en el tema de las imágenes, ellas están sujetas a un marco de referencia, en este caso es el más conocido de todos, el plano cartesiano (por sus coordenadas tanto en el eje x como en el eje y).

Como podemos observar, cada cuadrito blanco y negro representa un píxel y con ello esta sujeto a una coordenada con la cual podemos acceder a los valor RGB de dicho píxel. Es importante notar que la coordenada (0,0) osea la coordenada inicial, esta en la esquina superior izquierda, pues allí es donde comienza toda la imagen.

Con el marco de referencia bien definido podemos empezar a jugar con diferentes cosas, pues no solo podemos ver la imagen como píxeles formados por RGB, sino que la podemos empezar a ver como una matriz, en la cual podemos decir por ejemplo, de la imagen tal, quiero ver el pixel de la posición (2,2), entonces como nuestra imagen es una matriz, vamos a buscar la posición (2,2), lo cual nos daría el centro de la imagen (en el ejemplo), un píxel blanco formado por (255, 255, 255). Ahora ustedes ya se imaginaran un poco como funciona esto, solo es dar una coordenada y recibimos la tripleta RGB asociada a dicho píxel. (en publicaciones anteriores se hablar de matrices y arreglos bidimensionales).

Bueno, creo que hasta aquí llegan las bases para poder entender todo lo demás y hago la aclaración de que esto solamente es lo básico, pues si ustedes desean profundizar tanto en procesamiento de imágenes como en recolección de información de las misma, es muy recomendado que se lean la información estándar de cada formato, pues para cada tipo de imagen (.PNG - .JPG - .GIF - .BMP) hay ciertos criterios, ya sea con la información en forma de píxel, con la información hexadecimal o con los sublimes metadatos.


Mucho blablabla y poca acción, ¿Donde están mis bit's menos significativos?.



Ahora sí vamos a hacer la introducción al tema :)... Como ustedes ya saben, todo en el ámbito de la informática aunque aparentemente se rige por estructuras y estándares, al final todo se convierte en una sola cosa, en unos (1) o en ceros (0) y es este principio el que vamos a usar para el bit menos significativo. Resulta pasa y acontece qué el ojo humano aunque es una de las grandes maravillas de la existencia, tiene cierta falencia o deficiencia respecto al sistema de representación digital de colores, pues nuestros ojos matizan casi todos los colores y para nosotros es muy complicado el poder identificar cambios leves en tonalidades de colores muy similares, cosa que con la representación digital se puede lograr fácilmente, por tanto podemos realizar pequeños y precisos cambios a los colores en forma digital tal que nuestros ojos no podrían detectar (he aquí la esteganografía).

NOTAS:
  1. Vamos a trabajar a nivel binario.
  2. Cada carácter esta conformado por 8 Bit's (1 Byte).

:/ ¿y de qué me sirve esconder tonalidades de colores? 

Como les había dicho, en ultima instancia todo se convierte en unos (1) o en ceros (0), entonces presten atención a la simpleza de esta técnica; al pasar por cada pixel obtenemos una tripleta RGB compuesta por números enteros desde el cero (0) hasta el (255), y como cada número tiene su propia representación en binario, lo que haremos será convertir dicha tripleta en su equivalente en binario, por ejemplo, el pixel conformado por (148, 28, 202) equivale en binario a (10010100, 00011100, 11001010).

Ahora lo que hacemos es editar el bit menos significativo, osea aquel que se encuentre de último a la derecha, como pueden observar en la imagen los hemos resaltado en color rojo y sí se fijan bien también verán la explicación de por qué es el bit menos significativo, debajo en la columna LSB hemos alterado los bits (en rojo) pero los demás siguen intactos y el resultado de la tripleta RGB sufre algunos cambios, pero son mínimos. Si se fijan cuidadosamente en ambos colores es muy improbable que hallen algún tipo de diferencia visual pero en realidad hubo un cambio, después de alterar el bit menos significativo, la tripleta RGB es distinta de la que teníamos al inicio, pero el color aparentemente es el mismo (He ahí la belleza del LSB!!).. podemos alterar la información y enviarla sin que un atacante pueda percatarse de que hay algo extraño.

Todo es unos y ceros!! y podemos hacer que el LSB siga la secuencia que nosotros deseemos, por ejemplo, si deseamos esconder la palabra "Hacking" tenemos que recordar que cada letra (caracter) se puede representar por un Byte siendo así la "H"= 01001000 entonces si tenemos 3 pixeles podemos esconder esa secuencia mediante LSB.


Como cada pixel tiene tres valores que lo componen y en cada uno solo podemos alterar un bit, entonces son necesarios 3 pixeles para poder esconder la letra "H", pues su representación en binario corresponde a 8 bit's. La tabla antes presentada es muy intuitiva, pues lo que hacemos es obtener 3 pixeles de la imagen original sacamos sus respectivos RGB y como deseamos esconder la letra "H" en binario, simplemente reemplazamos los bit's menos significativos en el orden de la "H" y volvemos a reconstruir nuevamente los 3 pixeles, solo que ahora como escondimos una letra en ellos, sus valores han cambiado pero como lo habíamos dicho antes, ningún cambio perceptible al ojo humano.

De esta forma podemos esconder no solo texto sino también todo tipo de información, pues todo es representable en valores binarios; la manera de recuperar la información es solo recibir la imagen alterada y empezar a leer los bit's menos significativos, pues cada 8 bit's tenemos la representación de un carácter.


¿Y cómo lo podría realizar ?



En Python existen varias librerías que nos permite la manipulación de imágenes y gráficos, entre ellas tenemos la más popular, la librería PIL (Python Image Library) la cual nos permite trabajar con todo tipo de imágenes en su forma más elemental, tal como lo es la representación matricial de todos los pixeles que la conforman; como lo habíamos dicho anteriormente con el ejemplo de las coordenadas, las imágenes funcionan exactamente igual y lo que haremos con PIL será extraer dicha matriz y manejarla a nuestro gusto. (Pueden descargar la librería desde aquí http://www.pythonware.com/products/pil/ )





El uso de la clase Image de la librería PIL es muy intuitivo, pues solo nos pide que asignemos una imagen para abrir y después de ello, hay muchos métodos que nos facilitan las cosas, como podemos observar, podemos saber el tamaño en pixeles de la imagen y también mucha otra información, como su nombre, su última edición, profundidad de pixeles, etc... Algo curioso que nos permite la librería PIL es el hecho de que aunque podemos acceder a toda la clase Image, este no nos permite editar directamente la imagen, por lo tanto utilizamos:

>>>pix = img.load()

Lo que hace es que crea una copia de la imagen original, y nos permite acceder a la matriz de pixeles, en el caso de la imagen, nosotros quisimos saber la tripla RGB del pixel ubicado en [0,0] de forma que si editamos la posición [ x , y ] podemos acceder a cualquier pixel de la imagen y lo podemos editar.

------------------------------------
Por cuestiones de tiempo y eficiencia, hasta aquí llega la primera parte de la publicación, más adelante estaremos explicando el funcionamiento explicito de la tool que hemos desarrollado para LSB, esperen nuestra segunda parte (más acerca del funcionamiento de PIL, LSB y StegoLSB.py)
----------------------------------- 

StegoLSB.py

 

Esta herramienta nos permite realizar la técnica LSB en imágenes, con la cual podemos ocultar textos (y otras cosas) en los bits menos significativos de la imagen, la hemos hecho netamente en sentido académico pues la explicación de la misma, se llevará acabo a lo largo de varias publicaciones y talleres, por tanto no nos hacemos responsables del uso que le puedan dar. (descargar aquí)

https://github.com/D14M4NT3/StegoLSB.py

El funcionamiento del StegoLSB.py es muy sencillo, por el momento podemos esconder textos dentro de las imagenes y también podemos realizar el caso inverso, a partir de una imagen con un secreto, podemos recuperarlo.

Ocultar Información:
example.png : es la imagen donde se ocultara el secreto
secret.txt : es el mensaje que queremos incrustar en la imagen
>>>python StegoLSB.py -i example.png -l secret.txt  

Extraer Información:
image.png : es la imagen con el texto oculto, con la opción -x se revela
>>>python StegoLSB.py -x -i image.png

===============
Nos pueden dejar cualquier duda, sugerencia o petición, la atenderemos a la brevedad posible.
Bytez 

3 comentarios: