L'affermazione
if(now()=sysdate(),sleep(6),0)/*'XOR(if(now()=sysdate(),sleep(6),0))OR'"XOR(if(now()=sysdate(),sleep(6),0))OR"*/
in pratica prova tre diversi punti di iniezione contemporaneamente.
1. Quello diretto
if(now()=sysdate(),sleep(6),0)/*...*/
Se l'input sarebbe interpretato direttamente (senza caratteri di escape) questo sql verrebbe attivato. Il resto della stringa di input sarà commentato.
2. Virgolette singole ".."
..'XOR(if(now()=sysdate(),sleep(6),0))OR'..
Se l'input è incapsulato nell'istruzione con virgolette singole, i caratteri all'inizio e alla fine verranno esclusi dal contesto e verrà interpretato lo sql tra di essi.
3. Virgolette doppie ".."
.."XOR(if(now()=sysdate(),sleep(6),0))OR"*/
Come per le virgolette singole ma funziona per gli input incapsulati tra virgolette doppie.
Come potrebbe apparire la query
Se è PHP che costruisce questa dichiarazione MySQL, potrebbe apparire come una delle seguenti (a seconda del caso che la innesca):
sql = "INSERT INTO tbl_addresses (address,user) VALUES("+$_POST["address"]+",..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES('"+$_POST["address"]+"',..)"
sql = "INSERT INTO tbl_addresses (address,user) VALUES(\""+$_POST["address"]+"\",..)"
Come funziona
Le dichiarazioni sono le stesse per ogni caso di iniezione.
In primo luogo si confronta se il valore di ritorno della funzione "ora" corrisponde a quello della funzione "sysdate". Se questo è il caso (e dovrebbe essere), la funzione "sleep" verrà chiamata con un tempo di 6 o 0 secondi, con conseguente ritardo che hai osservato.
È possibile sfruttarlo come un'iniezione SQL completamente cieca. Uno strumento come sqlmap ti aiuterà in questo, perché ci vorrebbe un sacco di tempo se lo fai a mano.
Quello che fondamentalmente farà (in forma semplificata), è un problema come:
if ( nth_character_of(password) == "a" , sleep(6), 0)
Dove "nth_character_of" sarà una funzione specifica del database che seleziona un carattere da una stringa e "password" sarà una query che restituisce qualsiasi valore che si desidera recuperare dal database. Utilizzerà anche un metodo ottimizzato per trovare i caratteri corretti.
Se sqlmap sperimenta un ritardo, saprà che il confronto è stato corretto e itera ulteriormente.
Restringendolo
Puoi provare a fornire separatamente ciascuno dei tre casi di iniezione e dare un'occhiata al risultato. In questo modo la stringa di iniezione diventa molto più breve e più facile da modificare e capire.
Che cosa potresti provare
Se il valore viene effettivamente restituito nel frontend, come hai detto in un commento sotto un'altra risposta, quell'iniezione SQL non è puramente cieca.
Potresti riuscire a inserire il tuo valore direttamente in questo modo:
version()/*'+version()+'"+version()+"*/
per recuperare la versione nel frontend o con la tua query in tutte e tre le posizioni come:
(select password from users LIMIT 1)/*'+(select password from users LIMIT 1)+'"+(select password from users LIMIT 1)+"*/
Quello con la query personalizzata potrebbe non funzionare a seconda della codifica necessaria in questa specifica applicazione, ma vale la pena provarlo.