martes, 22 de junio de 2010

IP Fragmentation Overlap & Fragroute

Hace algunas semanas vi en una de las pruebas de las PreQuals de la DEFCON una prueba (c500) en la que había que analizar una captura de red y obtener de ahí la solución. Como técnica de "ofuscación" del contenido de la comunicación, pareció haberse usado una técnica de IP Fragmentation Overlap, entre otras. Veamoslo rápidamente:


No vamos a entrar a la resolución de este reto, por ser algo más complejo, pero simplemente queremos haceros notar la existencia de IP Fragmentation Overlap, ya que los offsets de los fragmentos van de 40 en 40 bytes y sin embargo algunos paquetes contienen 80 bytes de datos.

Pero creo que nos estamos adelantando un poco, y este reto nos da pie para hablar un poco de la Fragmentación de paquetes IP, del Fragmentation Overlap y a poner un par de ejemplos usando Fragroute, una herramienta especialmente pensada para este tipo de ataques. No nos gusta mucho "soltar el rollo", pero en este caso creemos que es necesario para entender bien estos ataques.

¿Qué es IP Fragmentation?

Como ya sabéis, según el modelo TCP/IP, un Datagrama IP será "encapsulado" (para que nos entendamos) en algún tipo de protocolo a nivel de enlace, en redes locales generalmente Ethernet, pero podría usarse cualquier otro medio, en función del enlace que vayamos a usar. Cuando vamos a realizar esta "encapsulación", tenemos un requisito que tenemos que tener en cuenta, y es el llamado MTU (Maximum Transmission Unit) de dicha red, que es diferente según el tipo de red que vayamos a usar.

Para que nos hagamos una idea, es como si el Datagrama IP fuera un salami, y lo queremos meter en un buzón para que sea enviado. Si la rendija del buzón es más grande que nuestro salami, no hay problema, se mete entero y listo, pero... ¿qué pasa si la rendija es más pequeña? En ese caso tendremos que sacar un cuchillo y trocear nuestro salami de alguna manera, meter cada uno de los trozos en un sobre diferente y enviarlo por partes.

La única pega con esto es que, aunque el salami nos llegue a trozos, nos da igual por donde empezar a comerlo, pero con los fragmentos de un datagrama IP no pasa lo mismo, ya que tienen un orden que deberemos respetar. Para garantizar que estos fragmentos son "reensamblados" en destino de la misma forma, el protocolo IP cuenta con estos dos campos:
  • IPID: Es el número que identifica a todos los fragmentos de un mismo paquete. Si un montón de fragmentos IP tienen el mismo IPID, quiere decir que deberán ser reensamblados en el mismo paquete.
  • Offset: Es la posición en bytes que ocupará el fragmento desde el inicio del paquete. De esta forma, el fragmento con offset=0 será el primero, el offset=X (siendo X la cantidad de bytes en los que hemos troceado) será el segundo, offset=2*X será el tercero, y así sucesivamente hasta reensamblar el paquete completo.
Por lo tanto, ya sabemos que existe una técnica para trocear los datagramas IP si no "caben" en nuestra red y luego reensamblarlo en destino, pero... ¿como afecta esto a la seguridad?

En primer lugar, podemos forzar que se realice una fragmentación siempre que queramos, aunque el MTU de nuestra red no lo requiera, y en segundo lugar, podemos crear "anomalías" en la fragmentación que nos haga encontrarnos ante excepciones del protocolo que no están resueltas de una manera estándar, y que por tanto cada fabricante de sistemas operativos puede haber resuelto de forma diferente. Una de las maneras de hacerlo es un IP Fragmentation Overlap.

¿Qué es un IP Fragmentation Overlap?

Hemos dicho que el IPID identifica a todos los fragmentos que deberán ser recompuestos en un mismo datagrama IP, y que el Offset nos señala a partir de donde deben reensamblarse dichos datos. En un caso de fragmentación normal, si por ejemplo hemos partido el datagrama IP en bloques de 40 bytes, deberíamos tener un fragmento con offset 0, 40, 80, 120, y así sucesivamente, todos ellos con un tamaño de 40 bytes.

No hay problema, reensamblamos perfectamente y obtendremos de nuevo el datagrama IP, pero... qué sucede si alguno de los paquetes es mayor de 40 bytes, nos encontraríamos con algo como esto:

Ya le hemos liado, ¿cómo construimos el paquete ahora? ¿Qué información ponemos entre el byte 80 y el byte 119? ¿La que está en el segundo fragmento o en el tercero?

