MS Access SQL Injection
Last updated
Last updated
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
La concatenazione di stringhe è possibile con i caratteri & (%26)
e + (%2b)
.
Non ci sono commenti in MS Access, ma apparentemente è possibile rimuovere l'ultimo di una query con un carattere NULL:
Se questo non funziona, puoi sempre correggere la sintassi della query:
Non sono supportate.
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.
Proprio come TOP, puoi usare LAST
che otterrà le righe dalla fine.
In una SQLi di solito vorrai in qualche modo eseguire una nuova query per estrarre informazioni da altre tabelle. MS Access richiede sempre che in sottoquery o query extra sia indicato un FROM
.
Quindi, se vuoi eseguire un UNION SELECT
o UNION ALL SELECT
o un SELECT
tra parentesi in una condizione, devi sempre indicare un FROM
con un nome di tabella valido.
Pertanto, devi conoscere un nome di tabella valido.
Questo ti permetterà di esfiltrare i valori della tabella corrente senza dover conoscere il nome della tabella.
MS Access consente una sintassi strana come '1'=2='3'='asd'=false
. Come di consueto, l'iniezione SQL sarà all'interno di una clausola WHERE
e possiamo abusarne.
Immagina di avere una SQLi in un database MS Access e sai (o hai indovinato) che un nome di colonna è username, e questo è il campo che vuoi esfiltrare. Potresti controllare le diverse risposte dell'app web quando viene utilizzata la tecnica dei chaining equals e potenzialmente esfiltrare contenuti con un iniezione booleana utilizzando la funzione Mid
per ottenere sottostringhe.
Se conosci il nome della tabella e colonna da estrarre, puoi utilizzare una combinazione tra Mid
, LAST
e TOP
per leakare tutte le informazioni tramite SQLi booleano:
Feel free to check this in the online playground.
Utilizzando la tecnica del chaining equals puoi anche forzare i nomi delle tabelle con qualcosa come:
Puoi anche utilizzare un modo più tradizionale:
Feel free to check this in the online playground.
Nomi comuni delle tabelle Sqlmap: https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt
C'è un'altra lista in http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
Puoi forzare bruscamente i nomi delle colonne correnti con il trucco della concatenazione uguale con:
O con un group by:
Oppure puoi forzare i nomi delle colonne di una tabella diversa con:
Abbiamo già discusso della tecnica del chaining equals per estrarre dati dalle tabelle attuali e da altre tabelle. Ma ci sono altri modi:
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.
Mid('admin',1,1)
ottiene la sottostringa dalla posizione 1 lunghezza 1 (la posizione iniziale è 1)
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
COUNT(*)
Conta il numero di elementi
Da qui puoi vedere una query per ottenere i nomi delle tabelle:
Tuttavia, nota che è molto tipico trovare SQL Injection dove non hai accesso per leggere la tabella MSysObjects
.
La conoscenza del percorso assoluto della root 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
MS Access risponde con un messaggio di errore contenente il percorso completo della directory web.
Il seguente vettore di 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 è invalido:
http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00
Un altro modo per enumerare i file consiste nel specificare un elemento database.table. Se il file specificato esiste, MS Access visualizza un messaggio di errore sul formato del database.
http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00
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.
Access PassView è 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.
Impara e pratica il Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica il Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)