Introduction État de l`art

Crawling for Breaking Passwords
Xavier Martin - Rania Berrazaga
4 mai 2015
Première partie
Introduction
Pour des raisons de simplicité, les gens ont tendance à créer des mots de passe à partir
de leurs informations personnelles telles que leur nom, prénom, email, date de naissance, ville
d’origine . . .
Ces mots de passe sont certes faciles à retenir, mais peu de personnes se rendent compte qu’il
est possible d’utiliser ces informations personnelles pour récupérer le mot de passe de la «victime». Les réseaux sociaux tels que Linkedin, facebook ou twitter sont parmi les sources les
plus accessibles permettant de récupérer de telles données personnelles [1].
Dans le cadre de notre projet, nous allons chercher à récupérer à partir d’un nom d’utilisateur les informations les plus pertinentes le concernant. Nous commencerons par un bref aperçu
des techniques et logiciels existants dans le domaine du craquage des mots de passe puis nous
expliquerons ce qu’est un crawler web ainsi que son architecture.
Enfin, nous présenterons le travail réalisé à l’aide du framework Python scrapy afin de mettre
en application le fonctionnement d’un crawler et de récupérer et traiter les informations personnelles d’une cible.
Nous espérons ainsi sensibiliser les utilisateurs à choisir leur mots de passe plus attentivement
en évitant autant que possible d’y introduire des données personnelles.
Deuxième partie
État de l’art
1
Cassage de mots de passe
Il est clair que les mots de passe ne doivent pas être stockés en clair sur une machine car si
un utilisateur malveillant arrive à accéder à la liste des mots de passe d’une application, il lui
sera alors aisé de se faire passer pour un autre utilisateur.
Pour cette raison, on utilise les fonctions de hachage qui transforment un mot de passe en une
suite de bits ou chaîne de caractère à partir de laquelle il est impossible de retrouver le mot de
passe originel. Ainsi, seul le hash du mot de passe doit être conservé.
Lors d’une identification, l’ordinateur comparera le hash du mot de passe stocké avec le hash
du mot de passe saisi. Cependant cette technique à ses limites, en effet si deux utilisateurs
choisissent le même mot de passe, les hashs obtenus seront identiques. Il est alors facile de
1
deviner que les hashs présents plusieurs fois sont ceux de mots de passe peu originaux et donc
vulnérables.
Enfin, stocker les mots de passe simplement hashé rend également la table de mots de passe
vulnérable aux attaques par table de hash pré-calculée.
Pour contrer ce type d’attaque, on ajoute une composante : le sel, qui peut être l’heure d’inscription de l’utilisateur ou une simple chaine aléatoire. On concatène le mot de passe et le sel
pour obtenir deux hash différents pour le même mot de passe, ce qui empêche les attaques par
table précompilée [2].
Fonction de hachage
Soit Σ un alphabet. On définit une fonction de hachage comme une application [3] :
h : Σ? 7→ Σn , n ∈ N
Les fonctions de hachage associent à un ensemble de bits de taille quelconque un ensemble de
bits de taille fixe. Remarquons qu’elles ne peuvent être injectives. De plus, elles sont construites
de façon à ce qu’il soit quasiment impossible de retrouver un antécédent à partir d’un hash.
Le seul moyen de retrouver l’antécédant est de hasher toutes les combinaisons possibles afin de
tomber sur la même valeur.
Un mot de passe pouvant être considéré comme une suite de bits, on en déduit que pour
retrouver le mot de passe à partir du hash de ce mot de passe, il faut hasher tous le mots de
passe possibles jusqu’à obtenir le hash en question.
A priori, plus le mot de passe en question est long, plus le temps pour le retrouver sera long. Dans
le cas d’un mot de passe de 8 caractères alpha-numériques, cela représente 628 ≈ 2.1834011×1014
combinaisons. Si on dispose d’une machine capable de calculer 109 hashs/s, cela prendrait
environ 2 jours et demi pour tester toutes les possibilités et retrouver le mot de passe. Dans
le cas d’un mot de passe de 12 caractères, il faudrait plus de cent mille années avec la même
machine.
Ce temps étant beaucoup trop long, nous devons nous concentrer sur les mots de passe les plus
probables. C’est ici qu’interviennent des logiciels tels que hashcat ou John the ripper.
Principe de fonctionnement des logiciels de craquage de mots de passe
À l’aide d’un craqueur de mot de passe, le pirate informatique commencera par tester en
premier les mots de passe évidents comme le nom d’utilisateur, le site internet d’où vient la
fuite... Ceci correspond au mode single de John the Ripper.
Le logiciel cherche ensuite le mot de passe à partir d’une liste prédéfinie dans un dictionnaire.
S’il n’arrive pas à le déterminer, on peut ajouter au dictionnaire quelques modifications (par
exemple, rajouter une date de naissance à la fin du mot de passe).
Enfin, si ces techniques n’ont pas réussi à retrouver le mot de passe, il reste à tester toutes les
autres possibilités. Pour économiser le plus de temps possible, John the ripper permet d’essayer
toutes ces possibilités en parcourant en premier les mots les plus «probables» tels que ceux
composés de tri-nomes comme «ing» ou «the».
2
Web crawler
Definition
Un web crawler (ou robot d’indexation en français) est un programme permettant de parcourir des pages web et d’en extraire un contenu. Il peut être utilisé dans différents buts [4] tels
que :
— Dans les moteurs de recherches qui indexent les pages web.
— Pour l’archivage du Web (un service, fourni par exemple des archives d’internet : un
grand ensemble de pages Web sont régulièrement rassemblées et archivées).
— Pour le Data mining : les pages web sont analysées selon des propriétés statistiques afin
d’être utilisées pour des analyses de données (exemple : Attributor, une entreprise qui
surveille le Web pour le copyright et la contrefaçons des marques).
Un crawler «poli» devra de plus respecter ces propriétés [4] :
— Une seule connexion doit être ouverte à la fois avec un serveur.
— Les requêtes successives à un serveur doivent être espacées de quelques secondes (afin
de ne pas risquer le déni de service).
— Respecter la volonté des sites web : certains serveurs web ont des politiques réglant la
fréquence à laquelle un crawler peut les visiter, les informations ou pages auquel il doit
restreindre son accès..
Architecture
La figure 1 ci-dessous montre l’architecture d’un crawler. Le crawler se compose de processus
multiples, liés par un réseau à haut débit, qui fonctionnent à différents nœuds d’un système distribué. Chaque processus se compose de multiples threads et chaque thread exécute des cycles
de travail.
Au début de chaque cycle, le thread obtient une URL de la structure de données de la frontière (Frontier data structure) qui distribue les URLs selon leur priorité et selon les politiques
de politesse.
Le thread invoque ensuite le HTTP fetcher. Le fetcher appelle d’abord un sous-module DNS
qui traduit le nom du domaine en une adresse IP (en utilisant les résultats cachés des résolutions antérieures si possible), se connecte ensuite au serveur Web et vérifie s’il y a des règles
d’exclusion de robots (qui sont typiquement cachées aussi). En effet, beaucoup de serveurs web
placent certaines portions de leurs sites Internet hors des limites du crawler, sous une norme
connue comme le Robots Exclusion Protocol [5]. L’exclusion de robots est faite en plaçant un
fichier sous le nom robots.txt à la racine de la hiérarchie d’URL sur le site.
Ci-dessous un exemple [5] d’un fichier robot.txt qui précise qu’aucun robot ne peut visiter
une URL commençant par /yoursite/temp/, sauf le robot searchengine.
User-agent : *
Disallow : /yoursite/temp/
User-agent : searchengine
Disallow :
Une URL (particulièrement référant à une page de faible qualité ou qui change rarement)
peut être dans la frontière pour des jours ou même des semaines. Si nous devions réaliser le
filtrage des robots avant d’ajouter une telle URL à la frontière, le fichier robots.txt pourrait
Figure 1 – Architecture d’un crawler web
avoir changé alors que l’URL est enlevée de la queue de la frontière et est passée au fetcher.
Nous devons exécuter par conséquent le filtrage des robots immédiatement avant que le fetcher
aille chercher la page Web.
Une fois que le filtrage est réalisé, le fetcher essaie de télécharger la page Web. Si le téléchargement réussit, la page peut ou non être conservée dans un dépôt de pages Web collectées. Dans
les deux cas, la page est passée à l’extracteur de lien, qui parse le contenu HTML des pages et
extraits les liens hypertextes.
Les URLs correspondantes sont alors passées à un distributeur d’URL, qui affecte chaque URL
à un processus. Ensuite, l’URL traverse le Custom URL filter (pour exclure par exemple des
URLs appartenant à une liste noire de sites ou des URLs avec des extensions de fichier particulières qui n’ont pas d’intérêt) et dans le Duplicate URL eliminator qui maintient l’ensemble
de toutes les URLs découvertes jusqu’à présent et transmet seulement les URLs non déjà rencontrées. La mise en œuvre la plus simple de cela est d’utiliser une empreinte digitale simple
telle qu’une somme de contrôle. Finalement, l’URL prioritizer choisit une position pour l’URL
dans la Frontière, basée sur des critères tels que l’importance de page estimée ou son taux de
changement.
Troisième partie
Travail réalisé
Nous vous présentons ici le travail réalisé dans le cadre du sujet Crawling for breaking passwords.
Motivations
Après avoir vu le fonctionnement d’un crawler-web, et étant donné qu’un grand nombre
de mots de passe contiennent des informations personnelles, il est légitime de se servir d’un
crawler-web afin de récupérer un maximum d’informations potentiellement utiles sur un utilisateur.
Un attaquant ayant récupéré la liste des mots de passe hashés d’un système (ceux présents dans
le fichier /etc/shadow sous Linux ou la database d’un serveur web suite à une injection SQL
par exemple) peut alors vouloir se servir d’un tel crawler pour augmenter ses probabilités de
succès lors du cassage de hashs. Il est d’ailleurs facile de se procurer de tels couples pseudo-hash
sur des sites internet tels que http://www.pastebin.com.
Notre crawler doit donc être capable de récupérer le plus d’informations possible - sous forme
d’un dictionnaire utilisable par des logiciels tels que john the ripper ou hashcat - à partir d’un
simple pseudo ou couple nom-prénom.
Choix du langage
Nous avons choisi d’implémenter notre outil en Python. Les raisons de notre choix étant :
— Python est un langage de haut niveau permettant de traiter simplement, et efficacement
les requêtes web ainsi que les documents HTML nécessaires à ce sujet.
— Il s’agit d’un langage de script pour lequel il sera facile de tester le fonctionnement de
chaque ligne de code dans un interpréteur sans avoir à recompiler le projet. Le temps
de calcul comparé au temps des requêtes web nécessaires étant négligeable, nous ne
souffrirons pas des performances moindres d’un langage non compilé.
— Enfin, l’outil de génération de dictionnaire est basé sur le framework scrapy dont l’utilisation nécessite de coder en Python.
Structure du projet
Figure 2 – Structure
La racine de notre projet contient les deux scripts principaux de notre outil (voir figure 2).
crawler.py permet de paramétrer et de lancer une recherche suivi par la création d’un dictionnaire de mots étant donnée un nom d’utilisateur ou pseudo.
refiner.py permet d’étendre le dictionnaire précédent en recherchant de nouveaux mots relatifs
au résultat de crawler.py
Le moteur principal de crawling du projet se trouve dans le répertoire word_crawler. Il
s’agit de l’architecture standard d’un projet utilisant le framework scrapy.
Pour les détails de fonctionnement d’un projet avec ce framework, vous pouvez vous référer à
la très bonne documentation disponible à cette adresse : http://doc.scrapy.org/en/latest/
Le répertoire lib contient un module que nous avons écrit afin de permettre à Python de
faire des recherches google et d’en extraire les URLs.
common_words contient un script Python permettant d’extraire une liste de mots de
longs textes. Nous générons ainsi deux dictionnaires sérialisés contenant une liste de mots courants en français et en anglais. Ces listes de mots seront utilisées pour retirer le bruit du résultat
de notre crawling.
Enfin, le répertoire results contient les fichiers raw.txt, wordlist.txt et enhanced.txt qui sont
respectivement le résultat du premier cycle de crawling de scrapy, ce dernier fichier retraité afin
d’en supprimer le bruit et de le classer par fréquence d’apparition des mots et le dictionnaire
de mots liés obtenu par le script refiner.py.
Principe de fonctionnement
L’outil développé se démarre par la commande python crawler.py.
On renseigne d’abord les informations connues de l’utilisateur (pseudo, couple prénom-nom ou
toute autres informations utiles), puis deux paramètres de profondeur de recherche.
Le premier joue sur le nombre d’URLs qui seront utilisées comme base pour le crawling à l’aide
de scrapy, et le second influe sur le nombre de liens qui seront parcourus lors de l’étape de
crawling.
Plus ces paramètres sont élevés, plus le dictionnaire résultant sera important. Fournir des paramètres trop élevés diminue cependant la pertinence du dictionnaire car cela implique de
s’éloigner de plus en plus de la sphère générée par le pseudo initialement fourni.
Le script fait alors appel au module gsearch afin d’obtenir une liste d’URLs qui serviront à
scrapy pour débuter le crawling.
Pour plus de lisibilité, nous affichons à l’utilisateur la liste des URLs retenues afin qu’il puisse,
s’il le désire, modifier les paramètres qu’il a fourni lors d’un autre appel.
Notre première passe de crawling est alors effectuée à l’aide du framework scrapy. Une spider
est utilisée afin de parcourir le web d’urls en urls tout en construisant des items contenant le
texte de chaque page html visitée. Ces items sont alors traités par un pipeline qui s’occupe d’un
premier traitement sur ces mots. Les doublons sont supprimés et les mots classés par fréquence
d’apparition. Lorsque notre spider termine le crawling, elle envoie un signal à notre pipeline
qui s’occupe de traiter les derniers items et écrit le dictionnaire généré dans ./results/raw.txt
Le script crawler.py reprend alors la main en affichant des statistiques sur cette première
passe de crawling à l’aide scrapy, puis il s’occupe de post-traiter notre premier dictionnaire. Ce
traitement consiste à supprimer le bruit du dictionnaire en y soustrayant les mots courants de
nos dictionnaires sérialisés présents dans ./common_words.
Le résultat est alors stocké dans ./results/wordlist.txt
Finalement, si l’utilisateur désire générer un dictionnaire supplémentaire suite à cette première passe, le script refiner.py le lui permet.
Il lui sera alors demandé de saisir le nombre de mots de la wordlist précédemment générée à
raffiner. Les mots sont automatiquement choisis de façon à raffiner les plus pertinents d’abord.
refiner.py s’occupe de générer une liste d’URLs décrivant au mieux les mots retenus, puis d’appeler un second crawler-web, CeWL, qui permet de simplement récupérer le texte d’une URL
donnée.
refiner.py récupère les résultats de ces appels, supprime les occurrences multiples du même mot
et enlève le bruit avant d’écrire le dictionnaire généré dans ./results/enhanced.txt
Les dictionnaires ./results/wordlist.txt et ./results/enhanced.txt sont alors utilisables en
l’état pour un utilitaire de cassage de mots de passe tel que john the ripper ou hashcat.
Références
[1] Danesh Irani, Steve Webband Calton Pu,Georgia Institute of Technology Kang Li ,University of Georgia "Modeling Unintended Personal-Information Leakage from Multiple Online
Social Networks"
[2] Simon Marechal "Etat de l’art sur le cassage de mots de passe", Thales Security Systems
[3] Les Fonctions de Hachage, ÉPREUVE COMMUNE DE TIPE 2008 - Partie D
[4] Christopher Olston and Marc Najork,"Web Crawling"
[5] "Web crawling and indexes" Online edition (c) 2009 Cambridge UP
[6] M. Dürmuth, A. Chaabane, D. Perito, and C. Castelluccia "When Privacy meets Security :
Leveraging personal information for password cracking"
[7] Christophe Alladoum "Google Hacking"