Pingo da morte! FreeBSD corrige bug crashtastic na ferramenta de rede PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Pingo da morte! FreeBSD corrige bug crashtastic na ferramenta de rede

Uma das primeiras ferramentas de rede de baixo nível que qualquer usuário de computador aprende é o venerável ping utilidade.

Nomeado após o efeito sonoro homônimo de toda e qualquer cena de filme de guerra da velha escola envolvendo submarinos, o comando é um eco metafórico (viu o que fizemos lá?) Da versão subaquática do RADAR conhecida como SONAR.

Você envia um ping (mais como um barulho de doinnnng, em realidade) nas profundezas salgadas e medindo quanto tempo leva para seu eco misterioso voltar para você e estimando a velocidade do som no oceano circundante, você pode calcular a distância até o objeto que produziu o eco.

Curiosamente, dado que você provavelmente já ouviu a abreviatura TCP/IP usada como uma descrição genérica da cola de protocolo que alimenta a internet, ping tecnicamente não usa TCP/IP.

Na verdade, TCP/IP é a abreviação de protocolo de controle de transmissão sobre o protocolo de internet, e refere-se a um mecanismo de alto nível para enviar dados pela Internet de forma que a própria rede coloque muito do “isso realmente funcionou corretamente?” esforço por você.

Por exemplo, em conexões TCP, todos os blocos de dados que você envia têm a garantia de chegar intactos na outra extremidade ou causar um erro para que você saiba que eles não chegaram.

Além disso, mesmo que diferentes blocos de dados acabem tomando rotas diferentes pela Internet (por exemplo, devido a balanceamento de carga, interrupções temporárias ou outros erros recuperáveis) e mesmo que alguns blocos demorem mais para chegar do que outros, os dados TCP serão armazenados em buffer corretamente para cima e apresentados na ordem certa na outra extremidade.

O ping é diferente

A ping O comando, no entanto, é normalmente usado para verificar se um computador no qual você está interessado está online, especialmente se não estiver aceitando o tipo de conexões TCP de alto nível que você esperaria, como receber e-mail ou permitir logins SSH.

Isso ajuda a determinar rapidamente se uma interrupção é provável devido à queda da rede ou do próprio servidor, ou devido a falhas na inicialização correta de serviços individuais em execução nesse servidor.

Como resultado, ping usa um protocolo de nível muito inferior ao TCP.

Com efeito, ping nem usa o UDP, primo mais casual do TCP, abreviação de protocolo de datagrama do usuário, que é uma forma de transmitir blocos de dados que é rápida e fácil, mas é popularmente conhecida como send-and-hope (ou, se você for um tipo cínico, como spray-and-pray).

O próprio UDP não informa se seus dados chegaram ao outro lado ou não e, mesmo que cheguem intactos, o UDP não rastreia a ordem em que seus pacotes foram originalmente enviados, portanto, não pode reorganizá-los em a outra ponta se eles chegarem fora da sequência.

Ping, pelo que vale a pena, usa um protocolo de nível muito baixo, especialmente projetado para solução de problemas e fins de reconfiguração de rede, conhecido como ICMP, ou protocolo de mensagem de controle de internet.

Normalmente tratado diretamente no kernel do sistema operacional, de modo que os pacotes ICMP/IP tenham quase certeza de passar, mesmo que nenhum software de rede de nível superior tenha surgido corretamente, o ICMP inclui notavelmente dois tipos de mensagens especiais:

  • Digite 0x08. Oficialmente chamado ICMP Echo, Este tipo de pacote geralmente é chamado de Solicitação de eco. é o que ping programa envia para sondar computadores ativos na rede.
  • Digite 0x00. Oficialmente chamado ICMP Echo Reply, este tipo de pacote é exatamente o que diz. Um computador que está ativo, online e não configurado para bloquear o tráfego ICMP Echo deve enviar esse tipo de pacote diretamente para o computador que o solicitou.

Gosto disto:

$ ping -c 3 -p 4E414B45445345435552495459 nakedsecurity.sophos.com PADRÃO: 0x4e414b45445345435552495459 PING news-sophos.go-vip.net (192.0.66.227) 56(84) bytes de dados. 64 bytes de 192.0.66.227 (192.0.66.227): icmp_seq = 1 ttl = 53 tempo = 84.0 ms 64 bytes de 192.0.66.227 (192.0.66.227): icmp_seq = 2 ttl = 53 tempo = 85.1 ms 64 bytes de 192.0.66.227 .192.0.66.227 (3): icmp_seq=53 ttl=84.8 tempo=3 ms --- news-sophos.go-vip.net estatísticas de ping --- 3 pacotes transmitidos, 0 recebidos, 2004% de perda de pacote, tempo 84.025ms rtt min/ média/máx/mdev = 84.644/85.062/0.446/XNUMX ms