El protocolo no lo deja claro, así que ahí cada fabricante de sistemas operativos lo ha resuelto de una manera diferente. Según la documentación de Snort, en este momento hay en el mercado 7 políticas diferentes a la hora de realizar el reensamblado de paquetes:
  • First: HP-UX 11, MacOS, SunOS <5.8
  • Last: Cisco
  • BSD: AIX, FreeBSD, HP-UX 10.x, IRIX
  • BSD-Right: Algunas impresoras HP
  • Linux: OpenBSD, Linux
  • Windows: Windows (obviamente)
  • Solaris: Solaris 9 y 10
La descripción de como realiza el reensamblado cada una de estas políticas (o al menos gran parte de ellas) puede encontrarse en este paper, salvo para Windows y Solaris, que Snort las ha separado recientemente de la política First, aunque sus diferencias sea leves.

El tema es que, aprovechando estas anomalías, podemos generar una conexión de red con una fragmentación especialmente creada para que funcione adecuadamente con nuestro sistema objetivo (un Windows, por ejemplo) pero que al ser reensamblado por otro tipo de sistemas (un Snort o un Wireshark en un Linux, por ejemplo) la información obtenida sea diferente, con lo que podemos ocultar una conexión e incluso provocar que el IDS no detecte ataques contra ese sistema (aunque ya veremos en otra ocasión como Snort tiene maneras de mitigar estos riesgos).

FragRoute

FragRoute es una herramienta de gran flexibilidad y potencia que nos permite forzar la fragmentación contra un sistema concreto, así como otros tipos de ataques de overlapping basados en TCP.

El tipo de ataques de fragmentación a realizar se define en un fichero de configuración con el que deberemos lanzar la herramienta. En nuestro caso, el fichero tiene el siguiente contenido:

ip_frag 40 old
order random
print

En este caso, estamos eligiendo realizar una fragmentación ip (ip_frag) de tamaño 40 bytes (40) y con overlaping favoreciendo que los fragmentos más antiguos tengan preferencia, es decir, estamos haciendo una fragmentación de tal forma que vamos a poder hablar con sistemas First, y probablemente Windows y Solaris (su política es muy similar a First). Además, estamos ordenando aleatoriamente los fragmentos (order random) y estamos señalando que queremos verlo por la pantalla (print), aunque por supuesto esta última parte es opcional.

Los usuarios de Ubuntu (o BackTrack, como es mi caso) pueden sufrir algún problema debido al contenido del fichero /proc/sys/net/ipv4/conf/all/rp_filter , que en este tipo de sistemas (y no sé si en algunos otros) está a "1" y debería estar a "0" para funcionar. Si os encontrais con problemas de funcionamiento en vuestro sistema, comprobad este flag:

# cat /proc/sys/net/ipv4/conf/all/rp_filter
1
# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

Ahora que ya tenemos esto configurado, si lanzamos la herramienta, probablemente nos encontraremos con el siguiente error:

# fragroute -f fragwin2.conf 172.16.24.151
fragroute: no route to 172.16.24.151: No such process

Por algún motivo, parece que fragroute requiere que tengamos al objetivo en nuestra tabla ARP o similar, así que tendremos que forzar una pequeña conexión antes de lanzarlo:

# ping -c 1 172.16.24.151 >/dev/null ; fragroute -f fragwin2.conf 172.16.24.151
fragroute: ip_frag -> order -> print

Por fin tenemos lanzado el fragroute. Ahora todo el tráfico que sea encaminado hacia 172.16.25.151, usemos la aplicación que usemos, será fragmentado de la manera que hemos escogido.

Como en el sistema Windows que hay en 172.16.24.151 tenemos un IIS a la escucha, vamos a ver que capturará el tcpdump o el wireshark cuando accedamos a este:

# tcpdump -nn -s 0 -w fragment.pcap host 172.16.24.151

# lynx -dump http://172.16.24.151
[respuesta esperada]

Tras ver que podemos visitar correctamente la web y que el Windows es capaz de reensamblar correctamente los fragmentos, vamos a ver que pasa cuando abrimos el pcap que hemos capturado en Wireshark:


Como podemos ver, el paquete reensamblado parece tener "basurilla" proveniente de los fragmentos con los que se hacía el overlapping. De hecho, si nos fijamos en la flecha, veremos que Wireshark nos muestra un fallo en el Checksum del contenido del paquete, algo lógico, ya que el Checksum fue calculado a partir del contenido original, y el contenido después de ser reconstruido el paquete es diferente, por lo que su Checksum no será el mismo.

Como decíamos antes, este tipo de técnicas pueden ser usadas para evadir la protección de los IDSs, ya que podemos hacer que un IDS sobre Linux (por ejemplo) reensamble el paquete de una forma incorrecta y que por lo tanto el contenido no haga match con ninguna regla, y sin embargo que el reensamblado en el host atacado sí que reensamble correctamente y sufra el ataque. También puede ser usado, como en el caso del reto de la DEFCON, para tocar los c****** a alguien que intenta analizar el tráfico de red :P

