Введение
Встречая в логах или в поле ввода подобную строку: ) AND EXTRACTVALUE(6832,CONCAT(0x7e,((SELECT (ELT(6832=6832,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение информации из базы данных через сообщения об ошибках. В данной статье мы разберём, как работает этот запрос, какие функции MySQL задействованы и почему такие строки считаются признаком попытки взлома.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запрос к базе данных. Если приложение недостаточно фильтрует пользовательский ввод, внедрённый код выполняется на сервере базы данных, что может привести к утечке конфиденциальных данных, изменению или удалению информации.
Существует несколько типов SQL-инъекций: union-based, error-based, blind, time-based и другие. Рассматриваемая строка относится к error-based инъекциям, когда злоумышленник заставляет базу данных выдать сообщение об ошибке, содержащее полезные данные.
Разбор строки ) AND EXTRACTVALUE(6832,CONCAT(0x7e,((SELECT (ELT(6832=6832,1)))),0x7e))-- -
Давайте разберём её по частям.
1. Закрывающая скобка и AND
Строка начинается с символа ). Это попытка закрыть скобку, которая могла быть открыта в оригинальном запросе приложения. Затем следует AND — логический оператор, позволяющий добавить условие к существующему запросу. Например, если исходный запрос был SELECT * FROM users WHERE id = (1), то после подстановки получится SELECT * FROM users WHERE id = (1) AND EXTRACTVALUE(...).
2. Функция EXTRACTVALUE
EXTRACTVALUE(XML_fragment, XPath_expression) — это функция MySQL (до версии 8.0), которая извлекает значение из XML-фрагмента по заданному XPath-выражению. Если XPath-выражение некорректно, функция генерирует ошибку, в тексте которой отображается переданный фрагмент. Это и используется для извлечения данных: злоумышленник передаёт в качестве XPath строку, содержащую результат подзапроса, и при ошибке сервер возвращает её в сообщении.
3. CONCAT и 0x7e
CONCAT(0x7e, ((SELECT ...)), 0x7e) объединяет символ ~ (код 0x7e) с результатом подзапроса и ещё одним ~. Символ ~ используется как маркер, чтобы в сообщении об ошибке легко было найти начало и конец извлечённых данных.
4. Подзапрос SELECT (ELT(6832=6832,1))
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Выражение 6832=6832 всегда истинно, что в числовом контексте равно 1. Таким образом, ELT(1, 1) вернёт 1. В данном примере подзапрос возвращает просто число 1 — это тестовая инъекция, чтобы проверить, выполняется ли она. В реальной атаке вместо 1 могла бы быть, например, version() или database().
5. Комментарий -- -
Два дефиса и пробел (или дефис) обозначают начало комментария в SQL. Всё, что идёт после, игнорируется базой данных. Это нужно, чтобы обрезать остаток оригинального запроса, который мог бы помешать выполнению инъекции.
Как это работает на практике
Предположим, уязвимый запрос выглядит так: SELECT * FROM articles WHERE id = (1). Злоумышленник подставляет вместо 1 строку ) AND EXTRACTVALUE(6832,CONCAT(0x7e,((SELECT (ELT(6832=6832,1)))),0x7e))-- -. В результате запрос становится:
SELECT * FROM articles WHERE id = (1) AND EXTRACTVALUE(6832,CONCAT(0x7e,((SELECT (ELT(6832=6832,1)))),0x7e))-- -)База данных выполняет EXTRACTVALUE, и поскольку второй аргумент не является корректным XPath (начинается с ~), возникает ошибка. В сообщении об ошибке MySQL отобразит переданную строку, например: XPATH syntax error: '~1~'. Так злоумышленник понимает, что инъекция работает, и может извлекать произвольные данные, заменяя 1 на другие SQL-выражения.
Почему это опасно?
Error-based инъекции позволяют быстро получать информацию о базе данных: версию СУБД, имя текущей базы, список таблиц и даже содержимое полей. В руках злоумышленника это может привести к полной компрометации данных. Кроме того, такие строки часто встречаются в логах веб-серверов, что говорит о попытках сканирования уязвимостей.
Как защититься?
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ, при котором пользовательский ввод передаётся отдельно от SQL-кода.
- Экранируйте специальные символы. Если параметризация невозможна, применяйте функции экранирования, предоставляемые драйвером базы данных.
- Ограничьте права пользователя БД. Не давайте приложению прав на выполнение опасных функций и доступ к системным таблицам.
- Обновляйте СУБД. В MySQL 8.0 функция EXTRACTVALUE удалена, что снижает риск подобных атак.
- Ведите мониторинг логов. Подобные строки в логах — сигнал о попытке взлома, требуйте немедленного реагирования.
Заключение
Строка ) AND EXTRACTVALUE(6832,CONCAT(0x7e,((SELECT (ELT(6832=6832,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, использующая особенности функций MySQL для извлечения данных через сообщения об ошибках. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои системы. Если вы встретили подобную строку в логах, это повод проверить безопасность вашего веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий