Jour 21 • Récupération de mot de passe

Ce matin en accédant à l’intranet1. Ce qui l’est plus c’est qu’aucune vérification du lien reçu n’est effectué : il m’a été possible de faire afficher un site internet extérieur.
Il m’est alors venu de faire afficher une page d’authentification pirate, me permettant ainsi de récupérer nom d’utilisateurs et mots de passe…

Le navigateur par défaut pour accéder à l’intranet étant Internet Explorer2, j’ai donc passé la matinée à fabriquer une réplique de la fenêtre de connexion Windows.
Il faut jouer sur la naïveté de l’utilisateur : pour certaines applications, l’authentification utilisateur de l’AD de sa machine Windows ne suffit pas pour se connecter. Normalement, une nouvelle fenêtre d’identification ne devrait pas trop le surprendre.

Le fait d’imiter la fenêtre de connexion ne suffit pas : il faut amener l’utilisateur à se rendre sur l’intranet sur une URL particulière, et le mieux, qu’il ne se rende pas compte que ses identifiants ont été dérobés. Une faille en cours de résolution sur le réseau interne est que le serveur d’envoi des mails ne vérifie pas vraiment l’identité. Il est donc possible d’envoyer un mail à plusieurs personnes en se faisant passer pour un autre. Il ne reste plus qu’à susciter l’intérêt de l’agent pour qu’il clique sur le lien : un message concernant une intervention du maire, un fiche de recommandation sur je ne sais quel sujet, …

Pour mettre en place cette récupération d’identifiants, je souhaitais que l’URL incluse ressemble à quelque chose d’officiel. J’ai opté pour auth.ville.local, sachant que le suffixe DNS des connexions filaires est ville.local. De plus, il est existe réellement un serveur auth.ville.fr, mais seulement accessible depuis l’extérieur. La ressemblance est relativement bonne, surtout pour un utilisateur naïf !
J’ai donc mis en place une machine virtuelle sous Ubuntu serveur, en y configurant un serveur Web, ainsi que son nom « auth », qui une fois sur le réseau, est devenue auth.ville.local. Parfait

Cette démarche a mis en évidence un autre problème du réseau interne : toute machine se connectant en filaire sur le réseau à l’intérieur de la DSIT3 obtient le suffixe DNS « ville.local ». Donc toute personne ayant renommée intelligemment sa machine peut tenter « d’usurper » l’identité d’une autre machine. C’est ce que P. a fait : il a nommé sa machine sous Linux du même nom que celle de A., et oh magie, lorsque je tentais un ping vers le nom de machine de A., c’est en fait la machine de P. qui répondait.
P. aurait souhaité prendre le nom d’un serveur, pour voir comment le réseau réagirait, mais cela ne lui a pas été possible4.

