[LACNIC/Seguridad] Processing of IPv6 "atomic" fragments (Fwd: I-D Action: draft-ietf-6man-ipv6-atomic-fragments-00.txt)

Fernando Gont fgont en si6networks.com
Lun Feb 6 20:37:21 BRST 2012


Hola, Ivan,

On 02/06/2012 01:04 PM, Iván Arce wrote:
> Me refiero a que en algún momento dado seguramente habrá hosts que
> implementen el algoritmo recomendado y hosts que sigan con la
> implementación actual de un contador global. Pensando en ese escenario
> se me ocurrió que ese podría dar una situación similar a la que se
> utiliza para hacer un Idle Scan:

Nota: El ya se puede realizar actualmente, con aquellas implementaciones
utilizan un contador global. Por ej. Windows, y Linux (previo al parche:
<http://www.ubuntu.com/usn/usn-1253-1/> ,
<https://rhn.redhat.com/errata/RHSA-2011-1465.html>)



> Supongamos que el host A implementa el algoritmo recomendado en la
> seccion 3.2 (un contador por destino que se inicializa con un numero
> pseudorandom y se incrementa en 1 por cada fragmento enviado) mientras
> que el host B no implementa el algoritmo y simplemente usa un contador
> global que se inicializa en 0 y se incrementa 1 enviado por cada
> fragmento enviado. Si A y B estan intercambiado paquetes, es trivial
> para B adivinar el proximo numero de fragmento que utilizará A en sus
> comunicaciones, por tanto la "confidencialidad" de dicha información
> depende de que no exista en B ningun mecanismo que un host maligno M
> pueda utilizar para exfiltrar el secreto... ese es el principio básico
> del que se aprovecha la técnica de idle scan.

Tal cual. Pero el proble que mencionas ya existe *hoy* en dia. El I-D
que yo escribi lo previene.. y de hecho Linux y Solaris parchearon en
consecuencia.

Microsoft tiene el mismo problema, con la unica diferencia que el
contador se incrementa en 2, y *no* en uno (lo cual, obviamente, apra el
caso es lo mismo). Sin embargo, desconozco que es lo que va a hacer MS
al respecto. En mi experiencia personal, suele ser una experiencia muy
frustrante hablar con el CSIRT de MS (secure@)


> De acuerdo a lo indicado en
> http://www.ietf.org/id/draft-ietf-6man-ipv6-atomic-fragments-00.txt para
> el host M es trivial forzar a que A y B se comuniquen usando fragmentos
> atómicos, también es trivial forzar una comunicación entre M y B usando
> datagramas fragmentados. Entonces, existe la posibilidad de que M,
> utilizando su comunicación con B como oraculo infiera el proximo numero
> de frag ID que utilizará A para comunicarse con B ?

Si. De hecho, tal como mencionaba arriba, el idle scan es posible. La
unica cuestión es que, en algunos casos, hay implementaciones que (por
tener bugs) no agregan un Fragment Header al recibir un ICMPv6 PTB
anunciando un MTU < 1280.


> No lo sé pero a
> priori parecería que si, cosa que no sucedería si el algoritmo
> recomendado fuera de elegir un número pseudorandom por cada fragmento.

Aca me perdí. Para evitar un idle scan, la cosa es simple: no debe haber
un contador global. Eso se puede evitar, entonces, o bien teniendo un
contador por cada destino (o un set de contadores mas o menos grande,
como por ej 8K o mayor), o bien generando el Frag ID con un PRNG.


>> Otra alternativa posible es generar los I-Ds asi:
>>
>> Frag_ID = F(src IP, dst IP, secret1)  +
>>           counter[G(src IP, dst IP, secret2)]
>>
>> Donde:
>> F(): hash
>> G(): hash
>> counter[]: array de contadores, inicializados al bootear con valores
>> aleatorios.
>>
>>
>> Esta alternativa es un "termino medio" entre "un contador global" y "un
>> contador por destino".
> 
> Otra alternativa es usar un PRNG global y para cada destino guardar los
> últimos "n" frag IDs usados para asegurarse de no tener colisiones, con
> 0  <= n <= K. El caso más simple es n := 0

Claro, pero... si vas a guardar "info por destino", por que no,
directamente, tener un contador por destino?



> Por supuesto que cada una de estas opciones tiene distinto impacto sobre
> la eficiencia del stack del host que las implemente y si la degradación
> de performace es importante entonces se abre la puerta a otro tipo de
> ataque de denegación de servicio porque aparentemente forzar la
> fragmentación es trivial...

En conversaciones con developers, algunos tambien plantearon la cuestion
de performance (no ercuerdo si respecto al Frag ID en particular, pero
de seguro estabamos hablando de randomizacion de algun campo (ya sea
Frag ID, flow label, puertos, o lo que sea). En tal caso, la solucion de
"contador por destino" termina siendo mas eficiente.

Hay otras cuestiones, tambien:
Si vos vas a guardar info "por destino", es bastante probable que
eventualmente tengas que "eliminar" dicha info (ya que un posible ataque
sería en hacer que dicha info crezca y crezca).

En tal caso, si uno utiliza "un contador por destino, que se inicializa
a un valor aleatorio", al "descartarse dicha info existe el peligro de
que se generen colisiones de Frag ID.

Por otro lado, si utilizas la solucion "basada en hashes", utilizando un
set de contadores globales, entonces en realidad no te hace falta
guardar info "por destino", y *no* corres riesgos de colisiones de Frag
IDs al descartar esas entradas "por destino".



>>> Parecería que eso abre la puerta a la "inserción y/o solapamiento de
>>> headers" que incluso se procesarían silenciosamente ?! No entiendo del
>>> todo las implicancias de eso en un escenario en el que se usan Fragment
>>> IDs predecibles pero sospecho que no son buenas...
>>
>> Coincido. *En principio* ("en teoría"), al menos desde la parte
>> fragmentada en adelante esto se evitaría gracias a lo especificado por
>> RFC 5722. 
> 
> Claro pero si se aplica tu recomendación para procesar fragmentos
> atómicos como si fueran datagramas no fragmentados, el solapamiento
> desde la parte fragmentada en adelante no se detectaría mas porque el
> datagrama atómico nunca entra en la cola para el reensamblado.

Correcto. Es cierto que, durante la "transición" hay (en principio) dos
maneras de interpretar el tráfico, lo cual podría utilizarse para
inserción/evasión.

SIn embargo, esto no es nuevo, ya que en la actualidad ya existen
multiples interpretaciones: sistemas que se actualizaron de acuerdo a
RFC 5722, sistemas que utilizan la primer copia de los datos,y  sistemas
que utilizan la ultima copia de los datos.


>> En lo que hace a la parte anterior al fragmento... dejame
>> pensarlo un poco, ya que no habia evaluado el tema.
> 
> Bueno, a eso es a lo que me refiero con inserción de headers. La parte
> anterior al fragmento puede incluir headers que se procesarían antes de
> tratar de reensamblar todos los fragmentos, despues cuando los
> fragmentos se reensamblan y se determina que hay solapamiento se tira
> todo a la basura...y sin embargo los headers insertados ya fueron
> procesados por el stack. El escenario en el que estaba pensando es uno
> en el que los ID de fragmento son predecibles por un tercero y por tanto
> spoofeando datagramas fragmentados se podrían insertar headers en las
> comunicaciones entre dos hosts.

Si los Frag IDs son predecibles, en principio podes insertar lo que vos
quieras... desde headers, hasta payloads. De hecho, existe una
posibilidad que no ha sido analizada en mucho detalle, descripta por
Zalewski en <http://lcamtuf.coredump.cx/ipfrag.txt>, y referenciada en
el trabajo gral que yo hice sobre TCP
<http://www.gont.com.ar/papers/tn-03-09-security-assessment-TCP.pdf>.



>> * Intencionalmente* el I-D no menciona con detalles el siguiente escenario:
>>                Conexion TCP
>>            A <--------------> B
>>
>> Un atacante (en cualquier otro punto de la red) podria spoofear un
>> ICMPv6 "Packet Too Big" a A, con un "MTU" < 1280. Tal como lo menciona
>> RFC 2460, "A" deberia empezar a enviar todos sus paquetes con un frag
>> header (serían "ataomic fragments"). Si los Frag ID utilizados por "A"
>> son predecibles, entonces el atacante podria enviar fragmentos
>> spoofeados a "B", de modo que colisionen con los fragmento legitimos
>> enviados por "A". Resultado: DoS.
> 
> Bueno, es precisamente en ese escenario que yo estaba pensando si
> existiría un ataque con implicancias mayores que denegación de servicio.
> Cualquier header que modifique una máquina de estados en el stack de
> destino y cuyo procesamiento no se idempotente es candidato a ser usando
> en un ataque con implicacias mayores que DoS.

Te referis a algo tipo inserción, u a otra cosa?

(dicho de otro modo, salvo que el stream de datos este autentificado, el
ataque en cuestion se podria utilizar para cualquier cosa).


>> La propuesta en cuestion previene dicho ataque, ya que al ser los
>> paquetes legitimos de tipo "atomic fragments", nunca se mezclarian con
>> los fragmentos maliciosos enviados por el atacante.
> 
> Que nunca se mezclen no significa que no persista el potencial de
> problemas...

Esto elimina *un* problema: que el trafico que utiliza frags atomicos no
pueda ser objeto de ataques basados en fragmentación.


>>>> Additionally, any fragments already queued with the
>>>> same set {IPV6 Source Address, IPv6 Destination Address, Fragment
>>>> Identification} should not be discarded upon receipt of the
>>>> "colliding" IPv6 atomic fragment, since IPv6 atomic fragments do
>>>>  not really interfere with "normal" fragmented traffic.
> 
> Esto no me queda claro, en principio se me ocurre que que entre A y B no
> pueden existir 2 tipos de comunicaciones simultaneas, una con fragmentos
> atómicos y otra con fragmentos "normales" 

Si. Fijate el siguiente caso: Si por ejemplo estuvieras usando cualquier
aplicación que utilice UDP, es muy probable que necesites fragmentar los
paquetes (ya sea NFS sobre UDP, o lo que quieras).

EL escenario de "atomic fragments" se da en aquellos casos en los que el
protocolo de transporte puede "segmentar el data stream" en varios
apquetes distintos, como es el caso de TCP (y de los protocolos
"connection-oriented", en gral).


> toda usando el mismo frag ID.

En lo que respecta a esto ultimo, todo depende del algoritmo que
utilices para la generacion del Frag ID. Si utilizaras un simple PRNG,
en un escenario como en el que describi arriba se podría dar esta situacion.


> Es más el RFC5722 prohibe que un host cree fragmentos solapados y la
> comunicación con fragmentos normales necesariamente tiene un fragmento
> con Offset=0 que se solaparía con el fragmento atómico si este estuviera
> en la cola de reemsamblado...

Si. Pero esto es asi *asumiendo* que:
1) EL host implemente RFC 5722 (no todos lo hacen.. de hecho, OpenBSD lo
implemento hace un par de semanas, recien)
2) El host no genera los Frag ID con un PRNG -- las implementaciones que
dependen de KAME (lease, al menos *BSD, lo hacen con un PRNG, aunque no
miré con que algoritmo, en particular)



