Contenido principal

Ethernet II framing + Internet Protocol V4 + Esteganografía en ICMP Echo combinado con Criptografía

Abril 6, 2009

"El Protocolo Internet (IP) [1] se utiliza para el servicio de datagramas de "host" a "host" en un sistema de redes interconectadas denominado Catenet [2]. Los dispositivos de conexión de redes se denominan Pasarelas (Gateways). Estas pasarelas se comunican entre ellas con propósito de control mediante el Protocolo Pasarela a Pasarela (Gateway to Gateway Protocol (GGP)) [3,4]. Ocasionalmente, una pasarela o un "host" de destino se comunicará con un "host" de origen para, por ejemplo, informar de un error en el procesamiento de datagramas. El Protocolo de Mensajes de Control Internet (ICMP) se usa para este propósito. ICMP utiliza el soporte básico de IP como si se tratara de un protocolo de nivel superior. Sin embargo, ICMP es realmente una parte integrante de IP, y debe ser implementado por todo módulo IP.

Los mensajes ICMP son enviados en varias situaciones: por ejemplo, cuando un datagrama no puede alcanzar su destino, cuando una pasarela no dispone de capacidad de almacenamiento temporal para reenviar el datagrama, y cuando la pasarela puede dirigir al "host" para enviar el tráfico por una ruta más corta." RFC0972

El propósito de este protocolo como es mencionado en el mismo RFC, es "suministrar información sobre los problemas en el entorno de comunicación", para cumplir tal función dispone de once tipos de mensajes:
:arrow: Eco
:arrow: Eco de respuesta
:arrow: Destino inaccesible
:arrow: Disminución del tráfico desde el origen
:arrow: Redirección
:arrow: Tiempo superado
:arrow: Problema de parámetros
:arrow: Marca de tiempo
:arrow: Respuesta de marca de tiempo
:arrow: Solicitud de información
:arrow: Respuesta de información

Para el propósito de hoy, nos centraremos en el tipo de mensaje Eco, comúnmente llamado "ping".
La siguiente imagen contiene la traza generada por el Script PHP que se encuentra al final de la publicación:

La imagen se compone de tres partes que podemos diferenciar por su color.
En el ejemplo, se envia por medio del mensaje Eco un texto cifrado a mi router identificado con la IP 192.168.1.255 y MAC 00:14:7f:32:31:ee


Ethernet II framing: en verde


Este protocolo es usado en este caso porque los datos se están enviando a través de una red LAN
Se compone de cuatro subpartes
:arrow: Destination MAC Address, es la dirección de control de acceso del destino (00:14:7f:32:31:ee)
:arrow: Source MAC Address, es la dirección de control de acceso de la fuente (00:11:22:33:44:55)
:arrow: EtherType, indica que protocolo está encapsulado en los datos, 0x0800 se refiere al protocolo de internet versión 4 (IPv4)
:arrow: Datos, datagramas del protocolo de internet (IPv4) que a su vez contiene el protocolo ICMP (Varia de 46 a 1500 bytes, por lo que no podemos excedernos de tal tamaño)


Protocolo de internet (IPv4): en roj0


Identificamos en la cabecera de este protocolo (La cabecera está subrayada con amarillo) los siguientes elementos:

Versión y longitud de la cabecera: Se almacenan en el primer byte, de la siguiente forma:
:arrow: bits 0,1,2,3 contiene la versión, en este caso 4, referente a IPv4
:arrow: bits 4,5,6,7 contiene la longitud de la cabecera, en este caso 5 para una longitud total de 20 bytes.

Convirtamos a binario el primer byte de la cabecera IP
45 -> bin -> 01000101
Los cuatro primeros bits indican la versión IP
0100 -> decimal -> 4
Los cuatro siguientes bits indican la longitud de la cabecera (Subrayada en amarillo)
0101 -> decimal -> 5
"IHL: 4 bits
Longitud de la Cabecera Internet (Internet Header Length), es la longitud de la cabecera en palabras de 32 bits, y por tanto apunta al comienzo de los datos. Nótese que el valor mínimo para una cabecera correcta es 5."
La explicación del RFC quiere decir, cada bit en el IHL representa 32 bits, así que para obtener la longitud en decimal debemos multiplicar el decimal obtenido ("5"), por 32 bits y luego dividirlo por 8 bits.
(5*32)/8 = 20 bytes

Tipo de servicio: 1 byte (Indica la prioridad y calidad del servicio)

Bits 0-2:  Prioridad.
Bit    3:  0 = Demora Normal,       1 = Baja Demora.
Bit    4:  0 = Rendimiento Normal , 1 = Alto rendimiento.
Bit    5:  0 = Fiabilidad Normal ,  1 = Alta fiabilidad.]
Bits 6-7:  Reservado para uso futuro (Este reservado se ve interesante)

En nuestro caso, este byte es nulo, así que: Conexión rutinaria, demora normal, rendimiento normal, y fiabilidad normal.

