Co naprawdę robi atak
Jest subtelny, ale sprytny szczegół dotyczący tego ataku, który przeoczyli inni respondenci. Zwróć uwagę na komunikat o błędzie Duplicate entry ':sjw:1:ukt:1' for key 'group_key'
. Ciąg :sjw:1:ukt:1
jest w rzeczywistości wynikiem wyrażenia ocenianego przez serwer MySQL. Jeśli Twoja aplikacja wyśle ciąg błędu MySQL z powrotem do przeglądarki, komunikat o błędzie może spowodować wyciek danych z Twojej bazy danych.
Ten rodzaj ataku jest stosowany w przypadkach, gdy wynik zapytania nie jest w inny sposób odsyłany do przeglądarki (ślepy wstrzyknięcie SQL) lub gdy klasyczny atak UNION SELECT jest trudny do wykonania. Działa również w zapytaniach INSERT/UPDATE/DELETE.
Jak zauważa Hawili, pierwotne konkretne zapytanie nie miało wyciekać żadnych informacji, był to tylko test, aby sprawdzić, czy Twoja aplikacja jest podatna na tego rodzaju wstrzyknięcie.
Atak nie nie powiedzie się, jak sugerował MvG, przyczyną tego błędu jest cel zapytania.
Lepszy przykład tego, jak można to wykorzystać:
> 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'
Dlaczego zgłaszany jest błąd
Dlaczego zapytanie powoduje ten błąd w MySQL, jest dla mnie nieco tajemnicą. Wygląda to na błąd MySQL, ponieważ GROUP BY ma zajmować się zduplikowanymi wpisami poprzez ich agregację. Uproszczenie zapytania przez Hawili w rzeczywistości nie powoduje błędu!
Wyrażenie FLOOR(RAND(0)*2)
daje następujące wyniki w kolejności, w oparciu o argument zalążka losowego 0:
> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
...
Ponieważ 3. wartość jest duplikatem drugiej, zgłaszany jest ten błąd. Można użyć dowolnej tabeli FROM zawierającej co najmniej 3 wiersze, ale tablica informacyjna_schema.tables jest powszechna. Części COUNT(*) i GROUP BY są niezbędne do wywołania błędu w 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'
Ten błąd nie występuje w zapytaniu równoważnym PostgreSQL:
# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
count | x
-------+---
83 | 0
90 | 1
(Przepraszam, że odpowiadam 1 rok spóźnienia, ale właśnie natknąłem się na to dzisiaj. To pytanie jest dla mnie interesujące, ponieważ nie wiedziałem, że istnieją sposoby na wyciek danych za pośrednictwem komunikatów o błędach z MySQL)