Sin embargo, no todo está perdido, ya que los IDSs pueden ser configurados de cierta forma que pueden detectar estos paquetes e incluso emular los diferentes tipos de reensamblado, pero claro, ha de ser configurado correctamente.

Pero eso será ya otro post.

22 comentarios :

mgesteiro dijo...

buenísimo! gracias por la explicación tan detallada y tan, al mismo tiempo, clara y simple.

Jose Selvi dijo...

Gracias @mgesteiro :)

Anónimo dijo...

A @mgesteiro ya me lo veo incluyendo las putaditas de overlap en sus hackcontest.

Muy bueno el artículo Mr. Selvi
Pptx

mgesteiro dijo...

@selvi de nada!

@pptx lo bueno hay que aprovecharlo, pero si estás aquí, ya lo reconocerás ;)

neofito dijo...

Has utilizado un salami para la analogia, ¿influencia de la serie de television "La que se avecina"? jaja

Fuera coñas, enhorabuena por el articulo.

Saludos

Jose Selvi dijo...

@neofito: En realidad lo he usado porque estaba pensando en algo que se pudiera "trocear" y me he acordado de las "técnicas salami", como las que se usaron en "Superman 3" y "Trabajo Basura" para robar una fracción de centavo de cada transacción xDDDD

Saludos a todos, y gracias por los comentarios ;)

Jose Selvi dijo...

@mgesteiro: Te jodo mucho el hackcontest si publico la semana que viene como reconstruir bien los paquetes con una herramienta? :P

bl4ckc00k1e dijo...

Muy buena info, me gusto mucho ahora que estoy con cisco

a0rtega dijo...

Otro post genial, para encuadernar con algunos más de aquí y hacer un libro de seguridad "made in pentester.es" :D

Jose Selvi dijo...

@a0rtega: Gracias por los cumplidos ;)

Libro libro... no creo, pero igual algún día nos animamos y montamos algún cursito o algo. Es una idea que nos ronda la cabeza desde que vi la buena aceptación que tuvo el curso de SANS que acabo de terminar de impartir en la modalidad Mentor. La gente parece que quedó bastante contenta.

César dijo...

Señores, uno de los mejores articulos que leo hace mucho tiempo en la web, realmente GENIAL!

Anónimo dijo...

Joer, recién estaba yo redactando un post de lo mismo. Eso si, peor explicado jaja.

Mis pruebas son con el snort y su super frag3 :D

Muchas gracias Jose,

Don Ximo para vos xD

Jose Selvi dijo...

@César: Gracias por los cumplidos, nos alegra que te gusten nuestras aportaciones :)

@Anónimo (aka Ximo xD): Sasto, el segundo post va de refragmentar paquetes usando Snort y Frag3. Eso para el lunes probablemente, o no sé si intercalaremos con otra entrada que tenemos en el tintero ;)

Gracias a todos por los comentarios.
Saludos!

Anónimo dijo...

Buenas Jose,

te vimos explicando esto en la NcN'10, y aunque ya habíamos leído esta serie de artículos, nos impresionó lo bien que te explicas en persona, mejorando lo presente en tu blog, que no es poco.

Claro, dispuestos a ponerlo en práctica para comprobar nuestros IDS, surge un problema. Vale que en LAN o entre máquinas virtuales, el ping evita que el fragroute se queje de no tener "ruta" hasta el objetivo. Sin embargo, si estamos separados de la víctima por una WAN, claro, de ARP nada, y ni siquiera añadiendo manualmente una ruta estática hacia el objetivo funciona. Ni con ping al objetivo, ni al gateway por defecto,...

¿Has logrado lanzar paquetes con fragroute a través de la wan y que no se queje de que no tiene ruta?

Gracias de antemano.

Jose Selvi dijo...

@Anónimo: A mi sí me funciona, es un tema más de "nexthop" en capa 2 que de rutas exactamente.

Parece ser que fragroute no es capaz de lanzar un ARP Request, así que necesita que esta resolución esté YA en la cache arp.

Si quieres hacer esto con un Host fuera de tu LAN, simplemente tienes que hacer algo que garantice que el "nexthop" (el gateway de la LAN) esté en la caché, haciendo un ping a este o a cualquier IP de fuera de tu LAN.

Si estás haciendo esto y no te funciona, seguramente tu problema será otro. ¿Te da exactamente ese error? ¿Qué no existe el proceso?

Gracias por tu comentario.
Saludos!

Josep Pi dijo...

Hola,

Yo he estado probando el fragroute y ni me funciona en LAN con un equipo que está en la misma LAN, sin pasar por un FW ni nada.Por que podría ser ? Es un Windows, pero tb lo he probado contra un Linux.