Para ver um ping em ação em um nível um pouco mais baixo, usaremos o código Lua que você encontra no final do artigo para construir nosso próprio pacote ICMP Echo e ler a resposta que retorna, se houver:

$ sudo luax ping.lua nakedsecurity.sophos.com Enviando solicitação ICMP ECHO para 192.0.66.227 --> 00000000 08 00 03 02 bb 5a 6f 1d 50 69 6e 67 52 65 71 75 |.....Zo.PingRequ| 00000010 65 73 74 4d 65 73 73 61 67 65 20 42 42 35 41 36 |estMensagem BB5A6| 00000020 46 31 44 |F1D | Voltei--> 00000000 45 00 00 37 f6 af 00 00 35 01 94 7f c0 00 42 e3 |E..7....5.....B.| 00000010 XX XX XX XX 00 00 0b 02 bb 5a 6f 1d 50 69 6e 67 |.........Zo.Ping| 00000020 52 65 71 75 65 73 74 4d 65 73 73 61 67 65 20 42 |SolicitarMensagem B| 00000030 42 35 41 36 46 31 44 |B5A6F1D |

A propósito, precisávamos usar sudo acima para executar nosso script com privilégios de superusuário, porque criamos o que é conhecido como soquete IP bruto – um que pode ser criado em qualquer formato subjacente que desejarmos, incluindo TCP, UDP e, conforme necessário aqui, ICMP.

Em muitos sistemas Linux/Unix, o ping comando fornecido por sua distro funciona sem privilégios de root explicitamente, geralmente porque é instalado com recursos de segurança especiais ou com seu setuid sinalizador definido, o que significa que ele começa a ser executado em uma conta de usuário diferente do usuário que o executou.

Bem desenhado ping os programas, é claro, descartarão automaticamente seus privilégios extras assim que abrirem o soquete bruto de que precisam.

Omitimos esse código de redução de privilégios de nosso script de amostra para fins de brevidade. Você pode usar o posix.unistd.setpid() função para alternar para uma conta sem privilégios depois de criar o soquete, mas antes de enviar ou receber dados.

Examinando a resposta

Como você pode reconhecer no despejo de dados de nosso script acima, a função de soquete de rede que estamos usando para ler os dados do servidor de resposta inclui não apenas os dados de resposta de eco ICMP, mas também o IP de baixo nível (cabeçalhos de protocolo da Internet) no pacote subjacente.

Não tentamos analisar ou processar esses dados, mas o FreeBSD ping o programa precisa fazer isso para entender a resposta, incluindo a compreensão de quaisquer mensagens de erro que retornarem.

Se o ping for rejeitado de alguma forma, o Echo Reply normalmente incluirá não apenas seus próprios cabeçalhos IP (como visto acima), mas também uma cópia de referência dos cabeçalhos IP e os dados ICMP que apareceram na solicitação de saída original.

Os cabeçalhos de pacotes IPv4 geralmente se parecem muito com o que você vê acima, onde os cabeçalhos IP começam com 45 00 00 37... e continue por 20 bytes no total, até e incluindo os bytes mostrados como ...XX XX XX XX, que é o endereço IP do meu laptop.

Gosto disto:

