GSB Bruteforce
C / libcurlUn programme CLI que j'ai développé en C avec l'API curl, pour effectuer des attaques par force brute.
Contexte
Dans le cadre de mon BTS SIO, nous avons développé un site web en PHP avec le framework CodeIgniter : GSB.
Ensuite, il nous a été demandé de tester la sécurité de notre site et de combler les failles de sécurité les plus connues.
J'ai essayé de faire des attaques par force brute sur mon projet avec des solutions déjà existantes, comme Hydra, cependant de par le design du site, du modèle MVC et du fonctionnement du framework, il est quasiment impossible d'utiliser Hydra pour cracker un mot de passe utilisateur.
En effet, Hydra utilise le contenu HTML de la page-cible du formulaire pour savoir s'il a réussi ou non à se connecter, mais mon site passe par une page en pur PHP (sans la moindre ligne de HTML) pour vérifier si les identifiants sont valides ou non.
J'ai décidé de développer ma propre application de bruteforce qui utilise les redirections d'URL et les codes d'états HTTP pour vérifier si on est connecté ou non, ce qui colle mieux au design de mon site.
Fonctionnement
Le code source est découpé en deux parties. La première génère des mots de passe suivant les conventions de mots de passe utilisées par le jeu de données fourni, c'est-à-dire 5 caractères qui sont soit des lettres minuscules soit des chiffres. Il suffit de modifier quelques lignes dans le programme pour pouvoir utiliser d'autres longueurs et caractères.
La deuxième utilise l'API curl et sa bibliothèque C libcurl pour envoyer des requêtes POST sur le formulaire que l'on passe au programme. Il teste le mot de passe et vérifie les codes HTTP ainsi que les redirections d'URL. Si on arrive sur la bonne URL, alors il affiche le nom d'utilisateur et le mot de passe et termine le programme.
Si aucun mot de passe n'est trouvé, le programme l'indique aussi.
Test du programme
On part du principe qu'on connaît déjà l'identifiant de l'utilisateur, puisque le jeu de données suit toujours la même convention (première lettre du prénom, puis nom de famille, non-accentué et en minuscule).
On commence par cibler l'URL où se trouve le formulaire, puis on tente de se connecter. On utilise les outils du navigateur pour connaître le contenu de la requête envoyée.
On possède maintenant la requête exacte envoyée par le formulaire, ainsi que le nom des variables. Le code source de mon projet GitHub utilise déjà cette requête.
Mon programme peut utiliser soit les redirections d'URL, soit les codes d'états HTTP pour savoir si on a réussi à se connecter ou non. Si on connaît l'URL sur laquelle arrivent les utilisateurs connectés, on peut l'utiliser directement. Sinon, il faut faire quelques tests avec l'API curl pour en déduire quel code HTTP signifie que la connexion a échoué, puis afficher les résultats seulement si on obtient un autre code.
Dans cet exemple, on va imaginer qu'on a déjà connaissance de l'URL connectée, qui est la page « selection ». Le programme va tester toutes les combinaisons de mots de passe possibles.
Comme on peut le constater, on remarque qu'en cas d'échec de la connexion, on obtient l'URL « index », avec un paramètre GET d'erreur, ainsi qu'un code HTTP 200. Quand la connexion réussit, on arrive sur l'URL « selection », et on a le code HTTP 500.
Par conséquent, peu importe la méthode détaillée plus haut qu'on utilise, on aurait trouvé le mot de passe. Pour finir, le programme affiche les identifiants et le mot de passe.