Yo-> 10.10.1.2
Objetivo-> 10.10.1.3

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

cat /etc/fragroute.conf

tcp_seg 1 new
ip_frag 24
ip_chaff dup
order random
print

ping -c 1 10.10.1.3 ; fragroute -f /etc/fragroute.conf 10.10.1.3
fragroute: tcp_seg -> ip_frag -> ip_chaff -> order -> print

ping 10.10.1.3 no hay respuesta

salida del fragroute:

10.10.1.2 > 10.10.1.3: icmp: type 117 code 104 (frag 0:24@0+) [delay 0.001 ms]
10.10.1.2 > 10.10.1.3: icmp: type 8 code 0 (frag 0:24@0+)
10.10.1.2 > 10.10.1.3: (frag 0:24@24+) [delay 0.001 ms]
10.10.1.2 > 10.10.1.3: (frag 0:16@48) [delay 0.001 ms]
10.10.1.2 > 10.10.1.3: (frag 0:24@24+)
10.10.1.2 > 10.10.1.3: (frag 0:16@48)
10.10.1.2 > 10.10.1.3: (frag 0:24@24+) [delay 0.001 ms]
10.10.1.2 > 10.10.1.3: icmp: type 100 code 110 (frag 0:24@0+) [delay 0.001 ms]

Tambien lo pruebo con esta otra config:
ip_frag 40 old
order random
print

y pasa lo mismo.

Sin embargo, fragtest me responde OK:

fragtest ping 10.10.1.3
ping: 5.673 ms

fragtest frag 10.10.1.3
frag: 1.160 ms

fragtest frag-old 10.10.1.3
frag-old: 0.562 ms

Jose Selvi dijo...

@Josep_Pi: Con qué tipo de conexión lo estás probando? Con un Ping?

Has probado que, sin usar FragRoute, el ping te funciona bien? Te lo digo porque los Windows con el Firewall activado no responden al ping. Puede que sea el problema.

Por otro lado, para cada caso hay que hacer un estudio y emplear un tipo de fragmentación, es decir, no puedes usar la misma con un Windows y luego probarla con un Linux, porque no te va a funcionar, esa es la gracia.

Asegurate que la conexión que estás probando llega sin fragmentación, luego prueba con una fragmentación sin overlapping (esto debería funcionar en todos los sistemas), y por último añadele el overlapping adecuado. En el caso de un Windows el ejemplo que yo puse en el post. Si solo te deja de ir en este último paso es que algo no va bien. Yo he tenido problemas a partir de BackTrack 4 R2 con FragRoute, parece ser que han actualizado alguna librería y sencillamente el Fragroute no funciona. Si ese es tu problema, tendrás que irte a una versión anterior. Yo no conseguí hacerlo funcionar en una BackTrack más moderna.

Josep Pi dijo...

@Jose_selvi

Si que tengo acceso por ping y tb al puerto 80 y no me funciona ni el ping ni un telnet/nc al puerto 80 con la fragmentacion.

Lo configure a medida tanto para Linux como Windows.Lo unico que no he probado es sin overlapping, voy a probarlo.Lo he usado con BT4R2 , entiendo que en esta version no te ha dado problemas.Voy a seguir probando, si encuentro que es lo que pasaba lo publico.

By the way... cada vez que uso algo BT5 incluso en la R1 no hago mas que encontrarme problemas! Yo sigo con BT4R2 en la medida de lo posible..

Saludos y gracias !

Jose Selvi dijo...

@Josep_Pi: Con la BT4R2 yo tampoco lo conseguí hacer funcionar. Prueba con la BT4 a secas.

marcos dijo...

Hola Jose selvi:

Pregunta sobre fragmentacion.

Quiero evadir una regla del IDS SNORT.
Por ejemplo la regla detecta si se hace ls-l en la URL victima.

La victima corre con Linux y tiene snort configurado.

Utilizando el fragrouter como puedo enviar un paquete TCP al puerto 80 fragmentado? No he sabido hacerlo.
quiero hacer esto pero fragmentado para linux.

GET /TWIKI/BIN/ls -l

Te agradeceria enormemente tu ayuda, ya que estoy haciendo mi proyecto de final de carrera sobre IDS evasiones.

Saludos.

Jose Selvi dijo...

Hola @marcos,

Si la víctima usa Linux y el Snort está en Linux (me comentas que son la misma máquina ¿no?) NO puedes usar ataques de fragmentation overlapping para evadir el IDS, ya que ambos van a defragmentar de la misma manera.

Hay otras técnicas que puedes utilizar en tu caso, pero tendría que ver como es la regla que quieres evadir. Ponme un correo y lo vemos.

Suerte con tu PFC!

Chris dijo...

Cool!