Gruger le routeur facilement

Jean-François GOUDE .

Mon site web a été attaqué récemment. Ce n'est ni la première, ni sans doute la dernière fois que cela se produit. Il s'agit d'un site d'informations destiné à une communauté de joueurs. Il n'y a ni argent à dérober ni technologie à voler. Comme il est sauvegardé tous les jours et qu'il est (plutôt) bien protégé, je n'ai pas de raisons d'être particulièrement inquiet. Lorsque ce genre d'attaques se produit, je n'ai, en principe, qu'à attendre que l'agresseur se lasse ...

routeur-joomla

N'empêche que cette fois-ci, les choses étaient un peu différentes :

  • d'abord mon hébergeur s'est (à jute titre ?) inquiété de l'ampleur des choses et a coupé l'accès à mon site ... plutôt désagréable, n'est ce pas ?
  • j'étais en vacances loin de chez moi et ne pouvais accédé à l'administration Joomla!, au cPanel et même à FTP que par des réseaux publiques : pas ce qu'il y a de mieux en ce qui concerne la gestion des sécurités.
  • l'attaque a été largement plus violente que les fois précédentes au point de justifier (?) la fermeture du site et il me semblait intéressant d'en faire une analyse post-mortem.

Les faits.

L'attaque a commencé le 4 octobre à 14h00 environ. Le site a reçu environ 6500 connexions (contre une centaine par jour en temps normal), bien entendu, l'adresse IP de l’agresseur changeait à chaque passe de même que le pays de rattachement de cette IP. A 18h00 mon hébergeur me signalait que le site dépassait la quantité autorisée dans une journée à la fois pour le nombre de scripts exécutés et pour l'utilisation de la bande passante, en conséquence de quoi il fermait provisoirement celui-ci. Suite à ma réaction indignée (après tout un bon firewall est du ressort de l'hébergeur), le site était ré ouvert une petite demi-heure avant d'être à nouveau fermé jusqu'à environ 1h00 du matin le 5 octobre, heure à laquelle l'attaque était stoppée grâce à une parade ingénieuse autant qu'efficace mise en oeuvre par Christophe Avonture auteur (entre-autre) du logiciel aeSecure.

J'ai déjà par le passé subi des attaques de ce type allant jusqu'à 13000 connexions en moins de 24 heures, pas souvent, Dieu merci, mais jamais mon site n'avait été fermé par l'hébergeur. Alors qu'y avait-il donc de spécial au cours de cette attaque ?

En fait l'agresseur (vous noterez que je ne parle pas de hacker. Un hacker essaie de s'introduire dans un site qui ne lui appartient pas, ici la suite nous montrera que ce n'était absolument pas le souhait de l'imb... qui a lancé l'attaque) a lancé 933123 fois une requête http, sous deux formes distincte mais dont la principale retournait plus de 315 000 caractères en réponse. Soit un total de 7 GB de bande passante en peu de temps.

Numéro spécial e-commerce & Joomla!

14,60 € l'unité E-commerce & joomla! - Édition papier
9,20 € l'unité E-commerce & joomla! - Ebook

Première analyse

Quelle est donc cette requête 'magique' qui a mis mon site à plat ? L'analyse des fichiers logs montre que c'est essentiellement une requête constituée avec le libellé :

http://www.monsite.fr/archives/56-everquest-ii/administrator/

Cette requête mène vers des résultats étonnants, si l'on affiche le log d'une seule adresse IP émettrice l'utilisant on obtient :

