SecureM

Aller au contenu | Aller au menu | Aller à la recherche

La Bruteforce

La Bruteforce... c'est un nom un peu bourrin je vous l'accorde ^^
Mais pourtant ça veut bien dire ce que ça veut dire : la force brute.

Mais commençons par le début : kesskécé ?

La Bruteforce : utilité

La Bruteforce est une attaque informatique visant à trouver une bonne séquence de caractères : un code.
On va donc "forcer" le code comme on forcerait une porte. Cette attaque utilise la puissance de l'ordinateur, qui est capable d'essayer plusieurs centaines de combinaisons à la minute...

La cible est généralement un système demandant un mot de passe, ou bien un mot de passe crypté qu'il faut décrypter - j'en reparlerai plus tard.

On a donc un système demandant un mot de passe. Par exemple une page de connexion à une interface d'administration. On a déjà le nom d'utilisateur mais pas le mot de passe.
Le bruteforceur a pour but de trouver ce mot de passe en les essayant... tous.

La Bruteforce : essayer toutes les combinaisons possibles

Quand je vous disais que c'était un truc de bourrin...
Ce procédé est aussi appelé attaque incrémentale parce qu'elle essaie chaque mot de passe possible l'un après l'autre :
Par exemple pour un code numérique à 4 caractères :
  • 0000
  • 0001
  • 0002
  • ...
  • 0010
  • 0011
  • ...
  • 0156
  • ...
  • 5910
  • ...
  • 9999
En pratique le bruteforceur n'atteindra que rarement 9999, puisqu'en envoyant chaque code au système, celui-ci répondra inlassablement "Code faux" jusqu'à que le bon code soit essayé... "Code valide, vous êtes maintenant connecté !"
Vous imaginez ? Ca fait froid dans le dos non ?
Surtout que les protections existantes ne sont pas nombreuses : on est obligé de laisser un utilisateur envoyer son code pour qu'il puisse se connecter...
Lorsque le réseau délivre 5000 tentatives de connexions à la minute, il fait parfaitement son travail !

La Bruteforce : protections

Voici les moyens les plus efficaces et les plus utilisés pour lutter contre la bruteforce :
  1. La limitation du nombre de connexions échouées : on fixe par exemple une limite de 5 tentatives ratées avant le blocage de l'utilisateur, par exemple pour une durée de 24H. Le problème majeur présenté par cette technique - qui est cependant la plus répandue car plus facile à mettre en place - est qu'elle bloque un ordinateur / une adresse IP pour un certain temps, ce qui peut être regrettable dans le cadre d'un poste public, ou pire d'un serveur piraté qui ne pourrait plus se connecter à un autre serveur (par exemple un serveur de base de données qui bloquerait le serveur web) ...
  2. Le placement d'un délai minimum entre deux tentatives : par exemple pas plus d'une tentative en 30 secondes, ce qui est raisonnable pour un humain normal, mais augmenterait considérablement le temps mis pour bruteforcer le mot de passe...
    Cette technique est plus difficile à mettre en place, mais est plus intelligente que la première.
  3. Les deux mon capitaine ! C'est en effet le mélange des deux principales solutions qui marche le mieux, et qui est par exemple utilisé sur les système Unix/Linux.
Et encore je ne vous ai pas parlé des autres solutions, qui restent grosso modo des remake de ces deux solutions...
Vous pourrez ainsi voir fail2ban, qui bloque automatiquement les IPs suspectes ...

La Bruteforce : performances et solution ultime

Mais LA meilleure solution pour éviter de voir une attaque par bruteforce réussir, c'est... d'avoir un bon mot de passe !
Plus "strong" sera ton mot de passe, plus de temps mettra ton attaquant à le trouver ! dixit un jour un petit personnage vert dont je ne me souviens plus du nom...
Ainsi, un mot de passe de 6 caractères ou moins est très vulnérable (moins de 24H environ pour le trouver) ;
Un mot de passe avec uniquement des minuscule aussi, c'est pourquoi je préconise un mot de passe de 7-8 caractères au moins, avec des majuscules, des minuscules, des chiffres et des caractères spéciaux.
Enfin, évitez par pitié les mots courants ou les noms ! Ces mots de passe sont particulièrement vulnérables aux attaques par dictionnaire (Dictionary Attacks) et aux Rainbow Attacks (pas la pêche de traduire ^^)