> Mas alla de eso, me parece que no se puede atender el problema de los
> fragmentos atómicos sin tener resuelto el problemas de los ID de
> fragmento predecibles porque sino cualquier algoritmo a recomendar
> también tiene que ser analizado desde el punto de vista de un atacante
> con la posibilidad de insertar datagramas con Frag ID válidos en
> cualquier momento.

A mi entender, ambos problemas son ortogonales. Si solucionas el tema de
los fragmentos atomicos, basicamente lo que logras es que incluso si los
Frag ID fueran predesibles, no te afecten los ataques basados en
fragmentación.

Ni hablar que el tema de los Frag ID predecibles es algo grave... pero
creo que es ortogonal al de los fragmentos atomicos.


>>> La posibilidad de adivinar un fragment ID y mandar un paquete spoofeado
>>> con un header espurio invalida la presunción de que todos los headers se
>>> procesan en orden no?
>>
>> Me perdi en esta ultima...
>>
>> Adivines o no el Frag ID, todo lo que se encuentra previo al Frag header
>> va a ser procesado por el destinatario. 
> 
> Claro, pero si el Frag Id es predecible y después encontrás fragmentos
> solapados con Frag ID válido SABES que estas sufriendo un ataque y que
> no deberías haber procesado headers que ya procesaste. 

Hacer ésto implicaria cambiar otro aspecto de RFC 2260: lease, no
requerir el proceso de los paquetes en orden.

De cualquier modo, no sé si esto evitaría algo: ya que en lo que
respecta a los headers que se encuentran previo a la parte fragmentada,
esos *siempre* se procesan sin la necesidad de adivinar nada.

Es decir, al menos hasta ahora, y sin pensarlo mucho, no se me ocurre
alguna situación en la que se le pudiera sacar provecho (lo cual,
obviamente, no quiere que la misma sea inexistente).

Saludos,
-- 
Fernando Gont
SI6 Networks
e-mail: fgont en si6networks.com
PGP Fingerprint: 6666 31C6 D484 63B2 8FB1 E3C4 AE25 0D55 1D4E 7492






Más información sobre la lista de distribución Seguridad