Hace 3 años | Por m4k1n4v4j4 a robertheaton.com
Publicado hace 3 años por m4k1n4v4j4 a robertheaton.com

Un ataque de reinicio de TCP se ejecuta usando un solo paquete de datos, de no más de unos pocos bytes de tamaño. Un segmento TCP falso, creado y enviado por un atacante, engaña a dos víctimas para que abandonen una conexión TCP, interrumpiendo las comunicaciones posiblemente vitales entre ellas. El ataque ha tenido consecuencias en el mundo real. El miedo a él ha causado que se hagan cambios mitigantes en el propio protocolo TCP.

Comentarios

D

#1 Pues la FCC por eso le pueden crujir. Interrupción de comunicaciones -> multaza . Y en EEUU las multas son individuales, no colectivas.

D

Esto es más viejo que la tana. Se conoce desde tiempos inmemoriales.

Lo jodido de esto es que en las imágenes que acompañan a cómo funciona, ponen código html, cuando en las peticiones web es prácticamente imposible llevarlo a cabo y no tiene sentido. Es en conexiones de larga duración donde lo tiene. Conexiones de Chat, entre clientes de torrents, websockets, todo servicio que necesite una conexión TCP abierta de forma continua.

Http es abrir conexión, pides /index.html, server responde y chapa conexión. Esto ocurre en cada petición en milisegundos. Quizá segundos si el server tiene que hacer alguna operación costosa. Pero si falla la petición, F5 y tienes una nueva.

D

#4 Eso que dices es incorrecto. Ve a cualquier web, pulsa F12 (developer tools), acude a la pestaña "network", y pulsa F5... verás que hay decenas, sino cientos de peticiones, todas como lo descrito. TCP handshake, una vez abierta conexión, protocolo HTTP de toda la vida, GET HTTP/1.1, servidor responde y se cierra la conexión TCP. Esto se repite para imágenes, javascripts, css, htmls.

Precisamente el protocolo HTTP es sin estado, no hay que tener una conexión abierta persistente. Más info en https://es.wikipedia.org/wiki/Protocolo_de_transferencia_de_hipertexto

El único pero son los websockets, que se inician como HTTP, pero acaban como una conexión TCP persistente y bidireccional, que se mantiene abierta hasta que alguna de las partes hace un RST.

D

#5 Correcto.

Aunque supongo que, si hablamos de http(s) se podría usar este ataque contra servicios de descarga web, o contra servicios de streaming de vídeo, por ejemplo, que asumo que usan conexiones persistentes. Eso por mencionar servicios de alta demanda y uso común, aunque por supuesto en un entorno empresarial, y si hablamos en términos generales, hay cosas más críticas, como conexiones a BBDD, y no digamos iSCSI si usas BfS en los servidores. En general funciona contra cualquier conexión persistente que no se haga sobre IPsec, con más o menos impacto.

D

#7 No son persistentes, en cuanto la descarga acabe el servidor cierra la conexión, sigue siendo HTTP.

Conexiones persistentes son las del IRC, las de Whatsapp que reciben nuevos mensajes o notificaciones del servidor al instante de ser recibidas, websockets, etcétera.

Por otro lado los servicios de streaming de video suelen usar UDP, no TCP. Y en UDP no hay conexión alguna, da igual que los paquetes se pierdan por el camino. Más info en https://es.wikipedia.org/wiki/Protocolo_de_datagramas_de_usuario

D

#10 No conocía DASH, le echaré un vistazo, gracias por el enlace. En #9 me intento explicar mejor. Todo venía porque en las imágenes de la web de #0 ponen código HTML ....

D

#7 A ver, me explico mejor. TCP sí es persistente pero el protocolo HTTP que funciona sobre TCP hace que la conexión dure lo que dure el servidor en contestar al cliente. Si te estás bajando un fichero vía HTTP de 20Gb, podría intentarse el ataque.

Lo que identifica una conexión es IP y puerto cliente e IP y puerto del server... Conocer la IP del servidor es trivial con un nslookup, y si es vía HTTP con TLS, será al puerto 443... vale, ya tenemos dos de los 4 datos... Si conocieras la dirección IP de la victima sólo queda su puerto de origen. Hay que spoofear su dirección IP enviando paquetes al server con el flag RST haciéndote pasar por la víctima... para encontrar el puerto del cliente se usa fuerza bruta ... Probando puerto tras puerto. Cuando das con el puerto, el server acepta el RST y cierra la conexión. Es sólo esto.

