DDOS et schtroumpf SNMP
|Vous avez très certainement entendu parler de l’attaque menée par CyberBunker contre Spamhaus et par effet de ricochet contre Cloudflare, qui a faillit “casser l’internet” pour reprendre les termes utilisés sur le blog de CloudFlare.
Encore plus fort que les inénarrables reboots cinématographiques qui permettent à nos stars d’antan de faire un bref et flamboyant retour sur le devant de la scène. CyberBunker a remis au goût du jour une attaque qui n’avait plus trop fait parler d’elle depuis que les équipements réseaux ont appris que relayer un ping en direction d’une adresse de broadcast c’est caca ! L’attaque des schtroumpfs, nommons là ainsi, et rétablissons une injustice faite lors de cette énième traduction ratée du nom donné par nos amis anglophones smurf attack… Oui parce que attaque par rebond/réflexion c’est un peu ternichon vous ne trouvez pas ?…
Le concept de cette attaque n’est pas inédit, il s’agit d’une adaptation informatique du principe de levier. Archimède disait « Πα βω και χαριστιωνι ταν γαν κινησω πασαν », ce que nous, hommes contemporains, traduisons par « Donnez-moi un protocole non connecté et assez de machines qui le comprennent, et je mettrais à genou l’internet ». Dans le cas de Spamhaus vs CyberBunker, le point d’appui était l’aggloméra de serveurs DNS hippies sous MDMA trop enclin à discuter avec n’importe qui. Il était en effet possible à tout un chacun de faire appel à leurs services… Mais plutôt que de vous contenter du résumé un poil désuet que je pourrais produire, et avant de vous plonger dans mon adaptation de cette attaque, je vous suggère de lire l’analyse de CloudFlare expliquant les tenants et aboutissants de toute cette histoire.
Abracada-schtroumpf SNMP
Si vous êtes au fait des articles que j’ai proposé jusque là, vous êtes certainement au courant de ma liaison sulfureuse avec SNMP. C’est donc tout naturellement que j’en suis venu à essayer d’adapter cette attaque à ce protocole. Rien d’exclusif dans le petit POC que je vais vous présenter, mais je gage que certains y trouveront tout de même leur compte ! :)
La première chose à faire, je ne vous l’apprends pas si vous avez lu l’article du blog CloudFlare, est de trouver le moyen de modifier l’adresse IP source des paquets que nous allons émettre durant l’attaque. Cette donnée est contenue dans l’entête IP, et correspond normalement à l’adresse de la carte réseau émettrice. Nous allons la remplacer par celle de notre cible, on parlera alors d‘IP spoofing. Aucune application pernicieuse n’est nécessaire pour réaliser cette permutation. Une simple utilisation d’iptables nous permet de mettre en place le subterfuge :
iptables -t nat -I POSTROUTING -s 192.168.1.42 -p udp --dport 161 -j SNAT --to 192.168.1.247
L’adresse IP de ma machine “offensive” est 192.168.1.42 et l’adresse IP de ma cible est 192.168.1.247. Cette astucieuse règle permet de remplacer mon adresse par celle de la cible, si et seulement si les paquets sont émis en UDP vers le port 161, ce qui correspond classiquement au protocole SNMP. Il est possible de vérifier votre entrée iptables avec cette commande :
iptables -t nat --list [...] Chain POSTROUTING (policy ACCEPT) target prot opt source destination SNAT udp -- 192.168.1.42 anywhere udp dpt:snmp to:192.168.1.247 SNAT udp -- 192.168.1.42 anywhere udp dpt:snmp to:192.168.1.247
Vous commencez à connaître la forme que revêtent la plupart de mes articles. Voici donc venu le temps des captures Wiresharks, cette fois pour illustrer deux choses : l’adresse source a bien été modifiée (bien que ce ne soit pas forcément évident au regard de ces deux captures… Mea culpa, je tâcherai de faire mieux la prochaine fois). Et, il est possible de générer une réponse plus volumineuse que la requête, élément crucial pour ce type d’attaque (oui parce que ce serait enfoncer des portes ouvertes qu’utiliser cette attaque pour générer 20kb/s de trafic sur notre cible en émettant à 20kb/s depuis notre machine offensive) .
La requête SNMP qui va nous permettre d’augmenter significativement notre puissance de frappe est la dénommée GetBulk ! L’agent SNMP que nous allons interroger se trouve à l’adresse 192.168.1.16.
snmpbulkget -v2c -c public 192.168.1.16 1
Capture coté attaquant (192.168.1.42)
La requête est émise chaque seconde tant que le client n’a pas reçu de réponse, au bout de cinq secondes (ou six requêtes), l’action est abandonnée. Comme nous altérons l’adresse IP source de nos paquets SNMP, le serveur visé répond à notre cible plutôt qu’à nous (hé-bé-oui, c’est le but beindiou !), notre client ne reçoit donc pas les réponses attendues, ce qui explique ces six paquets SNMP de type GetBulk. Chaque requête à un coût de 78 bits.
Capture coté cible (192.168.1.247)
Ces six requêtes entraînent six réponses de 271 bits, soit une augmentation de 347% du trafic généré par notre machine attaquante. A cela s’ajoute les réponses ICMP Destination Unreachable de notre cible pesant chacune 299 bits, exprimant à l’équipement intermédiaire (celui répondant aux requêtes SNMP) une certaine incompréhension quant-à la réception de ces paquets, effectivement aucun service n’écoute le port SNMP(161) sur la machine cible.
Proof 0x0ff Concept
Maintenant que l’efficacité théorique de l’attaque des schtroumpfs version SNMP est démontrée, je vous propose une petite commande très très bête permettant de générer un peu de trafic vers la cible de votre choix :
while true; do for i in {1..254}; do perl -e "print system(\"snmpbulkget -v2c -c public 192.168.1.$ENV$i 1 &\");"; done; done
Cette commande a valeur de démonstration. Bien que permettant de produire un peu de charge sur une interface réseau, dans le cas où le protocole SNMP serait massivement utilisé sur la plage ciblée, elle n’est pas exploitable dans l’état. Pour que l’attaque soit “rentable”, il est nécessaire de limiter l’émission des GetBulk aux seules machines capables d’y répondre ! En effet, la bande passante utilisée pour générer des paquets inutiles est de la bande passante gaspillée. D’autre part, les commandes systèmes sont affreusement lentes ! En revanche, l’utilisation de librairies/frameworks dédiés (Scapy par exemple), ou tout simplement l’utilisation des Raw Sockets peut constituer une solution efficace !