00000000 45 00 00 37 f6 af 00 00 35 01 94 7f c0 00 42 e3 |E..7....5.....B.| 00000010 XX XX XX XX |.... | Versão IP e comprimento do cabeçalho: 0x45 (4 = IPv4, 5 = cinco palavras de 32 bits, ou seja, 20 bytes Tipo de serviço e dados de congestionamento: 0x00 Comprimento total do pacote: 0x0037 (decimal 55) Informações de sequência: F6 AF 00 00 Tempo para -live (salto para a esquerda): 0x35 (decimal 53) Tipo de protocolo: 0x01 (ICMP) Soma de verificação: 0x947F (decimal 38015) Número IP do computador remetente: C0 00 42 E3 (192.0.66.227 = nakedsecurity.sophos.com) IP do destinatário (meu laptop): XX XX XX XX (REDIGIDO = meu próprio número IP)

FreeBSD's ping os programadores, ao que parece, presumiram que cabeçalhos desse tipo sempre teriam exatamente 20 bytes de comprimento, com base no valor do comprimento do cabeçalho no primeiro byte de 0x45, denotando IPv4 (0x4?) com um 5-DWORD (0x?5) ou cabeçalho de 20 bytes.

Com apenas 20 bytes para se preocupar, os programadores alocaram buffers de tamanho fixo na pilha onde poderiam manter uma cópia dos cabeçalhos IP na resposta, além de quaisquer cabeçalhos IP incorporados da solicitação original, se houvesse uma condição de erro para lidar .

Você pode adivinhar onde isso está indo.

Esse primeiro byte no cabeçalho IPv4 pode legalmente ter qualquer valor de 0x45 (o tamanho mínimo do cabeçalho de 5 DWORDs ou 20 bytes, conforme mostrado) até 0x4F (indicando 15 DWORDs, porque 0xF é decimal 15 ou 60 bytes de dados de cabeçalho no total), permitindo assim 40 bytes extras opcionais de dados de cabeçalho.

Esses bytes de cabeçalho extras raros, mas legais, podem ser usados ​​para vários “recursos” estranhos e incomuns com nomes curiosos, como Transmissão Direcionada Seletiva, Controle de Fluxo Experimental e Pacote Multicast Upstream – coisas que ouvimos falar, mas nunca usamos conscientemente, ou mesmo vimos.

Cuidado com os cibercriminosos que colocam você à prova

Como você pode imaginar, como esses campos extras quase nunca são usados, talvez você nunca veja um pacote IPv4 com algo diferente de 0x45 no início e com 20 bytes de dados de cabeçalho no total, a menos que você encontre um bando de cibercriminosos que estão prontos para colocá-lo à prova.

Infelizmente, não há muito que impeça um invasor de armar um servidor que adivinha se você está usando o FreeBSD e deliberadamente gera pacotes ICMP/IP Echo Reply superdimensionados para provocar um estouro de buffer de pilha dentro de sua ping .

Se alguma vez você verificar se o servidor deles está ativo (o que você pode fazer, ou talvez especialmente, se achar que é suspeito!), Você pode ser alvo de uma resposta armadilhada.

Na melhor das hipóteses, seu ping o programa irá travar; na pior das hipóteses, no entanto, como o aviso de segurança do FreeBSD generosamente admite, “pode ser possível que um host mal-intencionado acione a execução remota de código no ping.”

Felizmente, como os autores do FreeBSD também fazem notar, neste artigo, “[o] processo de ping é executado em uma caixa de proteção do modo de capacidade em todas as versões afetadas do FreeBSD e, portanto, é muito limitado em como pode interagir com o restante do sistema no ponto em que o bug pode ocorrer.”

Em outras palavras, você definitivamente precisa corrigir, mas os riscos podem ser considerados modestos.

Notavelmente, o ping O programa não está apenas bloqueado em uma caixa de proteção, mas também não está sendo executado como root quando o código com bugs é alcançado, conforme confirmado no comunicado de segurança: "Quando ping é executado, ele cria o soquete bruto necessário para fazer seu trabalho e, em seguida, revoga seus privilégios elevados.

Conforme descrito acima, os poderes do superusuário são necessários apenas para adquirir um soquete IP bruto do sistema operacional, não para usar o sendto() e recvfrom() funções nesse soquete posteriormente.

Este bug recebeu o identificador oficial CVE-2022-23093; está documentado no comunicado de segurança FreeBSD-SA-22:15.ping.

O que fazer?

  • Se você é um usuário do FreeBSD, simplesmente atualize as versões afetadas (FreeBSD 12 e FreeBSD 13) para suas versões mais recentes, onde esse bug foi corrigido.
  • Se você é um programador de rede, certifique-se sempre de ter contabilizado cabeçalhos de pacotes que possam indicar variações incomuns de tamanho. O fato de você nunca ter visto nenhuma variação não o impede de enfrentar amanhã um pacote fora do comum, mas perfeitamente legal.
  • Se você é um gerente de rede, considere bloquear pacotes IPv4 com cabeçalhos IP que não tenham 20 bytes de tamanho. Se você realmente precisa permitir que alguns produtos de software usem opções de cabeçalho IPv4 incomuns, considere registrar esses pacotes incomuns para saber o motivo.

Tome cuidado lá fora!


EXEMPLO DE CÓDIGO PARA DEMONSTRAR TRÁFEGO PING


Carimbo de hora:

Mais de Segurança nua