Si la conexión HTTP es suficientemente duradera como para que te pueda funcionar, funcionará, sin duda. Pero en general, dura milisegundos. No olvidemos el motivo del mensaje original. En las imágenes de la web de #0 ponen código HTML ....

m

#5 Eso que dices es incorrecto, #4 tiene razón.

En HTTP 1.0 las conexiones no son persistentes salvo que se indique lo contrario con la cabecera keep-alive. En HTTP/1.1 y HTTP/2, las conexiones son persistentes por defecto salvo que se indique lo contrario. Más información en https://en.wikipedia.org/wiki/HTTP_persistent_connection

Por otro lado, al menos en mi versión de Firefox, lo único que te muestra el developer tools son las conexiones HTTP pero no el manejo TCP subyacente. Todas esas peticiones se enrutan por un único canal TCP cuando la cabecera de keep-alive está activa.

Desconozco las estadísticas de uso de la cabecera keep-alive, pero la mayoría de los sitios que conozco la tienen activa. La mejor manera de comprobarlo sería con Wireshark o similar, si capturas tráfico, vez que todas las consultas a un sitio se hacen vía un único canal TCP, conteniendo la consulta HTTP a varios recursos (html, css, js...)

D

#11 Dime una web que genere 1 petición para transmitir todo el contenido. Meneame ronda las 50 peticiones.

D

#14 Ahora os entendí. Os voto positivo. Gracias por la info!

D

#18 y #17 Sí! lo comentó #14 ya. Gracias!... de todos modos todo esto venía porque aunque sea 1 conexión TCP para hacer varias peticiones HTTP no tiene sentido hacer el ataque que se explica en #0, porque dicha conexión TCP no dura lo suficiente. Al final de la ristra de peticiones HTTP hay un RST del server ... Por lo que la conexión no se mantiene viva.

D

#22 goto #21

D

#20 goto #21.

De todos modos pensaba estar seguro!... lo bueno de comentar y que te corrijan es que se aprende. ¿No crees? Hoy aprendí una cosa nueva!

Al mensaje que replicaba no daba detalle técnico alguno, información que poder comprobar ni leer. Entiende que sin esto, uno se reafirme en lo que cree que es cierto.

R

#24 Totalmente de acuerdo en lo de aprender. Sin embargo, lo que comentas en #21, no estoy de acuerdo. No te hace falta una sesion persistente para fastidiar una peticion HTTP. Si empiezo a hacer un TCP RST en el momento en el que te veo lanzar tu primer SYN al servidor, vas a tenerlo muy complicado para poder ver cualquier pagina web. Y esto sin contar algunas conexiones HTTP mas largas, ya sea para cargar imagenes, descargar ficheros o incluso scripts y html largos que utilizan mas de un paquete. Y a todo esto no me he metido con HTTPS, donde establecer el canal TLS va a requerir multiples paquetes en ambos sentidos tipo "Client Hello" y demas.

Tampoco entiendo por que dices que al final de la peticion HTTP hay un RST. Esto no es el comportamiento por defecto, ahi deberiamos ver normalmente un FIN/ACK/FIN/ACK. Cierto que en algunas redes puedes acabar con algun dispositivo que termina lanzando un RST para "cerrar" una comunicacion, pero vamos, yo lo considero una falta de educacion.

D

#26 Pero cómo vas a ver lanzar su primer SYN TCP si no es cuando estás en medio ... (MITM). Y si estás en medio, el ataque es mucho más simple! Si no estás haciendo un MITM no puedes hacer nada ... suponer que está intentando visualizar alguna web... pero ya me diras en los milisegundos que dura la conexión TCP (contando con el keep-alive incluso), cómo vas a cortar eso!..

R

#12 http://hg.openjdk.java.net

No estoy seguro si es una sola, puede que parte del contenido vaya a otro servidor, pero si quieres probar keep-alive, ahi puedes

D

#11 En lynx se nota la diferencia entre usar HTTP/1.1 y 1.0

anv

#5 Sí, hay muchas peticiones pero si el servidor y el cliente quieren, se abre un canal TCP y se mantiene abierto para evitar tener que hacer una nueva conexión para cada petición.

Ejemplo:

Request URL: https://www.meneame.net/
Request Method: GET

Response headers:
Cache-Control: s-maxage=0, private, community="anv"
Connection: keep-alive
Content-Encoding: gzip

Ese keep-alive le dice al navegador que no cierre la conexión después del pedido. Si el navegador lo soporta, mantendrá el socket abierto y enviará más peticiones por ahí. Así se ahorra tráfico.

