Résumé

  • Le mode UDP de serveurs memcached exposés permettait à une requête minuscule, portant l’adresse falsifiée d’une victime, de provoquer une réponse sans commune mesure vers cette victime.
  • La correction durable ne relève pas d’un acteur unique : le logiciel a désactivé UDP par défaut, les réseaux d’accès peuvent arrêter l’usurpation à la source et GitHub a gardé la main sur la détection, les routes et le recours au filtrage externe.

Un service de cache transformé en pouvoir d’émission

Memcached n’était pas censé être un service public. Son domaine naturel était le réseau de confiance d’une application, où la vitesse comptait davantage qu’une cérémonie de connexion. Mais UDP répond sans établir que l’adresse apparente de l’émetteur reçoit effectivement le retour. Dès qu’un cache acceptait des paquets venus d’Internet, cette propriété devenait une délégation involontaire.

Cloudflare a décrit l’enchaînement observé en 2018 : déposer d’abord une grande valeur dans un cache accessible, puis envoyer une petite commande get avec l’adresse de la cible comme source falsifiée. Dans un essai, 15 octets ont déclenché 134 Ko de réponse. Dans une observation distincte, 15 octets ont produit 750 Ko, soit un rapport de 51 200. Ce ne sont pas des constantes applicables à chaque serveur. Ce sont deux preuves du mécanisme : l’attaquant sollicite peu son propre accès et fait payer au cache tiers la majeure partie du débit.

Deux défauts opérationnels devaient donc coexister. Le cache devait répondre en UDP à un inconnu, et un réseau devait laisser sortir un paquet portant une adresse que son client n’avait pas le droit d’utiliser.

Le récit précis de GitHub

Le 28 février 2018, GitHub.com a été indisponible de 17 h 21 à 17 h 26 UTC, puis de manière intermittente jusqu’à 17 h 30. GitHub a précisé que la confidentialité et l’intégrité des données n’avaient pas été menacées.

Le pic a atteint 1,35 Tbit/s et 126,9 millions de paquets par seconde. Les réponses venaient de dizaines de milliers de points répartis dans plus de mille systèmes autonomes. Ces chiffres appartiennent à l’incident GitHub ; ils ne décrivent ni tous les caches memcached ni toutes les attaques utilisant ce vecteur.

L’alerte est partie d’un rapport anormal entre entrée et sortie. Lorsqu’un site a reçu plus de 100 Gbit/s sur ses liens de transit, GitHub a décidé de transférer le trafic vers Akamai. À 17 h 26, son outil ChatOps a retiré les annonces BGP envoyées aux transitaires et annoncé AS36459 uniquement par les liens Akamai. Après reconvergence, des listes de contrôle d’accès ont filtré l’attaque à la frontière d’Akamai. Le service était rétabli à 17 h 30.

À 17 h 34, GitHub a également retiré ses routes des points d’échange, déplaçant 40 Gbit/s supplémentaires. Un second pic d’environ 400 Gbit/s est survenu après 18 heures. L’entreprise a annoncé vouloir automatiser davantage l’activation des prestataires anti-DDoS. Le rapport prouve cette intention, pas sa réalisation ultérieure.

Cette chronologie vaut mieux qu’un record spectaculaire. Elle montre ce que la victime pouvait réellement décider : voir son propre bord, modifier ses propres annonces, choisir un partenaire et mesurer le retour du service. Elle ne pouvait pas reconfigurer pendant l’attaque des milliers de caches appartenant à d’autres.

Le correctif tenait dans le comportement initial

La version 1.5.6 de memcached, publiée le 27 février, annonçait principalement la désactivation d’UDP par défaut. Le commit correspondant change settings.udpport de 11211 à 0. Il supprime aussi l’activation implicite d’UDP lorsque seul le port TCP est indiqué. Les tests ont été modifiés avec le code.

