Tecnología, Internet y juegos
120 meneos
2558 clics
¿Cómo funciona un ataque de reinicio de TCP? [ING]

¿Cómo funciona un ataque de reinicio de TCP? [ING]

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.

| etiquetas: tcp , ataque de reinicio , paquetes falsificados , seguridad
62 58 0 K 284
62 58 0 K 284
  1. El artículo no lo dice, pero además de los chinos este ataque por lo visto fue utilizado por Comcast para joder conexiones de Bittorrent de sus clientes, qué majos:

    en.wikipedia.org/wiki/TCP_reset_attack#Comcast_Controversy
    www.eff.org/wp/packet-forgery-isps-report-comcast-affair
  2. #1 Pues la FCC por eso le pueden crujir. Interrupción de comunicaciones -> multaza . Y en EEUU las multas son individuales, no colectivas.
  3. 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.
  4. #3 No exactamente, normalmente se usan conexiones persistentes para hacer varias peticiones al mismo servidor. Ten en cuenta que una página web moderna igual tiene 10 scripts, tres o cuatro hojas de estilos y 20 imágenes. Tener que establecer una conexión TCP para pedir cada uno de los recursos es más lento que mantener la conexión abierta y reusarla para pedir varias cosas seguidas.
  5. #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 <recurso_que_se_quiere_solicitar> 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 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.
  6. #4 Y si quieres verlo por ti mismo usa telnet contra, pongamos www.google.com:

    ~ $ telnet www.google.com 80
    Trying 216.58.211.228...
    Connected to www.google.com.
    Escape character is '^]'.
    GET / HTTP1.1 <------- Esta es mi petición

    HTTP/1.0 400 Bad Request <------- cabeceras de respuesta del servidor. Vemos que hay error en mi petición. Y que el body tiene mimetype text/html
    Content-Type: text/html; charset=UTF-8
    Referrer-Policy: no-referrer
    Content-Length: 1555
    Date: Wed, 29 Apr 2020 07:32:34 GMT

    <!DOCTYPE html> <------- este es el body de la respuesta
    <html lang=en>
    <meta charset=utf-8>
    <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
    <title>Error 400 (Bad Request)!!1</title>
    <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (webkitmin-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
    </style>
    <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
    <p>400. <ins>That’s an error.</ins>
    <p>Your client has issued a malformed or illegal request. <ins>That’s all we know.</ins>
    Connection closed by foreign host. <----- servidor cierra conexión, tras la respuesta.

    Este ejemplo es el primer request que el navegador que uses siempre hace. Si el body contiene otros recursos (como en el ejemplo que puse), como imágenes, javascripts y css, el cliente vuelve a requerir mediante sucesivos requests esos recursos adicionales referenciados en el documento html original, causando lo que describí, decenas de requests que uno tras otro van haciéndose con todos los recursos necesarios para visualizar correctamente dicha web.
  7. #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.
  8. #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 es.wikipedia.org/wiki/Protocolo_de_datagramas_de_usuario
  9. #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 ....
  10. #8 No son persistentes, en cuanto la descarga acabe el servidor cierra la conexión, sigue siendo HTTP.

    Si la descarga dura 1 hora, y te hacen un ataque de estos, tiene impacto. Y si se lo hacen a todos los usuarios de una web de descargas, básicamente en un DoS en toda regla.

    Por otro lado los servicios de streaming de video suelen usar UDP, no TCP.

    Pues al menos Netflix (hay otros) usa DASH, que es básicamente partir peticiones MPEG en trocitos y enviarlas sobre HTTP, es decir, sobre TCP. Más info en en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP
  11. #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 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...)
  12. #11 Dime una web que genere 1 petición para transmitir todo el contenido. Meneame ronda las 50 peticiones.
  13. #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 ....
  14. #12 1 petición HTTP ninguna, 1 única conexión TCP, todas las que tengan la cabecera Content: keep-alive. Mismamente, Meneame tiene activada dicha cabecera y todas las peticiones HTTP se rutan a través de una única conexión TCP.

    Como Meneame usa https es dificil capturar el tráfico, aunque si lo capturas con Wireshark ves una única conexión TCP sobre la que se multiplexan varias peticiones y respuestas HTTP al mismo sitio.

    Sin embargo, si capturas tráfico de una web HTTP se ve como sobre la misma conexión TCP se multiplexan varias peticiones HTTP. Por ejemplo, si capturas el tráfico de dbfmkchsnlrxtvwz.neverssl.com/online verás que hace 2 peticiones HTTP /online y /favicon.ico sobre la misma conexión TCP. Puedes descargar la captura de tráfico en we.tl/t-R7f6VLXu3w y comprobarlo con Wireshark. Obviamente, el resto de peticiones que hace (A platform.twitter.com y syndication.twitter.com) son dos conexiones TCP diferentes, pero las 2 peticiones que hace a platform.twitter.com también son multiplexadas en una única conexión TCP (Que no adjunto por ser SSL y no poder distinguirse el tráfico). Es decir, para visitar dicho sitio web, se hacen 5 peticiones HTTP ruteadas a través de 3 sockets TCP.

    Si lo miras en el inspector ves que son 5 peticiones HTTP pero en ningún momento el inspector (al menos en mi versión de Firefox) habla de conexiones TCP. Sin embargo, si capturas tráfico con Wireshark, ves como son solo 3 sockets, es decir, que el socket TCP persiste y es utilizado para seguir mandando subsecuentes peticiones HTTP, que es lo que decía #4.
  15. #14 Ahora os entendí. Os voto positivo. Gracias por la info!
  16. 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)
  17. #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: 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.
  18. #6 Como tu mismo dices, en sucesivas peticiones HTTP, no necesariamente TCP que en muchos casos es persistente. Estas confundiendo peticiones HTTP y TCP.
  19. No aparecen las imágenes de la web,¿ a alguien más le pasa?
  20. #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.  media
  21. #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.
  22. #12 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
  23. #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.
  24. #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.
  25. #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.
  26. #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.
  27. #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.
  28. #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.
  29. #11 En lynx se nota la diferencia entre usar HTTP/1.1 y 1.0
  30. #19 Estarán haciendo ataques de reinicio para probar
  31. #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!..
comentarios cerrados

menéame