Le problème a été remonté mais n’est pour l’instant pas une priorité absolue. Il s’agit du réseau interne, et n’importe qui ne peut pas entré ni tombé sur une prise Ethernet active. L’extérieur de réseau est lui mieux sécurisé, et c’est là dessus que l’on souhaite se concentrer pour l’instant.


  1. Site web de la collectivité, accessible uniquement en interne, présentant les services internes, l’annuaire, etc), je me suis aperçu en affichant le webmail que l’intranet incluait directement la page grâce à une URL fournie en paramètre. Le webail étant hébergé en local rien de très choquant ((Même si la technologie utilisée est obsolète : le iFrame :( 

  2. Oui je sais… 

  3. Il faut déjà réussir à le faier, le bâtiment régulant toutes les entrées. 

  4. Et on comprend bien, il aurait fallu un réseau test à côté pour le faire. 

Jour 13 • Quand le chat n’est pas là, les souris dansent

Aujourd’hui A., RSSI de la collectivité locale, a pris sa journée pour faire son déménagement. J’en ai profité pour presque finaliser mes recommandations.
J’ai aussi fait quelques tests sur les cookies1, pour bien montrer qu’il ne faut jamais faire confiance aux données reçues. Il me reste un petit paragraphe sur la gestion et le stockage des mots de passe à éclaircir, et je devrais avoir terminer la partie « explications/exemples ».

Comme en début d’après-midi P. et moi nous devions présenter les vulnérabilités trouvées et les solutions pour les pallier à B., nous avons un peu retravaillé nos supports.

Le début d’après-midi a ainsi pu bien se déroulé. B. a été très à l’écoute, mais comme l’application est encore en développement et que la deadline n’est pas urgente, il fera les modifications nécessaires lorsqu’il aura un peu de temps. La réunion a été courte, mais il en a profité pour nous demander de tester d’autres internes et externes, pour voir ce que nous trouvions.

Il faudra cependant attendre demain, pour que A., notre responsable, téléphone au prestataire afin de les prévenir que nous allons faire des tests de vulnérabilité sur leurs serveurs où sont hébergés certains sites.


  1. Notamment avec ce plugin jquery-cookie pour insérer et lire des cookies en JavaScript, et Firebug pour modifier les cookies enregistrés sur mon ordinateur 

Jour 10 • Fin de semaine

Nous voilà vendredi, cela va faire deux semaines que mon stage à commencer. Le tiers est déjà fait, c’est fou comme je n’ai pas vu le temps passé.

Ce matin, programme agréable : préparation d’un court rapport et d’une petite présentation des solutions trouvées hier pour pallier les failles de sécurité trouvées, qui je le rappele, permettent l’envoi de n’importe quel fichier — et donc, au hasard un script PHP permettant de prendre la main sur le serveur —, et de nombres failles XSS permettant l’exécution de code malicieux.
Cette petite présentation devra être présentée cet après-midi avec A., mon maître de stage, et P. son premier stagiaire. P. devait s’occuper de faire la présentation concernant la recherche et présenter ce que permettent de faire les failles.

Ce midi : barbecue. Enfin, pour être exact, inauguration du barbecue. Pour l’occasion j’avais apporter une salade de nouilles/tomates/fromages/jambon. Les cuisiniers s’en sont très bien sortis ; ce fût très bon et très agréable de pouvoir discuter tous ensemble. Certains ont même commencé une partie de pétanque

Après ce petit repas, il a fallu digérer un peu, ce qui a permis de prendre son temps pour faire notre petite réunion de présentation. Tout s’est bien passé, nous avons pas mal discuté, surtout d’un sujet récurrent : comment l’application web arrive à identifier l’utilisateur sur l’Active Directory sans jamais transmettre son mot de passe.
La réponse est certainement très bête1.

Hé puis, mine de rien, il était déjà l’heure de rentrer


  1. Je verrais bien un échange de token pour authentifier l’utilisateur en fonction de sa session Windows — l’application n’est disponible qu’avec IE, les autres navigateurs ne supportant a priori pas la méthode d’authentification automatique utilisée… 

Jour 9 • Encore du code source

Cette journée a été la continuité de la veille. Le matin, j’ai continué à chercher des solutions pour pallier les vulnérabilités trouvées sur l’application de gestion des déchets.
Pour l’échappement des caractères, je n’ai pas mieux trouvé que htmlspecialchars. Néanmoins, la fonction utilisée telle quelle n’échappe pas les guillemets simples. Il faut ajouter un paramètres à la fonction pour que les caractères &, ", ', < et > soient échappés :

htmlspecialchars('ma super donnée à échapper', ENT_QUOTES)

Néanmoins, même sans ajouter ce paramètre, ajouter cette fonction d’échappement résoudra bien des problèmes.

Petite pause le midi pour jouer à Left4Dead. Bizarrement, il a fallu quelques temps avant d’arriver à ce que nous puissions tous les trois rejoindre une même partie en réseau local alors que nous avions tous une version authentique. Ce fut bien rigolo.

L’après-midi, je me suis plus concentré sur la validation des fichiers envoyés sur le serveur. J’ai trouvé deux solutions. Elles peuvent être mises en place séparément, mais il me semblerait plus judicieux de tout le temps utiliser les deux…

  1. La première solution consiste à désactiver l’exécution de scripts PHP dans les dossiers uploads et de forcer le téléchargement des fichiers.
  2. La seconde solution consiste à vérifier le type et l’extension du fichier envoyé, et de rejeter tout fichier dont ces critères ne seraient pas autorisés.

D’une manière générale, la seconde méthode doit toujours être mise en place, car :

Ne jamais faire confiance aux données reçues.

La première solution n’est là que si la vérification aurait échouée.

Jour 8 • Un peu de code source

La journée a commencé avec deux voitures incendiées : en arrivant nous avons pu voir que deux voitures de fonction utilisées par la collectivité locale étaient en cendre. Une personne de la police scientifique était présente et s’adonnait à des prélèvements, photos, etc pour tenter de déterminer la cause. A priori, ce ne serait pas volontaire.

Voitures brûlées

La suite du programme a été de tester une application web1 permettant de gérer le recyclage de gros déchets.
P. s’est rapidement aperçu que les champs des formulaires n’étaient aucunement contrôlés : bonjour les failles XSS. D’autre part, l’envoi de fichiers n’était pas non plus sécurisé : nous avons pu envoyer un fichier PHP et l’exécuter. Et enfin les commandes systèmes exec, shell_exec et system n’étaient pas désactivées, ce qui nous a permis d’avoir la main mise sur le serveur…Capture faille exploitée par script PHPL’après-midi a été consacré à la recherche des lignes problématiques dans le code source que B. a pu nous fournir. Les développeurs ont utilisés le framework Zend pour leur application. Le problème, c’est que Zend n’échappe les caractères par défaut lors de réception de données2. Il faut donc qu’à chaque ligne où la méthode de Zend pour récupérer une requête est utilisée échapper les caractères avec la fonction htmlspecialchars3.
Sublime Text a su me fournir rapidement toutes les lignes à corriger. Reste maintenant à pouvoir modifier le code source du projet en intégration…


  1. Encore en développement, sur un serveur d’intégration 

  2. Données reçues en GET ou en POST 

  3. L’application est en effet codée en PHP