Como funciona o ataque de redefinição do TCP

Um ataque de redefinição de TCP é realizado usando um único pacote de dados com tamanho não superior a alguns bytes. O segmento TCP substituído pela falsificação, criado e transmitido pelo atacante, engana as duas vítimas para encerrar a conexão TCP, interrompendo a conexão entre elas, o que pode ser crítico.


Este ataque teve consequências no mundo real. O receio de seu uso foi causado pela introdução de alterações no próprio protocolo TCP. Acredita-se que o ataque seja um componente essencial do Grande Firewall Chinês (o Escudo Dourado), usado pelo governo chinês para censurar a Internet fora da China. Apesar de sua experiência impressionante, entender os mecanismos por trás desse ataque não requer necessariamente um conhecimento profundo do TCP. Obviamente, a compreensão de suas sutilezas pode lhe ensinar muito sobre os recursos da implementação do protocolo TCP e, como veremos em breve, você pode realizar esse ataque contra si mesmo usando apenas um laptop.

Neste post nós:

  • Aprenda o básico do TCP
  • Aprenda como o ataque funciona.
  • Vamos conduzir um ataque contra nós mesmos com um script Python simples.

Antes de começarmos a analisar a mecânica do ataque, vamos primeiro ver como ele é usado no mundo real.

Como o ataque de redefinição do TCP é usado no Great Firewall?


O Great Firewall (GFW) é um conjunto de sistemas e técnicas usadas pelo governo chinês para censurar a Internet para usuários chineses internos. O GFW bloqueia e interrompe ativamente as conexões com servidores dentro e fora do país e também monitora passivamente o tráfego da Internet de conteúdo proibido.

Para impedir que os usuários se conectem a servidores proibidos, o GFW usa técnicas como poluição de DNS e bloqueio de IP(ambos custam artigos separados). No entanto, às vezes o firewall GFW precisa ter permissão para fazer uma conexão, mas depois a interrompe no meio. Por exemplo, isso é necessário se você deseja executar uma análise lenta e pendente da conexão, por exemplo, sua correlação com outras ações. Ou é usado se o firewall precisar analisar os dados trocados durante o processo de conexão e, em seguida, usar essas informações para decidir se deve continuar ou bloquear. Por exemplo, o tráfego para um site de notícias pode ser permitido, mas vídeos contendo palavras-chave proibidas serão censurados.

Para isso, o GFW precisa de ferramentas capazes de interromper conexões já estabelecidas. Uma dessas ferramentas é um ataque de redefinição de TCP.

Como um ataque de redefinição de TCP funciona?


Em um ataque de redefinição de TCP, o invasor interrompe a conexão entre as duas vítimas, enviando uma ou ambas as mensagens falsas pedindo que elas se desconectem imediatamente. Essas mensagens são chamadas de segmentos de redefinição de TCP . Em operação normal sem a participação de um invasor, os computadores enviam segmentos de descarte TCP quando recebem tráfego TCP inesperado e desejam que o remetente pare de enviá-lo.

O ataque de redefinição do TCP explora maliciosamente esse mecanismo, fazendo com que as vítimas terminem prematuramente as conexões TCP, enviando segmentos de redefinição falsos. Se o segmento de redefinição falsa for feito corretamente, o destinatário o levará para o segmento real e fechará a conexão, interrompendo a transmissão de informações adicionais nessa conexão. Para continuar a troca de dados, as vítimas podem tentar criar uma nova conexão TCP, mas o invasor pode ter a oportunidade de redefinir essa nova conexão. Felizmente, como um invasor precisa de tempo para criar e enviar um pacote falso, os ataques descartados são realmente eficazes apenas contra conexões de longo prazo. Conexões de curto prazo. por exemplo, usado para transferir pequenas páginas da web, geralmente tem tempo para cumprir sua missão até o momentoquando o atacante puder redefini-los.