Longitud total: 2 bytes (La suma del IHL mas los datos "Protocolo ICMP")
Vemos en el ejemplo "00 44", que equivale en decimal 68 bytes. 20 bytes del IHL + 48 bytes del protocolo ICMP

Identificación: 2 bytes (Ayuda en el reensamblaje de los fragmentos)
Tenemos la identificación "f1 90", en decimal 61840

Flags + Posición del fragmento: 2 bytes
:arrow: flags de 3 bits
:arrow: posición del fragmento de 13 bits
Ambos nulos

Tiempo de vida: 1 byte (Tiempo en segundos que permanece el datagrama con vida
80 hexadecimal, 128 decimal, 128 segundos con vida.

Protocolo: 1 bytes (Indica el protocolo a usar en el campo de los datos)
1 = Protocolo ICMP
6 = Protocolo TCP
17 = Protocolo UDP
Solo por mencionar, existen muchos protocolos aún sin explorar, la lista se puede encontrar ACÁ

La suma de control: 2 bytes (Para verificar que los datos enviados no estén corruptos)
Se usa la misma suma de control para el protocolo ICMP, en el script al final de la publicación está una función que calcula la suma de control. La suma de control se hace sobre la cabecera unicamente, y no sobre la cabecera y los datos.
"c4 d7", podemos verificar el valor utilizando la función y un script en php

<?php
//Función checksum: es el complemento a uno de 16 bits de la suma de los complementos a uno de todas las palabras de 16 bits únicamente de la cabecera.
echo Checksum16bits("\x45\x00\x00\x44\xf1\x90\x00\x00\x80\x01\x00\x00\xc0\xa8\x01\x01\xc0\xa8\x01\xff");
?>

Observamos entonces que el resultado es Ä×, por lo tanto la cabecera es íntegra.

La dirección de origen: 4 bytes (Representa la dirección IP de origen)
En el caso del ejemplo, tenemos "c0 a8 01 01", lo único que debemos hacer es convertir cada byte hexadecimal a byte decimal
c0 -> decimal -> 192
a8 -> decimal -> 168
01 -> decimal -> 01
01 -> decimal -> 01
Por lo tanto la IP de origen (Mi PC), es 192.168.1.1

La dirección de destino: 4 bytes (Representa la dirección IP de destino, donde se desea enviar los datos)
Repetimos el mismo paso anterior, convertimos cada byte a su respectivo decimal:
c0 -> decimal -> 192
a8 -> decimal -> 168
01 -> decimal -> 1
ff -> decimal -> 255
Quedaría que la IP de mi router es 192.168.1.255, como lo había indicado al iniciar la explicación de las cabeceras.

Y por último y no menos importante, los datos enviados, los cuales están pintados en azul y hacen referencia al procolo ICMP. Donde ocultaremos la información, y es en este protocolo precisamente donde entra a jugar la esteganografía combinada con un poco de criptografía.


Protocolo ICMP: en azul


Llegamos a la última parte, este protocolo se compone al igual que los dos anteriores, de una cabecera y una descripción.
La cabecera se compone de:
Tipo (1 byte): Como tratamos mensajes Eco, el tipo debe ser 8 para hacer la petición (Echo) o 0 para responder a una petición (Echo Reply).
Código (1 byte): Siempre será nulo.
Suma de control (2 bytes): Se calcula para la cabecera de este protocolo y los datos a enviar, teniendo como checksum valores nulos.
Identificador (2 bytes) + Número de secuencia (2 bytes): Si código = 0, se usan "como referencia para emparejar ecos y respuestas, que puede ser cero."

Y la descripción que son los datos que luego serán recibidos exactamente como se mandaron.

Por lo tanto vemos que Ethernet II framing contiene el protocolo IPv4, que a su vez contiene el protocolo ICMP, como se muestra en el siguiente esquema:

Cabecera Ethernet II framing
Datos = Cabecera IPv4
        Datos = Cabecera ICMP
                Texto cifrado


Esteganografía con Internet Control Message Protocol + Un poco de criptografía


Con lo anteriormente aprendido, podemos concluir que dos de las cinco cabeceras utilizadas en el protocolo ICMP, tienen uso en otros tipos de mensaje, pero en este no tienen mucha importancia (Estamos hablando del identificador y el número de sucuencia), y por supuesto la descripción, la cual puede contener datos aleatorios. (Donde se almacenará el texto cifrado)

Lo que haremos será, generar una clave aleatoria de cuatro bytes (dos bytes almacenados en el identificador y los otros dos en el número de secuencia), y con esta clave aplicaremos un XOR a un texto en limpio.

Acá es donde entra en juego la criptografía, el método es sencillo, aplicamos un XOR a cada letra del texto plano con cada letra de la clave. Un ejemplo no vendría mal.

Elegimos un texto en plano: "anita lava la tina y pepito le clava un clavito en la cabeza al calvito"
Elegimos una clave: "hola"

Lo siguiente es armar una tabla como la siguiente:
anita lava la tina y pepito le clava un clavito en la cabeza al calvito
holaholaholaholaholaholaholaholaholaholaholaholaholaholaholaholaholahol

El siguiente paso es aplicar el xor recorriendo el texto, el texto cifrado sería entonces de la misma longitud del texto en plano:
(Códigos dados en hexadecimal)
a xor h = 61 xor 68 = 09
n xor o = 6e xor 6f = 01
i xor l = 69 xor 6c = 05
t xor a = 74 xor 61 = 15
a xor h = 61 xor 68 = 09
...
i xor o = 69 xor 6f = 01
t xor l = 74 xor 6c = 1b
o xor a = 6f xor 61 = 03

Por lo que el mensaje cifrado con la clave "hola" será
"09 01 05 15 09 4F 00 00 1E 0E 4C 0D 09 4F 18 08 06 0E 4C 18 48 1F
09 11 01 1B 03 41 04 0A 4C 02 04 0E 1A 00 48 1A 02 41 0B 03 0D 17
01 1B 03 41 0D 01 4C 0D 09 4F 0F 00 0A 0A 16 00 48 0E 00 41 0B 0E
00 17 01 1B 03"

Para descifrar los datos aplicamos el procedimiento inverso, realizamos la operación XOR al texto cifrado, y obtenemos "mágicamente" el texto en plano

El script en PHP para enviar Ecos con la descripción cifrada es el siguiente:

<?php
// @titulo: Ecostegano
// @autor: http://www.sinfocol.org
// @descripción: Envia datos ocultos a través del mensaje Eco del protocolo ICMP
//–
function eco($host, $mensaje){
  $cifrado = cifrar($mensaje);
  $paquete = "\x08";  // Tipo 08 para mensajes Echo.
  $paquete .= "\x00";  // Código 00.
  $paquete .= "\x00\x00"; // Suma de control, ICMP Checksum (00 00).
  $paquete .= $cifrado[0]; // Identificador y número de secuencia (4 bytes = 4 bytes clave aleatoria).
  $paquete .= $cifrado[1]; // Datos (Opcionales, mensaje cifrado).
  // La suma de control se calcula con todo el paquete a partir del "Tipo" y un Checksum igual a 00 00.
  $icmp = Checksum16bits($paquete);
  $paquete[2] = $icmp[0]; // Reemplazamos el ICMP Checksum.
  $paquete[3] = $icmp[1];
  $sock = socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp')); // Creamos el socket con el protocolo ICMP.
  socket_sendto($sock, $paquete, strlen($paquete), 0, $host, 0); // Enviamos los datos.
  socket_close($sock); // Cerramos el socket.
}
// Función para calcular la suma de control.
// Complemento a uno de 16 bits de la suma de los complementos a uno de todas las palabras de 16 bits.
function Checksum16bits($buff){
  $word16 = 0;
  $sum    = 0;
  $len    = strlen($buff);
  $i    = 0;
  while($i<$len){
    $word16 = ((ord($buff[$i++]) << 8) & 0xff00) + (ord($buff[$i++]) & 0xff);
    $sum += $word16;
  }
  while($sum>>16) $sum = ($sum & 0xffff)+($sum >> 16);
  return pack('n*',~$sum);
}
function cifrar($texto){
  $key = '';
  for($i=0; $i<4; $i++) $key .= chr(rand(0, 255)); // Generación de 4 bytes aleatorias para la clave "secreta".
  $tmp = '';
  for($i=0; $i<strlen($texto); $i++){ // Recorremos el texto.
    $tmp .= $texto[$i] ^ $key[$i % 4]; // Aplicamos XOR al texto recorriendo la clave reiterativamente, ajustamos su longitud con la operación módulo.
  }
  $cif[0] = $key;
  $cif[1] = $tmp;
  return $cif;
}
eco('192.168.1.254','Mensaje oculto en el protocolo ICMP Echo');
?>

Consideraciones
:arrow: Si el Eco se hace a un dispositivo de la red local, entonces como la capa superior es la del Ethernet II framing, los datos dentro de esta no pueden superar los 1500 bytes, a su vez, la cabecera IPv4 casi siempre es de 20 bytes y la cabecera ICMP para el mensaje Eco es de siempre 8 bytes, así que 1500 - 20 - 8 = 1472 bytes que podemos ingresar en la descripción del ICMP. Razón por la cual se extinguió el Ping de la muerte.
:arrow: Si el Eco se hace a un dispositivo que no se encuentra en la red local (Conexión por Módem), la capa superior es la IP, la cual permite un total de 65535 bytes (Contando su cabecera), así que la descripción del Eco estaría limitada por 65535 - 20 - 8 bytes (65507 bytes)

Referencias
:arrow: Request For Comments Internet Protocol
:arrow: Request For Comments Internet Control Message Protocol ICMP

Archivado en: Criptografía, Esteganografía |

Deja un comentario