UDP n’a pas disparu. Un exploitant qui en avait besoin pouvait le réactiver avec -U 11211. C’est précisément pourquoi ce correctif illustre une spécification commune minimale. Le projet a supprimé une autorisation dangereuse donnée par l’inaction, sans interdire un choix local assumé.

Le numéro de version ne suffit pourtant pas. Un paquet, une unité de service ou une option locale peut rouvrir UDP. À l’inverse, un ancien binaire peut rester privé derrière une liaison et un pare-feu corrects. La preuve utile est extérieure : le service en fonctionnement répond-il à une requête UDP non fiable sur le port 11211, et avec quel volume ?

Running-Code Primacy oblige à distinguer annonce et état. La note de version exprime un choix. Le diff l’inscrit dans l’exécutable. Les tests en fixent l’attente. Seuls l’inventaire des sockets, la configuration effective et une sonde extérieure montrent l’adoption sur une machine donnée.

L’adresse source falsifiée est une frontière de réseau

La fermeture des caches retire le multiplicateur. La validation de l’adresse source retire le mensonge qui dirige le multiplicateur vers une victime.

Le BCP 38, publié sous la forme du RFC 2827, recommande au fournisseur d’accès de n’accepter depuis un réseau client que les paquets portant des préfixes que ce client utilise légitimement. Près du point d’agrégation, un paquet qui prétend venir de GitHub alors qu’il sort d’un autre client doit être rejeté.

Le principe est étroit ; la topologie peut être complexe. Le RFC 3704 traite des réseaux multihébergés et des routes asymétriques. Il compare listes d’accès, contrôle strict du chemin inverse, chemin faisable et variantes plus souples. Une règle stricte mal adaptée peut éliminer du trafic légitime. Une vérification trop lâche peut confirmer l’existence d’une route sans vérifier le droit de ce client à utiliser l’adresse.

La décision future doit donc rester localisée. Chaque opérateur choisit le mécanisme compatible avec ses routes, automatise les mises à jour et documente les exceptions. Mais il ne peut remplacer le résultat par une déclaration : il doit montrer qu’un client ne peut pas exporter l’identité source d’un tiers.

Aucun contrôle ne rembourse les deux autres

L’exploitant du cache doit prouver l’absence d’exposition ou la limitation de la réponse. Le réseau d’origine doit prouver son filtrage anti-usurpation. La victime doit prouver qu’elle peut détecter, dérouter, filtrer et revenir à la normale.

Le nettoyage chez un prestataire protège la victime après émission du trafic ; il n’empêche pas le cache de répondre. La désactivation d’UDP supprime un réflecteur ; elle ne corrige pas l’usurpation sur le réseau de départ. Le BCP 38 arrête de nombreuses requêtes falsifiées ; il ne donne pas à GitHub un plan de continuité. Cette séparation des responsabilités est une force, à condition que chaque frontière fournisse une preuve observable.

La coordination n’exige pas de souverain. GitHub a choisi Akamai pour une route de crise. Akamai n’a pas acquis le droit permanent de décider des annonces de GitHub. Le projet memcached a fixé un défaut plus sûr sans administrer les réseaux de ses utilisateurs. Les RFC décrivent une pratique commune sans exécuter une seule commande de routeur.

Limites de preuve

Les sources établissent le mécanisme, le pic mesuré par GitHub et le changement du défaut logiciel. Elles ne montrent pas que chaque instance memcached était publique, que chaque réponse valait 51 200 requêtes, ni que le flux reçu par GitHub reproduisait l’essai de Cloudflare. Elles ne prouvent pas non plus une adoption universelle du BCP 38.

La leçon demeure précise. Une valeur par défaut peut autoriser silencieusement une dépense de bande passante ; un bord non filtré peut prêter l’identité d’une victime ; une entreprise ne récupère vite que si ses commandes locales sont déjà prêtes. Le texte conseille. Le code et le trafic révèlent l’autorité réelle.

Sources