O envio de segmentos TCP falsos é, de certo modo, um processo fácil, porque nem o TCP nem o IP têm suas próprias maneiras de verificar a identidade do remetente. Há uma extensão IP chamada IPSec que fornece autenticação, mas não é tão amplamente usada. Os provedores de serviços de Internet devem se recusar a transmitir pacotes IP provenientes de um endereço IP obviamente falso, mas é alegado que essa verificação é muito medíocre. Tudo o que o destinatário pode fazer é levar o endereço IP e a porta de origem dentro do pacote ou segmento pelo valor nominal e, se possível, usar protocolos de nível superior, como o TLS , para identificar o remetente . No entanto, como os pacotes de despejo TCP fazem parte do próprio protocolo TCP, eles não podem ser verificados usando esses protocolos de alto nível.

Apesar da simplicidade de enviar segmentos falsos, criar um segmento falso e executar um ataque de redefinição de TCP bem-sucedido ainda pode ser uma tarefa assustadora. Para entender por que isso acontece, precisamos entender a operação do protocolo TCP.

Como o TCP funciona


O objetivo do protocolo TCP é enviar ao destinatário uma cópia exata do bloco de dados. Por exemplo, se meu servidor envia HTML via TCP para o seu computador, a pilha TCP do seu computador (a parte do sistema operacional que processa o TCP) deve gerar meu HTML exatamente na mesma forma e ordem em que o servidor o enviou.


No entanto, meu HTML não é transmitido pela Internet de maneira perfeitamente ordenada. Ele é dividido em muitos pequenos fragmentos (chamados de segmentos TCP ), cada um dos quais é transmitido individualmente pela Internet e recriado na ordem transferida pela pilha TCP do seu computador. Essa saída restaurada é chamada de fluxo TCP . Cada segmento TCP é transmitido em seu próprio pacote IP , no entanto, para entender o ataque, não precisamos saber detalhes sobre o IP.


A conversão de segmentos em um fluxo requer cuidados, porque a Internet não é confiável. Os segmentos TCP podem ser perdidos. Eles podem ficar fora de ordem, enviados duas vezes, danificados e sofrer muitas outras desventuras. Portanto, o objetivo do protocolo TCP é garantir a transmissão confiável de dados em uma rede não confiável. O TCP executa essa tarefa, exigindo que os dois lados da conexão mantenham contato próximo entre si e transmitam constantemente informações sobre quais blocos de dados foram recebidos. Isso permite que os remetentes entendam quais dados o destinatário ainda não recebeu e retransmitam os dados perdidos.

Para entender como o processo funciona, precisamos entender como os remetentes e receptores usam números de sequência TCP para marcar e rastrear dados transmitidos por TCP.

Números de sequência TCP


Cada byte transmitido por uma conexão TCP possui um número de sequência atribuído pelo remetente. As máquinas receptoras usam números de série para mover os dados recebidos para o pedido original.


Quando duas máquinas negociam uma conexão TCP, cada máquina envia outro número de seqüência inicial aleatória . Este é o número de sequência que a máquina atribuirá ao primeiro byte enviado. Cada byte subseqüente recebe o número de sequência do byte anterior mais 1. Os segmentos TCP contêm cabeçalhos TCP , que são metadados anexados ao início do segmento. O número de sequência do primeiro byte no corpo do segmento está incluído no cabeçalho TCP deste segmento.

Deve-se notar que as conexões TCP são bidirecionais, ou seja, os dados podem ser transmitidos em ambas as direções, e cada máquina em uma conexão TCP atua como remetente e destinatário. Por esse motivo, cada máquina deve atribuir e processar seu próprio conjunto independente de números de sequência.

Confirmação de recebimento de dados


Quando uma máquina recebe um segmento TCP, informa ao remetente do segmento que foi recebida. O destinatário faz isso enviando um segmento ACK(abreviação de "reconhecer"), contendo o número de sequência do próximo byte que ele espera receber do remetente. O remetente usa essas informações para entender que o destinatário recebeu com êxito todos os outros bytes até esse número.