Le mot de passe idéal est par exemple la première lettre de chaque mot d'une phrase : personnellement j'utilise souvent - par exemple - "Je suis un joueur de ce jeu formidable qu'est ***" qui donne > j$1j2cjfqe***
Avouez que c'est plus dur à trouver que sebastien42 !

La défense ultime contre la Bruteforce est donc de choisir un mot de passe suffisamment long :)

Les attaques par dictionnaire et les Rainbow Attacks

Il existe 3 types d'attaques BruteForce :
  • La Bruteforce incrémentale, qui essaie TOUTES les combinaisons dans l'ordre. (AAA AAB AAC ...)
  • Les Dictionary Attacks : on essaie tous les mots du dictionnaire, ce qui est nettement moins lourd que l'attaque incrémentale (beaucoup moins de possibilités).
  • Les Rainbow Attacks : on essaie tous les mots du dictionnaire, avec d'autres lettres, chiffres, symboles, etc... C'est une sorte de remix des deux précédents. Et la plus efficace.


J'étofferai sûrement cet article dans les jours qui viennent si je ne suis pas trop pris.
A bientôt, en espérant que cet article vous a été utile :)

Optimisez votre code PHP

Bonjour à tous !

C'est après une longue absence que je publie cet article, pour vous donner quelques conseils d'optimisation PHP.

C'est en fait depuis que je me suis remis à mon jeu en ligne futuriste FuturaX que j'avais commencé il y a quelques années, et que je développe seul la seconde version, que je me suis rendu compte de la différence entre mon code de 2004 et mon code d'aujourd'hui, et que je me suis dit que ça valait la peine de vous faire profiter de quelques astuces...

Voici la liste des différences techniques :

  • J'ai changé d'OS pour développer (Win 98 ou 2000 je sais plus, à un Linux Mandriva, mais sur un ordinateur qui ne s'est pas amélioré comme l'OS : 256Mo de RAM et processeur poussif).
  • J'ai changé d'encodage : je passe du ISO-machinchouette-3 à l'UTF-8, j'avais notamment eu un problème dû à l'encodage quand j'ai tenté de passer à l'AJAX (vous ne savez pas ce que c'est ? Pas grave, je vous ferai un article là-dessus si je prends le temps ^^)...
  • J'utilise désormais KDE (avec Linux, désolé pour les gnomes^^) qui permet notamment la gestion transparente du protocole FTP (entre autres), c'est-à-dire que je visualise un dossier distant, j'ouvre une image pour la modifier, je change les propriétés d'un fichier comme si j'étais en local. Cependant comme c'est légèrement plus lent (on s'en doute) et que Olympe-Network (mon génial hébergeur :P ) n'autorise pas plus de 80 utilisateurs connectés en même temps sur le FTP (sur 18000 utilisateurs), ça devenait difficile de développer directement en ligne... J'ai donc installé le serveur Apache et le reste (15 secondes chrono, vive Linux) pour pouvoir développer en local (et je me débarrasse ainsi de tout EasyPHP ou autre pseudo-serveur).
Ce que vous devez retenir, c'est (mis à part que Linux c'est bien - et compliqué) :
  • L'UTF-8 C'EST BIEN C'EST BON MANGEZ-EN !! Sérieusement, c'est beaucoup plus souple, pour quelques modifications pas difficiles : changer l'encodage dans votre éditeur préféré, ajoutez l'en tête HTTP et le meta-tag dans vos pages :
    <?php header('Content-type: text/html; Charset: UTF-8'); ?> (en adaptant bien sûr le content-type - type du contenu)
    Et <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> (de même pour le content-type)
  • Au niveau technique c'est à peu près tout, je ne préfère pas vous donner de conseils trop précis pour ce qui est de l'IDE (environnement de développement) ni de l'OS (gniark gniark ^^)
Pour ce qui est des habitudes de codage, certaines astuces vont sûrement vous intéresser / vous aider :

Manuel des fonctions

Premièrement, n'hésitez pas à ajouter le moteur de recherche du manuel PHP (RTFM qu'on vous dit !) soit en allant directement sur le site http://php.net/ et en ajoutant le moteur de recherche (ça marche sous Firefox du moins) ou bien pour vous simplifier la vie, en cliquant ici pour ajouter directement le moteur de recherche à Firefox.

