Ping de mort ! FreeBSD corrige un bug crashtastic dans l'outil réseau PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Ping de la mort ! FreeBSD corrige un bogue crashtastic dans l'outil réseau

L'un des premiers outils réseau de bas niveau que tout utilisateur d'ordinateur découvre est le vénérable ping utilitaire.

Nommée d'après l'effet sonore éponyme de toutes les scènes de films de guerre à l'ancienne impliquant des sous-marins, la commande est un écho métaphorique (vous voyez ce que nous avons fait là-bas ?) de la version sous-marine de RADAR connue sous le nom de SONAR.

Vous envoyez un p-i-n-g (plutôt un bruit de do-i-n-n-n-n-g, en réalité) dans les profondeurs saumâtres, et en mesurant le temps qu'il faut pour que son étrange écho vous revienne, et en estimant la vitesse du son dans l'océan environnant, vous pouvez calculer la distance jusqu'à l'objet qui a produit l'écho.

Curieusement, étant donné que vous avez probablement entendu l'abréviation TCP/IP utilisée comme description générique du protocole qui alimente Internet, ping techniquement, n’utilise pas du tout TCP/IP.

En fait, TCP/IP est l'abréviation de protocole de contrôle de transmission sur le protocole Internet, et fait référence à un mécanisme d'assez haut niveau permettant d'envoyer des données sur Internet de telle manière que le réseau lui-même ajoute une grande partie de la question « est-ce que cela a réellement fonctionné correctement ? un effort pour vous.

Par exemple, dans les connexions TCP, tous les morceaux de données que vous envoyez sont garantis soit d'arriver intacts à l'autre extrémité, soit de provoquer une erreur afin que vous sachiez qu'ils ne l'ont pas fait.

De plus, même si différents fragments de données finissent par emprunter des itinéraires différents sur Internet (par exemple en raison d'un équilibrage de charge, de pannes temporaires ou d'autres erreurs récupérables), et même si certains fragments mettent plus de temps à arriver que d'autres, les données TCP seront correctement mises en mémoire tampon. et présentés dans le bon ordre à l’autre bout.

Le ping est différent

La ping La commande, cependant, est généralement utilisée pour vérifier si un ordinateur qui vous intéresse est en ligne, surtout s'il n'accepte pas le type de connexions TCP de haut niveau que vous attendez, comme la réception d'e-mails ou l'autorisation des connexions SSH.

Cela vous aide rapidement à déterminer si une panne est susceptible d'être due à une panne du réseau ou du serveur lui-même, ou à un échec de démarrage correct des services individuels exécutés sur ce serveur.

En conséquence, ping utilise un protocole de niveau beaucoup plus bas que TCP.

En effet, ping n'utilise même pas le cousin plus décontracté de TCP, UDP, abréviation de protocole de datagramme utilisateur, qui est un moyen de transmettre des blocs de données rapide et facile, mais communément appelé envoyer et espérer (ou, si vous êtes cynique, pulvériser et prier).

UDP lui-même ne vous informe pas si vos données sont parvenues à l'autre extrémité ou non, et même si elles arrivent intactes, UDP ne garde pas la trace de l'ordre dans lequel vos paquets ont été envoyés à l'origine, il ne peut donc pas les réorganiser. l'autre extrémité s'ils arrivent dans le désordre.

Ping, pour ce que ça vaut, utilise un protocole de très bas niveau, spécialement conçu à des fins de dépannage et de reconfiguration du réseau, connu sous le nom d'ICMP, ou protocole de message de contrôle Internet.

Généralement géré directement dans le noyau du système d'exploitation, de sorte que les paquets ICMP/IP soient presque certains de passer même si aucun logiciel réseau de niveau supérieur n'est apparu correctement, ICMP inclut notamment deux types de messages spéciaux :

  • Tapez 0x08. Appelé officiellement ICMP Echo, Ce une sorte de paquet est généralement appelée une demande d'écho. C'est ce que le ping Le programme envoie afin de rechercher des ordinateurs actifs sur le réseau.
  • Tapez 0x00. Appelé officiellement ICMP Echo Reply, ce type de paquet est exactement ce qu'il dit. Un ordinateur actif, en ligne et non configuré pour bloquer le trafic ICMP Echo est censé renvoyer ce type de paquet directement à l'ordinateur qui l'a demandé.

J'aime ça:

$ ping -c 3 -p 4E414B45445345435552495459 Nakedsecurity.sophos.com MODÈLE : 0x4e414b45445345435552495459 PING news-sophos.go-vip.net (192.0.66.227) 56(84) octets de données. 64 octets de 192.0.66.227 (192.0.66.227) : icmp_seq=1 ttl=53 temps=84.0 ms 64 octets de 192.0.66.227 (192.0.66.227) : icmp_seq=2 ttl=53 temps=85.1 ms 64 octets de 192.0.66.227 .192.0.66.227 (3) : icmp_seq=53 ttl=84.8 temps=3 ms --- statistiques ping de news-sophos.go-vip.net --- 3 paquets transmis, 0 reçus, 2004 % de perte de paquets, temps 84.025 ms rtt min/ moy/max/mdev = 84.644/85.062/0.446/XNUMX ms

Pour voir un ping en action à un niveau légèrement inférieur, nous utiliserons le code Lua que vous pouvez trouver à la fin de l'article pour construire notre propre paquet ICMP Echo, et pour lire la réponse qui revient, le cas échéant :

$ sudo luax ping.lua Nakedsecurity.sophos.com Envoi de la requête ICMP ECHO au 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 |estMessage BB5A6| 00000020 46 31 44 |F1D | Je suis revenu -> 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 |DemandeMessage B| 00000030 42 35 41 36 46 31 44 |B5A6F1D |

Au fait, nous devions utiliser sudo ci-dessus pour exécuter notre script avec les privilèges de superutilisateur, car nous avons créé ce qu'on appelle un prise IP brute – un format qui peut être conçu dans n'importe quel format sous-jacent que nous aimons, y compris TCP, UDP et, si nécessaire ici, ICMP.

Sur de nombreux systèmes Linux/Unix, le ping La commande fournie par votre distribution fonctionne sans explicitement bénéficier des privilèges root, généralement parce qu'elle est installée avec des fonctionnalités de sécurité spéciales, ou avec son setuid indicateur défini, ce qui signifie qu'il commence par s'exécuter sous un compte utilisateur différent de celui de l'utilisateur qui l'a exécuté.

Bien conçu ping les programmes, bien sûr, supprimeront automatiquement leurs privilèges supplémentaires une fois qu’ils auront ouvert le socket brut dont ils ont besoin.

Nous avons omis ce code de suppression de privilèges de notre exemple de script par souci de concision. Vous pouvez utiliser le posix.unistd.setpid() fonction pour passer à un compte non privilégié après la création du socket, mais avant d'envoyer ou de recevoir des données.

Examiner la réponse

Comme vous pouvez le constater dans le vidage des données de notre script ci-dessus, la fonction de socket réseau que nous utilisons pour relire les données du serveur répondant inclut non seulement les données ICMP Echo Reply, mais également l'IP de bas niveau (en-têtes de protocole Internet). dans le paquet sous-jacent.

Nous n'avons pas essayé d'analyser ou de traiter ces données, mais FreeBSD ping le programme doit le faire pour donner un sens à la réponse, y compris pour donner un sens aux messages d'erreur qui reviennent.

Si la ping est rejetée d'une manière ou d'une autre, la réponse Echo inclut généralement non seulement ses propres en-têtes IP (comme vu ci-dessus), mais également une copie de référence des en-têtes IP et des données ICMP apparaissant dans la demande sortante d'origine.

Les en-têtes de paquets IPv4 ressemblent généralement à ce que vous voyez ci-dessus, où les en-têtes IP commencent par 45 00 00 37... et continuez sur 20 octets au total, jusqu'aux octets indiqués comme suit : ...XX XX XX XX, qui est l'adresse IP de mon ordinateur portable.

J'aime ça:

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 |.... | Version IP et longueur d'en-tête : 0x45 (4 = IPv4, 5 = cinq mots de 32 bits, soit 20 octets Type de service et données de congestion : 0x00 Longueur totale du paquet : 0x0037 (décimal 55) Informations de séquence : F6 AF 00 00 Time-to -live (sauts à gauche) : 0x35 (décimal 53) Type de protocole : 0x01 (ICMP) Somme de contrôle : 0x947F (décimal 38015) Numéro IP de l'ordinateur d'envoi : C0 00 42 E3 (192.0.66.227 = Nakedsecurity.sophos.com) IP du destinataire (mon ordinateur portable) : XX XX XX XX (SUPPRIMÉ = mon propre numéro IP)

FreeBSD ping les programmeurs, semble-t-il, ont supposé que les en-têtes de ce type auraient en effet toujours une longueur exacte de 20 octets, sur la base de la valeur de longueur d'en-tête dans le premier octet de 0x45, désignant IPv4 (0x4?) avec un 5-DWORD (0x?5), ou en-tête de 20 octets.