Um segmento é ACKindicado pela presença de um sinalizador ACKe o número de confirmação correspondente no cabeçalho TCP do segmento. Existem apenas 6 sinalizadores no protocolo TCP, incluindo (como veremos em breve) um sinalizador RST(abreviação de "reset" - "reset"), indicando o segmento de redefinição.


Nota: O TCP também permite o uso de ACKs seletivos , que são transmitidos quando o receptor recebe alguns, mas não todos, segmentos no intervalo de números. Por exemplo, "recebi os bytes 1000-3000 e 4000-5000, mas não 3001-3999". Por simplicidade, não considerarei ACKs seletivos em nossa discussão sobre ataques de redefinição de TCP.

Se o remetente transmitir dados, mas não receberACKpara eles durante um determinado intervalo de tempo, ele assume que os dados foram perdidos e os reenvia, fornecendo os mesmos números de série. Isso significa que, se o receptor aceita os mesmos bytes duas vezes, ele usa trivialmente os números de sequência para se livrar das duplicatas sem interromper o fluxo. O destinatário pode aceitar dados duplicados porque o segmento original foi recebido posteriormente, depois que foi enviado novamente ou porque o segmento original foi recebido com êxito, mas o correspondente foi ACKperdido no caminho para o remetente.


Embora esses dados duplicados sejam raros o suficiente, o desperdício excessivo de recursos causado por eles não leva a problemas. Se todos os dados ACKchegarem mais cedo ou mais tarde ao destinatário e os dados correspondentes chegarem ao remetente, a conexão TCP fará seu trabalho.

Escolhendo um número de série para um segmento falso


Ao criar um segmento falso, o RSTinvasor precisa fornecer um número de série. Os destinatários estão satisfeitos com o fato de você precisar aceitar segmentos com números de série inconsistentes e conectá-los independentemente na ordem correta. No entanto, suas capacidades são limitadas. Se o destinatário receber um segmento com um número de sequência "muito" avariado, ele descartará esse segmento.

Portanto, para um ataque de redefinição de TCP bem-sucedido, é necessário um número de sequência plausível. Mas o que é considerado esse número? Para a maioria dos segmentos (embora, como veremos mais adiante, não para RST), a resposta é determinada pelo tamanho da janela TCP .

Tamanho da janela TCP


Imagine um computador antigo do início dos anos 90, conectado a uma moderna rede de fibra óptica de gigabit. Uma rede ultrarrápida pode transferir dados para este computador idoso a uma velocidade incrível, mais rapidamente do que a máquina pode processá-lo. Isso nos incomoda, porque o segmento TCP não pode ser considerado recebido até que o receptor possa processá-lo.


Os computadores têm um buffer TCP no qual novos dados que chegam aguardam processamento enquanto o computador está trabalhando nos dados que chegam antes dele. No entanto, esse buffer tem um tamanho limitado. Se o destinatário não conseguir lidar com a quantidade de dados transmitidos a ele pela rede, o buffer será excedido. Quando o buffer está cheio, o destinatário não tem escolha a não ser livrar-se dos dados redundantes. O destinatário não envia ACKdados descartados; portanto, o remetente precisa reenviá-los quando houver espaço livre no buffer do destinatário. Não importa a rapidez com que a rede pode transmitir dados se o destinatário não tiver tempo para lidar com eles.

Imagine um amigo excessivamente zeloso que envia para você um fluxo inteiro de cartas mais rápido do que você pode ler. Há um certo espaço de reserva dentro da sua caixa de correio, mas depois que estiver cheio, todas as cartas não colocadas cairão no chão, onde raposas e outras criaturas as comerão. Um amigo terá que reenviar as cartas que ele comeu, mas, por enquanto, você terá tempo para receber as mensagens anteriores. Enviar muitas cartas ou volumes de dados que o destinatário não pode processar é um desperdício de energia e canal de transmissão.

