URL Rewriting

Rédacteur : Trance

Date de création : 09/02/2007

Section : Sécurité > Failles Web

L'URL Rewriting est une fonctionnalité d'Apache permettant comme son nom l'indique la réécriture d'URL à la volée. Cela permet ainsi de changer l'URL de ses pages, et entre autres de faire croire au visiteur (et aux moteurs de recherche) que toutes ses pages sont statiques, en HTML. Certains s'en servent pour décourager des script-kiddies, d'autres pour augmenter leur référencement. Mais est-ce toujours possible d'exploiter des vulnérabilités des pages originales ? Avant de répondre à cette question, nous verrons comment fonctionne le mécanisme d'URL Rewriting.

Sommaire

  1. Notions sur les expressions régulières
  2. Principe de base de l'URL Rewriting et intérêts
  3. Risques et exploitation

Introduction

Imaginez que vous êtes un script-kiddie à la recherche de failles à exploiter sur un site Web. Vous visitez quelques pages, et là, malheur, vous ne tombez que sur des pages ayant l'extension HTML... Le HTML est réputé comme "infaillible" puisqu'en effet, n'étant pas un langage de génération dynamique de pages, il ne permet aucun traitement de données. Pour autant, peut-on conclure de manière générale qu'un site comportant des pages possédant l'extension .html n'est pas vulnérable ?

La réponse est non. En effet, les serveurs HTTP comme Apache permettent aisément au webmaster de manipuler d'URL de leurs pages, et de les transformer. On peut ainsi demander à Apache de transformer les URL tapées par le visiteur afin d'exécuter une page dynamique de manière cachée. Cela s'appelle l'URL Rewriting.

1. Notions sur les expressions régulières

Pour bien comprendre le mécanisme d'URL Rewriting il est nécessaire de connaître les expresisons régulières. Si vous connaissez déja le domaine en les ayant manipulées en PHP ou en Perl, vous pouvez sauter cette partie.

Tout d'abord, qu'est-ce qu'une expresison régulière ? Il faut voir une expression régulière (en abrégé "regex") comme un modèle ("pattern" en anglais) permettant de décrire un ensemble de chaînes de caractères.

Voyons tout de suite un exemple. Imaginons que vous souhaitez rechercher dans votre disque dur les fichiers dont le nom comporte un "e" et finit par ".txt". Que taper dans la boîte de recherche ? Vous aimeriez bien qu'un caractère "joker" existe, qui permettrait de décrire 'nimporte quoi". Par exemple, avoir à taper "*e*.txt", en supposant que l'étoile * soit ce caractère joker. En fait, ce que vous venez de taper est une forme d'expression régulière ! Pour la suite, vous pouvez oublier cet exemple, car l'étoile aura une autre signification.

Plus généralement, une expresison régulière est une suite de caractères, qui peuvent être normaux ou spéciaux. Les caractères normaux ne désignent rien de particulier, à par eux-mêmes. C'est le cas des lettres et des chiffres. Viennent ensuite les caractères spéciaux, qui comprennent par exmeple des signes de ponctuation. Ces caractères ne désignent pas eux-même mais ont un comportement différent, que nous allons voir.

Maintenant que vous avez compris les bases des regex, saurez-vous à qui correspond cette regex : "[a-z0-9]@[a-z0-9]\.[a-z0-9]{1,4}" ?

Réponse : c'est une adresse e-mail ! En effet, "[a-z0-9]" correspond à un caractère alphanumérique, le @ n'a pas de signification particulière et reste donc un arobase, "\." correspond à un point (déspécialisé par le \) et ce qui figure derrière est une suite de 1 à 4 caractères alphanumériques. C'est bien une adresse e-mail... à la différence près que les majuscules ne seront pas prises en compte ici, je vous l'accorde... Et si vous revenez à l'exemple du début, à savoir trouver des noms de fichiers comportant un e et finissant par .txt, la regex correspondante est en fait : ".*e.*\.txt" (on laisse la possibilité d'avoir des caractères avant et après le e).

Petite parenthèse : si vous voulez faire du traîtement de chaînes de caractères (appelé aussi parsing), les expressions régulières sont un excellent moyen de faire ! Elles sont compactes et puissantes, ce qui est très rentable quand on écrit du code. D'ailleurs, si vous aimez les expressions régulières, vous aimerez le langage Perl, puisqu'il est basé dessus !

2. Principe de base de l'URL Rewriting et intérêts

L'URL Rewriting est permise par un module d'Apache (mod_rewrite) qui permet la réécriture d'URL à la volée. La configuration de l'URL Rewriting se fait dans un fichier .htaccess, placé én général à la racine du site Web concerné. Voici un exemple de fichier qui définit quelques règles d'URL Rewriting :

#Activation du module
RewriteEngine on

#Règles
RewriteRule photos-(.+)\.html     /index.php?page=photos&p=$1    [L]
RewriteRule index\.html           /index.php                     [L]
RewriteRule ([a-z]+)\.html        /index.php?page=$1             [L]

