Cosa fa veramente l'attacco
C'è un dettaglio sottile ma intelligente su questo attacco che altri rispondenti hanno mancato. Nota il messaggio di errore Duplicate entry ':sjw:1:ukt:1' for key 'group_key'
. La stringa :sjw:1:ukt:1
è in realtà il risultato di un'espressione valutata dal tuo server MySQL. Se la tua applicazione invia nuovamente la stringa di errore MySQL al browser, il messaggio di errore può perdere dati dal tuo database.
Questo tipo di attacco viene utilizzato nei casi in cui il risultato della query non viene altrimenti restituito al browser (iniezione SQL cieca) o quando un classico attacco UNION SELECT è complicato da eseguire. Funziona anche nelle query INSERT/UPDATE/DELETE.
Come osserva Hawili, la query particolare originale non doveva far trapelare alcuna informazione, era solo un test per vedere se la tua applicazione è vulnerabile a questo tipo di iniezione.
L'attacco non fallire come suggerito da MvG, causare questo errore è lo scopo della query.
Un esempio migliore di come questo può essere utilizzato:
> SELECT COUNT(*),CONCAT((SELECT CONCAT(user,password) FROM mysql.user LIMIT 1),
> 0x20, FLOOR(RAND(0)*2)) x
> FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key 'group_key'
Perché viene generato l'errore
Perché la query causa questo errore in MySQL è in qualche modo un mistero per me. Sembra un bug di MySQL, dal momento che GROUP BY dovrebbe gestire voci duplicate aggregandole. La semplificazione della query di Hawili, infatti, non causa l'errore!
L'espressione FLOOR(RAND(0)*2)
fornisce i seguenti risultati in ordine, in base all'argomento seme casuale 0:
> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
...
Poiché il 3° valore è un duplicato del 2°, viene generato questo errore. È possibile utilizzare qualsiasi tabella FROM con almeno 3 righe, ma information_schema.tables è comune. Le parti COUNT(*) e GROUP BY sono necessarie per provocare l'errore in MySQL:
> SELECT COUNT(*),FLOOR(RAND(0)*2)x FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
Questo errore non si verifica nella query equivalente a PostgreSQL:
# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
count | x
-------+---
83 | 0
90 | 1
(Scusa se rispondo con 1 anno di ritardo, ma mi sono imbattuto in questo proprio oggi. Questa domanda è interessante per me perché non sapevo che ci fossero modi per far trapelare dati tramite messaggi di errore da MySQL)