Vous n'avez alors plus qu'à entrer un nom de fonction, de classe, de ce que vous voulez pour obtenir la documentation complète et les exemples !

Utilisez des classes (et vive la POO ^^)

Deuxièmement, utilisez des classes si cela est pertinent et utile dans le contexte, par exemple pour la gestion de MySQL. C'est ce que j'ai fait, et je peux ainsi centraliser la gestion des erreurs MySQL, la sécurisation des requêtes (contre les injections SQL), ou encore compter le temps mis pour effectuer une requête, le nombre de requête par page en moyenne...

Les expressions ternaires

Utilisez les expressions ternaires, qui fonctionnent de la manière suivante :

$nom = (empty($pseudo)) : 'Inconnu' ? $pseudo;

Elles permettent de remplacer les instructions IF de manière plus réduite, condensée et efficace (sous la forme condition : valeur-si-oui ? valeur-si-non).

L'URL Rewriting

L'URL Rewriting (un article viendra prochainement) permet une gestion beaucoup plus souple des URLs, une petite sécurité supplémentaire, et beaucoup de soucis en moins !L'utilisation des include_once (et require_once) permet d'éviter la double inclusion de code (librairies, configurations, etc...)

Les guillemets simples et doubles

Les guillemets simples sont à préférer aux guillemets doubles dans de nombreux cas. Ce n'est pas une réelle question de rapidité, mais plus de facilité pour vous :
Je rappelle qu'il existe deux manières d'afficher (par exemple) une chaîne de caractères :
echo "Bonjour toi !"; ou echo 'Bonjour toi !';
La différence majeure est que les guillemets doubles permettent d'inclure des variables :
echo "Bonjour "; echo $nom; echo ", ça va ?"; est similaire à echo "Bonjour $nom, ça va ?"; et affichera "Bonjour Camille, ça va ?" si la variable $nom contient Camille.
Au contraire, vous serez obligés de concaténer les morceaux avec les guillemets simples :
echo "Bonjour ",$nom,", ça va ?";
Dans ce cas, les guillemets doubles sont largement préférables, car ils vous permettent de mieux écrire et visualiser vos chaînes formatées, et je vous encourage vivement à les utiliser dans le cas où vous avez des variables à inclure.
Cependant, dans le cas où par exemple vous affichez du HTML, avec de nombreux attributs pour vos balises, je pense qu'il est préférable d'utiliser les guillemets simple pour éviter d'antislasher tous les guillemets doubles du HTML (mais il faudra alors antislasher les guillemets simples). Je m'explique (vous en avez sans doute grand besoin) :
Pour afficher <div class="volante" id="boite_volante"><bold title="Vous avez un nouveau message"><a href="messages.html" title="Afficher ces 2 nouveaux messages">2 Nouveaux Messages !</a></bold></div>, il vaut mieux écrire
echo '<div class="volante" id="boite_volante"><bold title="Vous avez
un nouveau message"><a href="messages.html" title="Afficher ces 2
nouveaux messages">2 Nouveaux Messages
!</a></bold></div>';
que
echo "<div class=\"volante\" id=\"boite_volante\"><bold title=\"Vous avez
un nouveau message\"><a href=\"messages.html\" title=\"Afficher ces 2
nouveaux messages\">2 Nouveaux Messages
!</a></bold></div>";
De même, j'utilise généralement des fonctions du type message($message) appelées par exemple comme message('Une erreur vient de se produire !!"); (enfin celui-ci j'aime pas trop m'en servir :P). Ici l'utilisation de guillemets simples est plus utile.
En règle générale, il vaut mieux faire comme bon vous semble, pour avoir le moins d'anti-slashs à placer dans vos chaînes de caractères.

Journalisation des évènements

Depuis la première version de mon jeu, je journalise les évènements se produisant dans le jeu, au niveau du PHP, comme par exemple, la connexion d'un joueur, chacune de ses actions (construire, attaquer, message...) ainsi que les données techniques (synchronisation de tel ou tel fichier, intrusion, etc...).
Une simple fonction gère cela :

// Enregistrement des actions
function logue($txt){
    // $fic = @file_get_contents(_LOG); // Le fichier n'existe pas forcément
    $txt = '['.date('d/m-H:i').'] '.$txt;
    $fichier = fopen(_LOG,'a+');
    fputs($fichier, " $txt");
    fclose($fichier);
}