"Demais" - quantos dados são? Como o remetente entende quando enviar mais dados e quando vale a pena esperar? É aqui que o tamanho da janela TCP é útil.. O tamanho da janela do destinatário é o número máximo de bytes não reconhecidos que o remetente pode transferir para ele a qualquer momento. Suponha que o destinatário relate que o tamanho da janela é 100.000 (em breve descobriremos como ele passa esse valor); portanto, o remetente envia 100.000 bytes. Suponha que, no momento em que o remetente transmitisse cem milésimos de byte, o receptor enviasse os segmentos ACKpara os primeiros 10.000 desses bytes. Isso significa que 90.000 bytes ainda não foram confirmados. Como o tamanho da janela é 100.000, o remetente pode transferir outros 10.000 bytes antes de esperar pelos novos ACK. Se após o envio desses 10.000 bytes adicionais aindaACKse não foi recebido, o remetente terá o limite de 100.000 bytes não confirmados. Conseqüentemente, o remetente terá que esperar e parar de enviar dados (exceto a retransmissão de dados que ele considera perdidos) até receber novos ACK.


Cada lado da conexão TCP notifica o outro sobre o tamanho de sua janela durante o processo de handshake que é realizado quando a conexão é aberta. Além disso, os tamanhos das janelas podem ser alterados dinamicamente durante o processo de conexão. Um computador com um buffer TCP grande pode anunciar um tamanho de janela grande para maximizar a taxa de transferência. Isso permite que a máquina que se comunica com ela transmita dados continuamente por uma conexão TCP sem pausar ou aguardar confirmação. Um computador com um pequeno buffer TCP pode ser forçado a relatar um tamanho de janela pequeno. Às vezes, os remetentes preenchem completamente a janela e são forçados a esperar até que alguns dos segmentos sejam confirmados. A largura de banda sofre por causa disso, mas é necessário que os buffers TCP não excedam.


O tamanho da janela TCP é um limite estrito da quantidade de dados não confirmados transmitidos. Podemos usá-lo para calcular o número máximo possível de sequências (que na equação abaixo designei como max_seq_no), que o remetente pode enviar no momento atual:

max_seq_no = max_acked_seq_no + window_size

max_acked_seq_no- Esse é o número máximo de sequência para o qual o destinatário enviou ACK. Esse é o número máximo de sequência que o remetente sabe que recebeu exatamente. Como o remetente pode transmitir apenas window_sizebytes não confirmados, o número máximo de sequência que pode enviar é max_acked_seq_no + window_size.

Por esse motivo, a especificação TCP afirma que o destinatário deve ignorar todos os dados recebidos que possuam números de série fora da janela válida. Por exemplo, se o destinatário tiver confirmado todos os bytes de até 15.000 e o tamanho da janela for 30.000, ele receberá todos os dados com um número de série no intervalo de 15.000 a (15.000 + 30.000 = 45.000). Além disso, o destinatário ignora completamente os dados com números de série fora desse intervalo. Se o segmento contiver dados, alguns dos quais estão dentro desta janela e outros fora dela, os dados dentro da janela serão aceitos e confirmados, mas os dados externos serão descartados. Observe que ainda ignoramos a possibilidade das seletivasACK que foram brevemente tocadas no início do post.

No caso da maioria dos segmentos TCP, essa regra nos fornece um intervalo de números de sequência aceitáveis. No entanto, como mencionado anteriormente, as RSTrestrições impostas aos segmentos são ainda mais rígidas do que as restrições aos segmentos comuns de transmissão de dados. Como veremos em breve, isso foi feito para complicar a condução de uma variante de um ataque de redefinição de TCP chamado "ataque de redefinição de TCP cego" .

Números de sequência aceitáveis ​​para segmentos RST