Avec seulement 20 octets à gérer, les programmeurs ont alloué des tampons de taille fixe sur la pile où ils pouvaient conserver une copie des en-têtes IP dans la réponse, ainsi que tous les en-têtes IP intégrés à la requête d'origine, s'il y avait une condition d'erreur à gérer. .

Vous pouvez deviner où cela va.

Ce premier octet de l'en-tête IPv4 peut légalement avoir n'importe quelle valeur de 0x45 (la taille d'en-tête minimale de 5 DWORDs, ou 20 octets, comme indiqué) jusqu'à 0x4F (indiquant 15 DWORD, car 0xF est un nombre décimal de 15, soit 60 octets de données d'en-tête au total), permettant ainsi parfaitement 40 octets supplémentaires en option de données d'en-tête.

Ces octets d'en-tête supplémentaires rares, mais légaux, peuvent être utilisés pour diverses « fonctionnalités » géniales et inhabituelles avec des noms curieux tels que Diffusion dirigée sélective, Contrôle de flux expérimental ainsi que Paquet de multidiffusion en amont – des choses dont nous avons entendu parler mais que nous n’avons jamais utilisées sciemment, ni même vues.

Méfiez-vous des cybercriminels qui vous mettent à l'épreuve

Comme vous pouvez l'imaginer, étant donné que ces champs supplémentaires ne sont presque jamais utilisés, vous ne verrez peut-être jamais de paquet IPv4 contenant autre chose que 0x45 au début, et avec 20 octets de données d’en-tête au total, à moins que vous ne rencontriez une bande de cybercriminels prêts à vous mettre à l’épreuve.

Malheureusement, il n'y a pas grand-chose pour empêcher un attaquant de configurer un serveur qui devine si vous utilisez FreeBSD et génère délibérément des paquets de réponse d'écho ICMP/IP surdimensionnés afin de provoquer un message d'erreur. débordement de la mémoire tampon de la pile l'intérieur de votre ping .

Si jamais vous vérifiez si leur serveur est actif (ce que vous pourriez faire même, ou peut-être surtout, si vous pensez que c'est suspect !), vous pourriez être ciblé par une réponse piégée.

Au mieux, votre ping le programme va planter ; au pire, cependant, comme l'admet généreusement l'avis de sécurité de FreeBSD, "Il peut être possible qu'un hôte malveillant déclenche l'exécution de code à distance en ping."

Heureusement, comme les auteurs de FreeBSD signaler, "[l]e processus ping s'exécute dans un bac à sable en mode capacité sur toutes les versions concernées de FreeBSD et est donc très limité dans la façon dont il peut interagir avec le reste du système au point où le bug peut survenir."

En d’autres termes, vous devez absolument appliquer des correctifs, mais les risques peuvent être considérés comme modestes.

Notamment, le ping Le programme est non seulement verrouillé dans un bac à sable, mais ne s'exécute pas en tant que root lorsque le code buggé est atteint, comme le confirme l'avis de sécurité : "Quand ping s'exécute, il crée le socket brut nécessaire pour effectuer son travail, puis révoque ses privilèges élevés.

Comme décrit ci-dessus, les pouvoirs de superutilisateur sont requis uniquement pour acquérir un socket IP brut auprès du système d'exploitation, et non pour utiliser le socket IP brut. sendto() ainsi que recvfrom() fonctionne ensuite sur cette prise.

Ce bug a reçu l'identifiant officiel CVE-2022-23093; c'est documenté dans l'avis de sécurité FreeBSD-SA-22:15.ping.

Que faire?

  • Si vous êtes un utilisateur FreeBSD, mettez simplement à jour les versions concernées (FreeBSD 12 et FreeBSD 13) vers leurs dernières versions, où ce bug est corrigé.
  • Si vous êtes un programmeur réseau, assurez-vous toujours que vous avez pris en compte les en-têtes de paquets qui pourraient indiquer des variations de taille inhabituelles. Le fait que vous n’ayez jamais constaté de variation vous-même ne vous empêche pas d’être confronté demain à un paquet hors du commun et pourtant parfaitement légal.
  • Si vous êtes un gestionnaire de réseau, envisagez de bloquer les paquets IPv4 avec des en-têtes IP d’une taille inférieure à 20 octets. Si vous semblez réellement avoir besoin d'autoriser certains produits logiciels à utiliser des options d'en-tête IPv4 inhabituelles, envisagez de consigner ces paquets inhabituels pour savoir pourquoi.

Faites attention là-bas!


EXEMPLE DE CODE POUR DÉMONTRER LE TRAFIC PING


Horodatage:

Plus de Sécurité nue