Что это за строка?
Представленная строка:
") OR EXTRACTVALUE(3722,CONCAT(0x7e,((SELECT (ELT(3722=3722,1)))),0x7e))-- -
является классическим примером error-based SQL-инъекции (инъекции, основанной на ошибках) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы данных путём вызова ошибок, в тексте которых возвращается запрашиваемая информация.
Подобные строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в задачах по пентесту. Понимание их работы помогает разработчикам и администраторам правильно защищать приложения.
Разбор компонентов запроса
Разберём строку по частям:
")— закрывающая кавычка и скобка. Предполагается, что исходный SQL-запрос имел видSELECT ... WHERE field = ("..."). Злоумышленник закрывает строковый литерал и скобку, чтобы внедрить свой код.OR— логический оператор, который делает условие всегда истинным или позволяет выполнить дополнительное выражение.EXTRACTVALUE(3722, CONCAT(0x7e, ((SELECT (ELT(3722=3722,1)))), 0x7e))— вызов функции EXTRACTVALUE, которая извлекает значение из XML-фрагмента по XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, содержащую переданный аргумент.-- -— комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.
Функция EXTRACTVALUE
EXTRACTVALUE(XML_frag, XPath_expr) возвращает текст первого текстового узла, найденного по XPath-выражению. Если XPath содержит недопустимые символы (например, тильду ~), MySQL выдаёт ошибку вида:
XPATH syntax error: '~1~'
Именно эту ошибку и использует атакующий: в сообщении об ошибке отображается результат подзапроса.
Функция ELT и условие 3722=3722
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(3722=3722, 1) — условие 3722=3722 всегда истинно (равно 1), поэтому возвращается первый элемент — 1. Это простейшая проверка работоспособности инъекции. В реальных атаках вместо 1 подставляются подзапросы, извлекающие имена таблиц, колонок или данные пользователей.
CONCAT и 0x7e
CONCAT(0x7e, ..., 0x7e) объединяет строки. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как маркер, чтобы в сообщении об ошибке было легко найти внедрённые данные. Например, ошибка примет вид XPATH syntax error: '~1~'.
Как работает атака
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE name = ("$input")
Если пользователь передаст строку ") OR EXTRACTVALUE(3722,CONCAT(0x7e,((SELECT (ELT(3722=3722,1)))),0x7e))-- -, итоговый SQL станет:
SELECT * FROM users WHERE name = ("") OR EXTRACTVALUE(3722,CONCAT(0x7e,((SELECT (ELT(3722=3722,1)))),0x7e))-- -")
База данных выполнит EXTRACTVALUE с некорректным XPath, возникнет ошибка, и в ответе сервера (если ошибки не подавлены) появится сообщение XPATH syntax error: '~1~'. Это подтверждает, что инъекция работает.
Далее атакующий заменяет 1 на подзапрос, например:
SELECT (SELECT table_name FROM information_schema.tables LIMIT 0,1)
и получает имя первой таблицы в ошибке. Меняя LIMIT, можно перебрать все таблицы и колонки, а затем извлечь данные.
Примеры реальных полезных нагрузок
Вот как выглядят типичные error-based инъекции через EXTRACTVALUE:
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -— получение имени текущей базы данных.' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT user()), 0x7e))-- -— получение имени пользователя MySQL.' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x7e))-- -— извлечение имени первой таблицы.
Аналогичный подход используется с функциями UPDATEXML и GTID_SUBSET.
Чем опасна error-based SQL-инъекция?
Error-based инъекции позволяют злоумышленнику:
- получить структуру базы данных (имена таблиц, колонок);
- извлечь конфиденциальные данные (логины, пароли, персональные данные);
- в некоторых случаях выполнить произвольные команды на сервере (при наличии соответствующих привилегий).
Опасность усугубляется тем, что для атаки достаточно лишь выводить сообщения об ошибках СУБД в ответе приложения. Многие фреймворки в режиме отладки делают это по умолчанию.
Как защититься от error-based SQL-инъекций
Основные меры защиты:
- Использование подготовленных выражений (prepared statements). Параметризация запросов исключает возможность внедрения SQL-кода.
- Экранирование специальных символов. Если параметризация невозможна, применяйте функции экранирования, например
mysqli_real_escape_string. - Отключение вывода ошибок СУБД. Настройте приложение так, чтобы детали ошибок не попадали в ответ клиенту. Логируйте их на сервере.
- Ограничение привилегий пользователя БД. Не используйте учётную запись с правами
FILEилиSUPERдля веб-приложений. - Использование WAF. Веб-приложения-экраны могут блокировать известные шаблоны атак, но не являются панацеей.
- Регулярное обновление СУБД и фреймворков. Устаревшие версии могут содержать дополнительные уязвимости.
Заключение
Строка ") OR EXTRACTVALUE(3722,CONCAT(0x7e,((SELECT (ELT(3722=3722,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для error-based SQL-инъекции в MySQL. Она использует функцию EXTRACTVALUE для вызова ошибки, в тексте которой возвращаются данные. Понимание принципов работы таких атак необходимо для построения надёжной защиты веб-приложений. Разработчикам следует всегда использовать параметризованные запросы и не выводить ошибки СУБД конечным пользователям.
Комментарии
—Войдите, чтобы оставить комментарий