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
en.wikipedia.org/wiki/TCP_reset_attack#Comcast_Controversy
www.eff.org/wp/packet-forgery-isps-report-comcast-affair
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.
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.
~ $ 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.
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.
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
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 ....
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
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...)
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.
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.
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.
No estoy seguro si es una sola, puede que parte del contenido vaya a otro servidor, pero si quieres probar keep-alive, ahi puedes
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.
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.
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.
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.