Segmentos regulares são aceitos se o número de sequência estiver entre o próximo número de sequência esperado e esse número mais o tamanho da janela. No entanto, os pacotes RSTsão recebidos apenas quando o número de sequência é exatamente igual ao próximo número de sequência esperado. Voltemos ao exemplo anterior, no qual o destinatário enviou o número de confirmação 15.000. Para que o pacote RSTseja recebido, seu número de sequência deve ser exatamente 15.000. Se o destinatário receber um segmento RSTcom um número de sequência diferente de 15.000, ele não o aceitará.


Se o número de sequência estiver fora do intervalo, o receptor o ignorará completamente. No entanto, se estiver dentro da janela dos números de sequência esperados, o receptor envia um "desafio ACK" ("chamada ACK"). Este é um segmento que informa ao remetente que o segmento RSTtem um número de sequência inválido. Ele também informa ao remetente o número de sequência que o destinatário espera. O remetente pode usar essas informações da ACKchamada para recriar e reenviar as dele RST.

Até 2010, o TCP não impunha essas restrições adicionais de segmento RST. Os segmentos foram RSTaceitos ou rejeitados de acordo com as mesmas regras que os demais. No entanto, isso também simplificou os ataques cegos de redefinição do TCP .

Ataques TCP cegos


Se o invasor puder interceptar o tráfego trocado entre suas vítimas, ele poderá ler os números de série e confirmação dos pacotes TCP das vítimas. Ele pode usar essas informações para selecionar quais números de série fornecer aos seus segmentos falsos RST. No entanto, se o atacante não puder interceptar o tráfego das vítimas, ele não saberá quais números de sequência inserir. Mas ele ainda pode transferir qualquer número de segmentos RSTcom qualquer número de série diferente, esperando que um deles esteja correto. Esse ataque é chamado de ataque cego de redefinição de TCP.

Como já dissemos, na versão inicial do protocolo TCP, o invasor apenas precisou pegar o número de sérieRSTdentro da janela TCP do receptor. Um artigo intitulado “Deslizando pela janela” mostrou que isso tornava os ataques cegos muito fáceis, pois, para um sucesso quase garantido, um invasor só precisava enviar dezenas de milhares de segmentos. Para combater isso, a regra que forçou o destinatário a aceitar o segmento RSTfoi substituída pelo critério mais rigoroso descrito acima. Graças às novas regras para realizar ataques de redefinição de TCP, milhões de segmentos precisam ser enviados às cegas, o que os torna praticamente irrealizáveis. Veja RFC-5963 para detalhes .

Realizar um ataque de redefinição de TCP contra nós mesmos


Nota: Testei esse processo no OSX, mas recebi alguns comentários de que ele não funciona corretamente no Linux.

Agora sabemos tudo sobre a execução de um ataque de redefinição de TCP. O atacante deve:

  • Assista ao tráfego de rede ( "cheirar" ) entre duas vítimas
  • Cheire o segmento TCP com o sinalizador ativado ACKe leia seu número confirmado
  • Crie um segmento TCP falso com o sinalizador ativado RSTe um número de sequência igual ao número confirmado do segmento interceptado (observe que isso implica uma transmissão lenta; caso contrário, o número de sequência selecionado ficará rapidamente desatualizado. (Para aumentar as chances de sucesso, você pode transferir vários segmentos RSTcom um grande intervalo de números de sequência) .)
  • Envie segmentos falsos para uma ou ambas as vítimas, esperando que isso interrompa a conexão TCP

Para praticar, vamos realizar um ataque TCP contra nós mesmos no mesmo computador, comunicando-nos através de nós localhost. Para isso, precisamos:

  1. Configurar conexão TCP entre duas janelas de terminal
  2. Escreva um programa de ataque que lide com o tráfego de sniffing
  3. Modifique o programa para que ele produz e envie segmentos falsos RST.

Vamos começar.

1. Estabelecendo uma conexão TCP entre duas janelas do terminal


Vamos configurar a conexão TCP usando a ferramenta netcat, que por padrão está disponível em muitos sistemas operacionais. Qualquer outro cliente TCP fará . Na primeira janela do terminal, executaremos o seguinte comando:

nc -nvl 8000

Este comando inicia um servidor TCP que está escutando uma porta em nossa máquina local 8000. Na segunda janela do terminal, execute o seguinte comando:

nc 127.0.0.1 8000

Este comando tenta criar uma conexão TCP com a máquina pelo endereço IP da 127.0.0.1porta 8000. Agora, entre as duas janelas do terminal, uma conexão TCP deve ser estabelecida. Tente inserir algo em uma janela - os dados terão que ser transmitidos pela conexão TCP e aparecer em outra janela.


2. Cheirar o tráfego


Escreveremos um programa de ataque que executa a detecção de tráfego usando a scapypopular biblioteca de rede Python. Este programa usa scapy para ler dados transferidos entre duas janelas do terminal, embora não faça parte da conexão.

O código do programa é publicado no meu repositório no GitHub . O programa fareja o tráfego de conexão e o exibe no terminal. O núcleo principal do código é a chamada de método sniffda biblioteca scapylocalizada no final do arquivo:

t = sniff(
        iface='lo0',
        lfilter=is_packet_tcp_client_to_server(localhost_ip, localhost_server_port, localhost_ip),
        prn=log_packet,
        count=50)

Este trecho de código nos diz scapypara cheirar pacotes na interface lo0e capturar detalhes de todos os pacotes como parte de nossa conexão TCP. A chamada possui os seguintes parâmetros:

  • iface- ordens scapypara ouvir a interface de rede lo0ou host local
  • lfilter — , scapy , IP- localhost . , , lo0. , .
  • prn — , scapy , lfilter. . , RST.
  • count — , scapy .

Para testar este programa, configure a conexão TCP da etapa 1. Clone meu repositório GitHub, siga as instruções de configuração e execute o programa na terceira janela do terminal. Digite algum texto em um dos terminais da conexão TCP. Você deve ver que o programa começará a registrar informações sobre os segmentos de conexão.

3. Enviando pacotes falsos RST


Estabelecemos uma conexão e o programa pode detectar todos os segmentos TCP que passam por ela. A única coisa que resta é modificar o programa para que ele execute um ataque de redefinição de TCP transmitindo segmentos falsos RST. Para fazer isso, mudaremos a função prn(veja a lista de parâmetros acima), chamada scapyde pacotes que atendem aos requisitos da função lfilter. Na versão modificada da função, em vez de simplesmente consertar o pacote correspondente, estudamos, extraímos os parâmetros necessários e usamos esses parâmetros para criar e enviar o segmento RST.

Suponha que tenhamos interceptado um segmento que vai de (src_ip, src_port)k (dst_ip, dst_port). Ele tem um sinalizador definido ACKe o número de confirmação é 100.000. Para fabricar e enviar um segmento, nós:

  • IP- , . , . , .
  • RST , , RST
  • , ,
  • send scapy — .

Para modificar nosso programa anterior, conforme necessário, remova o comentário desta linha e comente a linha acima.

Agora estamos prontos para um ataque em grande escala. Configure a conexão TCP de acordo com a etapa 1. Execute o programa de ataque da etapa 2 na terceira janela do terminal. Em seguida, digite algum texto em um dos terminais da conexão TCP. No terminal em que você digitou o texto, a conexão TCP será interrompida repentina e misteriosamente. O ataque está feito!


Trabalho adicional


  1. Continue experimentando com a ferramenta de ataque. Acompanhe o que acontece se você adicionar ou subtrair 1 do número de sequência do pacote RST. Verifique se ele deve ser exatamente igual ao valor do ackpacote interceptado.
  2. Wireshark lo0 . TCP-, RST. ip.src == 127.0.0.1 && ip.dst == 127.0.0.1 && tcp.port == 8000 .
  3. , . RST, RST , . , RST, .


O ataque de redefinição do TCP é profundo e simples ao mesmo tempo. Boa sorte com suas experiências e deixe-me saber se você tiver perguntas ou comentários.

All Articles