La première option active le module et est donc absolument nécessaire. Les lignes d'en dessous définsisent les règles, c'est à dire les conditions sous lesquelles l'URL sera réécrite ou pas. Une règle commence par la directive "RewriteRule", suivie d'une regex (d'où l'utilité du 1er chapitre) qui décrit le modèle d'URL à réécrire, suivie de l'URL réécrite, et terminée par une option. Prenons l'exemple de la 2ème règle, la plus simple. Elle dit simplement que si le visiteur tente d'accéder à la page "index.html", alors le serveur lui renverra la page index.php. La dernière ligne dit que si le visiteur tente d'ouvrir une URL composée d'une suite de lettres terminées par ".html", le serveur affichera la page "index.php?page=$1" en remlplaçant $1 par la suite que l'utilisateur aura tapée.

Il faut bien comprendre que ce mécanisme est totalement invisible pour le visiteur, qui croit surfer sur un site en HTML alors qu'en fait la génération des pages est dynamique (ici en PHP). Enormément de sites utilisent (ou semblent utiliser) ce mécanisme, comme par exemple le site du Monde, le Site du Zero, beaucoup de blogues, et... GITS (pour la version 2 :p).

Quel est l'avantage d'utiliser un tel système ? En fait, il y en a plusieurs. Premièrement, cela permet de masquer à l'utilisateur le fait que le site soit en PHP, il sera donc moins tenté de tester les failles dessus. De plus, les URL sont plus "jolies", plus parlantes, plus facilement mémorisables. Cela permet aussi de booster son référencement dans les moteurs de recherche, car les moteurs ont beaucoup de mal à indéxer des pages dynamiques avec des URL comportant beaucoup de paramètres à rallonge. Cela permet aussi de définir plusieurs URL pointant vers une seule, vu qu'il y a des regex. Ainsi, on peut définir dans une URL des parties "flexibles", c'est à dire que le visiteur peut modifier sans perdre l'accès à la page. On peut donc y glisser des mots-clés, ce qui booste encore plus le référencement...

3. Risques et exploitation

Mais certains webmasters sans beaucoup de connaissances dans le domaine de la sécurité laissent des failles sur leur site et s'en remettent à l'URL Rewriting pour les masquer, espérant que cela sera suffisant. Malheureusement, cela ne l'est pas toujours... Imaginez que vous tombez sur l'URL "http://site.com/article2.html" puis sur une autre "http://site.com/article8.html", et ainsi de suite. On peut soupçonner l'utilisation de l'URL Rewriting... Si l'on fait varier le nombre situé derrière "article", on peut voir ce que cela donne. La page réécrite (cachée) pourrait ressembler à http://site.com/article.php?id=$1 avec $1 le nombre en question. A partir de là, il faut utiliser les techniques habituelles de recherche de failles : faire varier le paramètre, tenter d'insérer des lettres, des caractèes spéciaux, pourquoi pas des balises (qui a dit XSS ? :p), etc. Il n'est même pas nécessaire de connaître le nom du paramètre, puisque si la regex est assez permissive, elle réécrira la chaîne tapée en paramètre de la page. Ainsi, si l'on teste une injection SQL : http://site.com/article1%20and1=2.html deviendra quelque chose du style http://site.com/article.php?id=1%20and1=2 et le résultat de la page nous informera du succès ou non de l'injection.

Ceci était dans le cas où l'expression régulière définie dans la règle était assez permissive, c'est à dire qu'elle n'imposait pas au visiteur de taper un nombre. Elle aurait pu être du type "(.+)\.html". Maintenant, imaginons que le webmaster a voulu restreindre la réécriture en mettant une regex plus restrictive comme "([0-9]+)\.html" qui n'accepte que les nombres. Là, il n'y a pas de technique pour bypasser cette protection (vu que filtrer est bien le but d'un filtre...) ! Mais il ne faut pas perdre de vue le fait que si on connaît le nom de la page PHP qui contient le script (ici article.php), et qu'elle comporte une faille, alors rien ne nous empêche de l'exploiter. L'URL Rewriting n'est en faite génante dans ce cas que si l'URL de cette page est inconnue...

Conclusion

Nous sommes déjà à la fin de cet article... J'espère que vous n'êes pas trop décus ! En fait, ce qu'il faut retenir est que le mécanisme d'URL Rewriting ne comporte pas en lui-même de failles, mais il masque juste des éventuelles failles déja existantes dans le script de la page. Il faur savoir que cela existe, car ce mécanisme est de plus en plus utilisé, vu les avantages qu'il offre.

Concernant l'exploitation de failles, si les règles de réécriture sont permissives, l'exploitation de ces failles se fait sans problèmes, mais si elles ne le sont pas, et que l'on ne connaît pas le nom de la page originale, l'exploitation est déjà plus dure (il faut y aller en testant...).