' 1=1 GROUP BY CONCAT_WS ('~',version(), FLOOR(rand(0)*2)) having min(0)
1 > > La mia prima domanda è la funzione CONCAT
utilizzata in questa query
2 > > E perché usiamo avere min(0)
qui.
' 1=1 GROUP BY CONCAT_WS ('~',version(), FLOOR(rand(0)*2)) having min(0)
1 > > La mia prima domanda è la funzione CONCAT
utilizzata in questa query
2 > > E perché usiamo avere min(0)
qui.
Bene, analizziamolo:
CONCAT_WS
- Concatena con separatore. version()
- Restituisce la versione di MySQL. FLOOR(rand(0)*2)
- Emette la seguente sequenza di numeri: 0, 1, 1, 0, 1, ... having min(0)
- Di per sé, questo è illegale, poiché la clausola HAVING
richiede una condizione. Questo, e il fatto che non ci sia ; --
alla fine, implica che l'iniezione si aspetta una condizione alla fine. Quindi, concatena la stringa di versione e una sequenza di numeri in un gruppo. La sequenza di numeri per la clausola di gruppo è derivata da FLOOR(rand(0)*2)
.
La cosa su GROUP
è che richiede chiavi di gruppo univoche. Poiché version()
restituirà lo stesso valore ogni volta, concatenando quello e l'output di FLOOR(rand(0)*2)
tre volte, verranno generati due numeri diversi (0, 1) quindi una seconda istanza di 1, che causa un errore (voce duplicata per il gruppo tasto), che viene visualizzato all'utente. L'errore è simile a questo:
Duplicate entry '5.6.24-1~1' for key 'group_key'
Ciò causa il rilascio del numero di versione nella risposta come parte di un attacco di SQL injection basato sull'errore. Questo può quindi essere espanso per eseguire altri attacchi.
Per quanto riguarda perché l'attacker ha scelto FLOOR(rand(0)*2)
, è un'espressione dead-simple che è affidabile (la funzione rand()
è un PRNG che prende un parametro seed, lo stesso seme produce lo stesso sequenza sempre) e soddisfa il requisito di avere un'uscita duplicata relativamente rapidamente. Puoi scegliere un valore diverso da 0 e funzionerebbe comunque.
Leggi altre domande sui tag sql-injection mysql