Fragmentación IP

La fragmentación IP es una técnica utilizada para dividir los datagramas IP en fragmentos de menor tamaño. Ésto es necesario ya que cuando los datagramas IP viajan de un lugar a otro, éstos pueden atravesar diferentes tipos de redes y el tamaño máximo -llamado MTU– de estos paquetes puede variar dependiendo del medio físico utilizado para la transmisión.

El valor máximo que técnicamente puede utilizarse para un datagrama IP es de 65536 bytes, aunque en la práctica se utilizan otros tamaños mucho más pequeños:

  • Ethernet: 1518 bytes (típicamente 1500 bytes).
  • PPPoE: 1492 bytes.
  • ATM: 8190 bytes.
  • FDDI: 4470 bytes.
  • PPP: 576 bytes.

Veamos cómo funciona esta técnica con más detalle. La cabecera IP, que suele tener un tamaño de 20 bytes, contendrá la siguiente información:

  • Identificador de fragmento. Cada Fragmento debe asociarse con un único identificador para que el reensamblaje en destino pueda realizarse correctamente.
  • Información sobre la posición en el paquete final.
  • Información sobre el tamaño de los datos que se transportan en el fragmento.
  • Cada fragmento debe contener el bit MF (More Fragments) para saber si el fragmento actual es el último o no.

Así que la figura de un paquete de máximo tamaño que no necesite fragmentación en una red típica Ethernet sería algo así:

Paquete de 1500 bytes
Paquete de 1500 bytes

Si sumamos la cabecera y los datos encapsulados, tenemos que en total hacen 1500 bytes, por lo que al viajar por una red Ethernet, no sería necesaria su fragmentación.

Los datos encapsulados pueden ser tanto un protocolo IP como TCP, UDP o ICMP. Veamos un ejemplo en el que se tenga que utilizar la fragmentación. Este es un ejemplo anormalmente grande, pero en el que podremos ver cómo se realiza el proceso de fragmentación. Se trata de una petición echo que pasa por una red Ethernet con MTU de 1500 bytes.

Proceso de fragmentación de un paquete de 4028 bytes
Proceso de fragmentación de un paquete de 4028 bytes

En el paquete original, la suma de las cabeceras y los datos ICMP suman 4028 bytes. Este paquete al ser transmitido en una red Ethernet deberá ser fragmentado, generandose así 3 paquetes de 1500 bytes o menos. Cada fragmento llevará obligatoriamente al menos la cabecera IP (necesaria para saber hacia dónde se dirige el fragmento), que en este caso ocupa 20 bytes, así que tendremos realmente 1480 bytes útiles.

El primer fragmento contendrá la Cabecera IP + la cabecera ICMP + la información restante para llegar a 1500 bytes, en este caso 1472 bytes. Puesto que es el primer fragmento, el valor de Offset valdrá 0 y el bit MF valdrá 1 ya que hay más paquetes.

El segundo fragmento contendrá la Cabecera IP + la información restante para llegar a 1500 bytes, en este caso 1480. Ahora el valor de Offset valdrá 1480, ya que es la posición que debe ocupar al ensamblar el fragmento (recordemos que el primer fragmento tenía 8+1472 = 1480). El bit MF valdrá 1 ya que no es el último paquete.

El tercer fragmento contendrá la Cabecera IP + la información restante, en este caso 1048 bytes (ya no hay más bytes). El valor de Offset valdrá 2960, ya que el primer y segundo fragmento ocupaban 1480 cada uno. El bit MF se establece a 0 porque es el último fragmento del paquete.

El campo Protocol sólo indica a qué tipo de protocolo corresponde el paquete original. ID fragmento indica un identificador que será igual para todos los fragmentos del paquete original, así se podrá reconstruir en destino sin confusión. El bit MF (more fragments) se establecerá a 1 siempre, excepto para el último paquete, que será 0. El Offset nos indica la posición que ocupa cada fragmento dentro del paquete original. El campo Tamaño, simplemente registra el tamaño del fragmento actual sin contar la Cabecera IP.

Una vez conocemos a grosso modo cómo funciona esto de la fragmentación, explicaré por encima, cómo un usuario malintencionado puede utilizar este procedimiento para realizar un ataque.

El ataque más conocido que explota la fragmentación IP se llama Teardrop. Este ataque usará información falseada en los fragmentos para poder confundir el reensamblaje en destino y colapsar así el sistema.

Imaginemos que tenemos un MTU de 512 bytes y un paquete que necesita ser dividido en N fragmentos y utilizamos los campos Tamaño y Offset de la siguiente manera:

Offset Tamaño
Fragmento 1 0 512
Fragmento 2 500 512
Fragmento N 10 100