Avantasia

#5 #17 #20 Ya no es solo el keepalive, depende de más cosas, se han ido implementando varias técnicas, casi todas para eliminar el HoL blocking, el keepalive es una.. pero hay más.

Por una parte está el domain sharding, una técnica que escanea el HTML inicial en busca de dominios para ver qué recursos están en el mismo dominio, por otra parte está un ajuste del navegador relacionado con el máximo número de conexiones que puede realizar en paralelo al mismo servidor (o proxy), es decir, que el keepalive posibilita el uso de la misma conexión para acceder a todos los recursos en el caso óptimo, pero es posible que el navegador decida que va a lanzar 4 peticiones en paralelo (como si no existiera el ajuste keepalive) porque accede antes a los recursos, probablemente esto también depende del tipo de medio y de si puede hacer una carga parcial o no, o si se necesita hacer una precarga o no.

Eso sí, una vez agotadas las conexiones en paralelo si se podrá usar las conexiones persistentes para reutilizar esas conexiones, pero en el caso del ejemplo del ejercicio de 3 imágenes no aplica, porque la mayoría de los navegadores tienen por defecto alrededor de 6 conexiones simultaneas por defecto.

En resumen, ahora mismo, que yo sepa (por pruebas que hago de vez en cuando) solo firefox hace caso realmente al keepalive si está disponible, pero la misma prueba en Chrome y Edge pasan del ajuste totalmente y lanzan peticiones en paralelo


En el caso de HTTP/2 y HTTP/3 las conexiones persistentes ya son obligatorias, ya que solo se realiza una conexión a cada servidor y todas las peticiones son multiplexadas en modo binario sobre esa conexión.

R

#25 Esto me deja claro que me va a tocar ponerme al dia con redes algun dia de esto. Han pasado años desde que me dedicaba a ello.

Avantasia

#6 Tu petición
1- Es HTTP/1.1
2- No tiene cabeceras

Si haces nc o telnet y pegas tal cual esto (acabo de probar)

GET / HTTP/1.1
Host: www.google.com
Connection: Keep-Alive
(enter 2 veces)

te da el resultado y la conexión queda abierta, y pides después sobre la misma conexión TCP lo que te de la gana. Los navegadores hacen esto (algunos), escanean el HTML y ya reaprovechan esa conexión para pedir recursos al mismo dominio, eso no quita que dependiendo del tipo de recurso (o alguna otra consideración, la carga del navegador, max connexiones abiertas etc) puedan lanzarla en paralelo y pasar del keepalive como decia en #25.

De todas formas con HTTP/2 y 3 esto es es otra historia, y cada vez está más implementado.

R

#5 Si alguien te corrige, mas vale que estes muy seguro de lo que dices, porque en este caso me parece que estas insistiendo en el error. Todo depende de si el cliente y el servidor estan de acuerdo y establecen una peticion persistente (lo que venia siendo Connection-type: keep-alive y que se sigue poniendo "por si acaso"). Esto no estaba en el RFC de HTTP 1.0 (pero se implemento por muchos servidores y clientes como extension) pero si que forma parte de HTTP 1.1 y de hecho se considera la opcion por defecto del protocolo.

Incluyo una pequeña imagen donde se ve el trafico de wireshark, claramente un unico stream tcp con su inicio y dos peticiones http dentro. Tras eso, puede verse como se mantiene la comunicacion durante aproximadamente dos minutos mas y tras esto, la comunicacion termina Si tienes especial interes, avisame y te lo paso en formato pcap.

D

#4 Y si quieres verlo por ti mismo usa telnet contra, pongamos www.google.com

b

#6 Como tu mismo dices, en sucesivas peticiones HTTP, no necesariamente TCP que en muchos casos es persistente. Estas confundiendo peticiones HTTP y TCP.

t

#3 no siempre es así, está el keep-alive para que el servidor se quede a la espera sin cerrar la conexión y se reutilice en las siguientes peticiones, también está HTTP/2 Server push que no se si le podría afectar, pero aún así yo también veo veo mucho mas factible ataques a servicios que usan conexiones más persistentes en el tiempo tal y como comentas.

anv

Hay que tener en cuenta que esto no se puede hacer desde cualquier parte. La mayoría de los proveedores de internet bloquean tráfico que tenga IP de origen falsificada (o sea que no sea la ip de quién lo mandó realmente)

Patrañator

No aparecen las imágenes de la web,¿ a alguien más le pasa?

reivaj01

#19 Estarán haciendo ataques de reinicio para probar