// Nettoyage des logs
function nettoielogs(){
    unlink(_LOG);
    logue('Réinitialisation du log...');
}


Où _LOG contient l'adresse interne du fichier.
Ce fichier est envoyé toutes les 24H sur mon adresse mail personnelle et termine dans un dossier spécialisé.

Les raccourcis, les astuces diverses

Connaissez-vous file_get_contents, ou file_put_contents ?
Savez-vous chronométrer le temps d'exécution d'une page, d'une action particulière ?
Un simple appel à microtime et une petite soustraction suffit !

Les optimisations SQL

Ca, c'est un gros chapitre ! J'ai récemment écouté quelqu'un qui comptait stocker ses templates HTML (tout le code HTML autour du contenu) dans une base de données, et qui voulait les récupérer pour chaque page. Il ne connaissait pas la fonction include.
Mon hébergement chez Olympe m'a fait comprendre qu'il était utile - et même important - d'optimiser le volume de données transitant sur le réseau, notamment pour les requêtes SQL.
En utilisant des requêtes plus complètes, plus poussées, on peut faire transiter le strict minimum, et ainsi alléger grandement le pauvre serveur SQL d'Olympe-Network votre propre serveur SQL.
  • Tout d'abord, l'étoile (astérisque) est à proscrire des requêtes :
SELECT * FROM `utilisateurs` est mauvais pour plusieurs raisons :
  1. Vous récupérez TOUS les champs correpondants, même si vous n'en avez pas besoin. C'est souvent près d'1Ko de données par requête par enregistrement, soit beaucoup en 24H pour l'ensemble des enregistrements de l'ensemble de vos bases sur l'ensemble de vos pages appelées par l'ensemble de vos visiteurs... Vous suivez ? ^^
  2. Vous ne connaissez pas la structure de la table que vous appelez ! Généralement je préfère avoir le nom des champs que j'utilise, ça me permet de coder beaucoup plus rapidement.
  • Pour compter le nombre d'enregistrements (nombre de messages, de joueurs, etc...) pensez à utiliser SELECT COUNT(*) AS nb FROM `utilisateurs` qui renvoie pour nb le nombre d'enregistrements (non nuls).
  • Vous pouvez effectuer des sélections croisées, pour cela je ne peux que vous indiquer l'excellent article sur le site du zéro

Voilà, là je suis un peu en manque d'idées, je compléterai sûrement cet article si des choses me reviennent.
J'espère que tout ceci pourra vous être utile =D

Quelques nouvelles :)

Après quelques mois d'absence, je suis de retour ! pour vous jouer un mauvais tour ! (désolé)

Dans ce billet :

> la solution tant attendue du code du FBI, et les explications : pas à pas, je cracke les codes du FBI :P

> l'indisponibilité du site cette semaine

> les prochains billets...

Lire la suite...

"Le FBI recrute" : un peu de cryptographie

Bonsoir à tous

J'ai découvert en lisant mes RSS (qui défilent en continu dans une barre tout en haut de l'écran, rétractable à souhaits, vive KDE), que le FBI organisait un "jeu" dont le but était de décrypter un message codé. (ce n'est nullement - enfin ça m'étonnerait - une recherche massive pour recruter, désolé de vous décevoir ;) ).
Le principe est simple : un message a été chiffré et vous devez le décrypter.
Code du FBI
J'ai personnellement trouvé ça très facile (moins de 30 minutes pour "cracker" le message), même si ils prétendent que 1% des personnes réussissent. Je pense surtout que 99% des gens n'ont pas la pêche d'essayer...
Voici quelques indices :
  • Chaque lettre a été remplacée par une autre, il suffit donc de trouver la table de conversion;
  • Seules les lettres ont été transformées, pas la ponctuation.
  • Le FBI met à disposition une aide "pour les enfants seulement" pour comprendre comment faire.
Allez, je vous mets la solution l'année prochaine ^^
J'attire cependant votre attention sur le vocabulaire à employer :
http://fr.wikipedia.org/wiki/Cryptographie#Vocabulaire .


J'en profite pour vous souhaiter à tous une bonne année 2009 et pleins de bonne choses !