92.242.108.122 - - [04/Oct/2016:14:01:38 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 301 278 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"
92.242.108.122 - - [04/Oct/2016:14:01:38 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 301 278 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"
92.242.108.122 - - [04/Oct/2016:14:01:39 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 301 278 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"
92.242.108.122 - - [04/Oct/2016:14:01:39 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 200 315120 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"
92.242.108.122 - - [04/Oct/2016:14:01:39 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 200 315120 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"
92.242.108.122 - - [04/Oct/2016:14:01:43 +0200] "GET /archives/56-everquest-ii/administrator/ HTTP/1.0" 200 315120 "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36"

Evidemment, la première réaction lorsque l'on voit la fin de l'URL  : /administrator/ est  : "il s'agit d'une tentative de pénétration et d'accès aux privilèges de super administrateur" mais cette url n'a pas d'existence légale, ne donne en aucun cas accès à l'administration et devrait juste retourner une erreur 404, or elle retourne un (voire plusieurs) code 301 : redirection permanente et après 3 redirection successives, elle mène à des retours d'information de 315 Ko à chaque fois, il y a bien des données affichables, données qui proviennent effectivement de mon site, affichant un contenu qui existe bel et bien mais qui n'a jamais été de manière préméditée, conçu pour être affiché et surtout pas avec une telle URL.

Redirection permanente ? bien,  mais vers quoi et pour quelle raison ?

Il est intéressant de comprendre cette url, qui vue de l'administrateur n'existe pas. Mon site n'utilise pas de composants du style sh404SEF et le fichier .htaccess ne contient que quelques redirections bien maîtrisées. Une tentative en désactivant provisoirement le composant Redirection de Joomla! reste sans effet. Le code 301 de redirection permanente ne vient donc pas du site lui-même.

Si la redirection n'est pas provoquée par le site, cela ne peut donc être que Joomla! lui-même qui le génère ...

Retour aux bases : le routeur.

Le composant de Joomla! qui analyse les URLs saisies par les utilisateurs et les transforme à coup de redirection pour en générer une URL finale, compréhensible par le serveur Apache s'appelle pour Joomla! le routeur et son comportement est décrit en détail dans un document officiel qui fait force de loi et est en quelque sorte la bible du traitement des URLs, tant par Joomla! lui-même que par les fournisseurs de composants tiers. Ce document est décrit dans un article de la documentation officielle de Joomla .

Ce document dit très exactement (mais en anglais !) :

Le premier segment d'un routage est, pour les URL régulières, l'alias d'un élément de menu. L'URL SEF est réputée acheminée à travers cet élément de menu. Les autres segments sont entièrement déterminées par le routeur du composant qui fournit le type de l'élément de menu. La Catégorie - Blog type d'élément de menu, par exemple, est fourni par le composant de contenu, et donc le routeur de ce composant est responsable de la construction et de l'analyse les segments restants. 

Dans le cas présent :

  • 56-everquest-ii est le nom d'une catégorie de mon site (ou presque !) sous la forme id-alias de catégorie.
  • administrator pourrait être le mode de présentation ou à défaut de la responsabilité du module routeur en ce qui concerne l'interprétation de l'affichage à effectuer.

Bien ceci dit :

  • c'est vrai, j'ai un menu dont le nom et l'alias sont : archives
  • everquest-ii est bien le nom et l'alias d'une catégorie de mon site, mais 56 n'est pas son id (l'id de cette catégorie est 42, 56 correspond à une sous-catégorie de everquest-ii).

Bizarrement l'article ou le pseudo-article affiché (ça ressemble plutôt à un affichage de blogs des catégories) reprend tout un ensemble d'articles (on a quand même 315 Ko de données) mais n'a rien à voir de près ou de loin avec la catégorie everquest-ii ni avec les articles rattachés à cette catégorie ! ?

Jouons un peu avec le routeur

Première étape, j'envoie la même URL mais sans l'alias de menu 'archives' dedans. Formidable, ça marche toujours : toujours pas d'erreur 404 mais c'est un autre ensemble d'articles qui est affiché, toujours sous la forme blog des catégories.

Continuons, j'envoie maintenant juste l'URL /monsite.fr/56-everquest-ii, toujours pas d'erreur, j'obtiens l'affichage d'un autre article n'ayant rien à voir avec les précédents, pire, n'envoyer comme URL que : /monsite.fr/56 fonctionne également et affiche la même chose (le libellé ou plus exactement l'alias de libellé associé à la catégorie n'est pas utilisé : le routeur ne fait aucun contrôle entre l'id et l'alias de libellé !).

Cette fois c'est clair, c'est le routeur qui est en cause et qui fait absolument n'importe quoi, ou qui fait pour le moins autre chose que ce que l'on est en droit d'attendre de lui au vu des prescriptions de la bible des développeurs.

 

Revenons au départ  et fabriquons de toute pièce des URLs :

  • /monsite.fr/test/56- marche pareillement (bien sûr cette fois-ci je n'ai absolument pas de menu 'test' ni en tant que libellé, ni en tant que alias, d'ailleurs "monsite.fr/xyz/56-" ou "monsite.fr/truc/56-" donnent exactement le même résultat) et affiche l'article d'id 56
  • /monsite.fr/56-/blabla affiche une liste de type blog des catégories (la catégorie 56, toujours sans se préoccuper de l'alias de cette catégorie dont la présence n'est d'ailleurs même pas nécessaire dans l'url) blabla doit lui toutefois exister, sa présence conditionne le passage en blog de la catégorie.

Pourtant la bible du routeur dit clairement :

Pour un élément de menu, Joomla! utilise l'alias de l'URL comme emplacement. Supposons que vous utilisez les deux premières options d'URL SEF et vous créez un élément de menu appelé Products. Votre URL serait example.com/products

En fait une URL quelconque /xyz/id- affiche l'article d'id id et lui seul tout à fait correctement qu'il y ait ou non un libellé après l'id et que ce libellé soit compatible ou pas avec un alias d'article que cet alias existe ou pas
/id- voir même /id affiche exactement le même article (et bien sûr tout ça vu du côté google : c'est du duplicate content, puisque pour des URLs différentes on a le même contenu)

Résumons :

  • /test/id ou /test/id- affiche l'article id dans le format standard prévu pour le site. L'existence ou pas d'un menu de libellé ou alias test est sans importance.
  • /id-/blabla affiche une liste des articles correspondant à la catégorie d'id 'id' et à ceux de même catégorie au format blog. Que blabla prenne la valeur administrator, machin ou n'importe quoi d'autre existant sans lien direct avec la catégorie id.
  • /xyz/id/blabla est le seul cas particulier où l'on obtient dans tous les cas une erreur 404 sauf s'il y a bien un menu xyz, dans ce cas alors, quelque soit la valeur de blabla, c'est le type d'affichage du blog de la catégorie id qui est affiché, comme ci-dessus sans tenir compte de la présence ou pas du menu xyz d'ailleurs.

Conclusion

Alors c'est vrai, il faut bien le reconnaître, certaines des affirmations ci-dessus marchent plus ou moins bien selon les sites, en fonction (probablement) du contenu du fichier .htaccess, de la présence ou non de certains composants (sh404SEF entre autre ou ses équivalents) et selon leur paramétrage bien sûr, certaines URLs 'fabriquées' de toute pièce retournent (ou pas) une erreur 404. Vous pouvez d'ailleurs essayer certains cas de figure comme ceux donnés ci-après. Il n'en est pas moins vrai, que toutes ces URLs manipulées devraient dans tous les cas de figure retourner une erreur 404. On est loin du compte. De là à dire que le routeur facilite le travail des hackers ...

Exemple d'URLs qui devraient retourner une erreur 404 mais qui fonctionnent en donnant des résultats pas forcément attendus par leurs auteurs :

Il semble que la version Joomla! 3.7 qui doit paraître en décembre va supprimer ou tout au moins donner l'opportunité de supprimer l'id d'article et/ou de catégorie dans une URL. C'est un gros pas en avant qui nécessitera très certainement de faire pas mal de redirections pour éviter les erreurs 404 générées par des vraies URLs du coup dépréciées, mais cela fermera une porte d'entrée aux nuisibles de toutes sortes, qui pour le moment peuvent générer très facilement des URLs au hasard jusqu'à trouver, comme cela à sans doute été le cas pour mon site, une url qui fournisse en retour un flux suffisamment important pour pénaliser le serveur qui reçoit à jet continu des requêtes très gourmandes.

Sur ce site, nous utilisons des cookies.