Al reconstruir el paquete en destino se producirá un error de desbordamiento de buffer (buffer overrun), ya que el fragmento N apunta a un lugar en el que ya se había escrito previamente y obliga a sobreescribirse.

Otro ataque interesante es enviar cientos o miles de fragmentos manipulados con diferentes ID de fragmento contra la máquina que se desea atacar, de manera que agotemos los recursos de reensamblaje del equipo atacado; acabaremos colmando la pila en la que reconstruye estos paquetes, y no aceptará ninguno más, generando así un ataque de Denegación de Servicio (DoS).

Afortunadamente, a dia de hoy, este tipo de ataques no suelen ser efectivos. Los sistemas operativos vulnerables son Windows 3.1x, Windows 95, Windows NT y las versiones inferiores a Linux 2.0.32, así como la 2.1.63.

Otro día hablaré del famoso ping de la muerte! 🙂

16 comentarios en “Fragmentación IP”

  1. Suponga que el host A está conectado a un router R1, que este router está conectado a otro router R2 y R2 tiene línea con el host B. Suponga que un mensaje TCP que contiene 900 bytes de datos y 20 bytes de encabezado TCP se pasa a código IP en el host A para entregarlo a B. Muestre los campos: Longitud total, Identificación, DF, MF y Desplazamiento del fragmento del encabezado IP en cada paquete transmitido a través de los tres enlaces. Suponga que de A a R1 el tamaño máximo de trama es 1024 bytes, con 14 bytes de encabezado. La línea R1 a R2 su tamaño máximo es de 512 bytes, con 8 bytes de encabezado y que de R2 a B la trama máxima es de 512 bytes y encabezado de 12 bytes.

  2. Hola, muy buena publicación. Un solo detalle, el campo offset indica desplazamiento en bloqeus de 64 bits, es decir que en el fragmento 2 del ejemplo, el campo offset toma el valor 185 y en el fragmento 3 370.
    Saludos

  3. Amigo tengo una consulta!
    Porque finalmente quedo el tamaño 1500 bytes en datos de Ethernet? Por que no es mas, por que no es menos?

    Agradecería tus comentarios!

  4. Como te han dicho por arriba el campo offset indexa agregados de 8 bytes para que los 65536 bytes se puedan indexar en un número de 13 bits que tiene el offset.

  5. Buen dia.
    Excelente publicacion.
    Quisiera hacerte una pregunta que no he podido decifrar.
    Estoy programando en un micro un servidor web y aunque el compilador cuenta con las librerias ethernet no fragmenta ni desfragmenta paquetes. Entonces estoy implementando esa parte.
    Uno de los problemas es que cuando llega un solicitud GET no logro identificar si la solicitud es de un solo paquete o vienen mas. Estoy monitoreando con wireshark y veo que la solitud get que envia el chrome es picada en dos paquetes y el bit more fragment esta a 0 a pesar que falta un paquete mas. Lo he probado estableciendo una ventana MSS menor para que sean mas paquetes y more fragment siempre esta a 0 en el wireshark.
    Me pregunto si ya que IP no me est dando informacion de si vinen mas fragmentos, la capa TCP tiene manera de indicarme si luego de recibir el primer fragmanto, vienen mas etc. O en su defecfo como saber que es el ultimo.
    Saludos

  6. Hola buenas. Muy bien explicado!
    Me veo en un caso parecido pero lo que sucede es que manda 3 paquetes fragmentados con el more fragments a 1 y el cuarto es mandado con valor 0 (siendo el último paquete ha recibir) y acto seguido manda 7 paquetes fragmentados más con el more fragments a 1. Y después descarga un malware (ataque malware downloader).
    Se que es un ataque de fragmentación IP con fragmentos superpuestos pero no se el funcionamiento (la razón) de mandar 3 paquetes con MF=1, 1 paquete con MF=0 y 7 paquetes con MF=1
    Sabrías por qué realiza así el ataque?
    Gracias
    Saludos

  7. Muchas Gracias por la explicación.
    Pero de lo que yo estaba estudiando, en algunos casos se pone el bit DF y me gustaria saber cuando es que este bit toma valor 0 ó 1

  8. El bit DF, conocido como bit «Don’t Fragment» puede tomar valor 1 cuando es necesario que un paquete no sea fragmentado. Si pasa por alguna red cuya MTU es menor que el tamaño del paquete y éste está marcado como no-fragmentar, entonces el paquete será descartado. Una utilidad es para descubrir precisamente el MTU de una red concreta.

  9. Hola, hay alguna formula para calcular todo esto? Lo has explicado muy bien lo e entendido genial muchas gracias

  10. En respuesta a [JUAN – 18 octubre, 2018 a las 00:41]
    Si es posible fragmentar un fragmento ya que el MTU es variable entre redes y puede darse el caso que necesitemos fragmentar más de una vez un mismo envío

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *