Введение
В запросе пользователя указана строка %\") OR EXTRACTVALUE(1579,CONCAT(0x7e,((SELECT (ELT(1579=1579,1)))),0x7e))-- -. Это классический пример полезной нагрузки для error-based SQL-инъекции через функцию EXTRACTVALUE в СУБД MySQL или MariaDB. В данной статье мы детально разберём, что делает каждый элемент этого запроса, как злоумышленники используют такие конструкции для извлечения данных и как защититься от подобных атак.
Что такое SQL-инъекция?
SQL-инъекция (SQLi) — один из самых распространённых способов взлома веб-приложений. Атакующий внедряет в пользовательский ввод специальные символы или команды, которые интерпретируются базой данных как часть SQL-запроса. Это позволяет читать, изменять или удалять данные, а иногда и выполнять произвольные команды на сервере.
Существует несколько типов SQL-инъекций: UNION-based, error-based, blind (boolean и time-based). Наш случай относится к error-based — злоумышленник намеренно вызывает ошибку базы данных, чтобы в её тексте увидеть результат подзапроса.
Разбор полезной нагрузки
Рассмотрим строку по частям:
%\")— закрывающая кавычка и скобка, которые завершают оригинальный запрос приложения. Символ%может быть частью URL-кодирования, а\— экранированием. Часто такая последовательность используется, чтобы «вырваться» из строкового литерала в уязвимом параметре.OR EXTRACTVALUE(...)— логический оператор OR, после которого вызывается функцияEXTRACTVALUE. Если исходное условие ложно, СУБД вычислит правую часть, что и приводит к выполнению внедрённого кода.EXTRACTVALUE(1579, CONCAT(0x7e, (SELECT (ELT(1579=1579,1))), 0x7e))— сама функция.EXTRACTVALUE(XML_fragment, XPath_expression)извлекает значение из XML-документа по XPath. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой отображается переданный фрагмент.CONCAT(0x7e, ..., 0x7e)— объединяет символ~(0x7e) с результатом подзапроса и ещё одним~. Тильды служат маркерами, по которым атакующий легко находит выведенные данные в сообщении об ошибке.(SELECT (ELT(1579=1579,1)))— подзапрос, возвращающий значение.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь1579=1579— всегда истина (1), поэтомуELT(1,1)вернёт1. В реальной атаке вместо этой заглушки стоял бы подзапрос к системным таблицам, например,SELECT password FROM users LIMIT 1.-- -— комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.
Таким образом, при выполнении уязвимого запроса база данных попытается обработать XPath-выражение, содержащее символ ~ и результат подзапроса, что вызовет ошибку вида XPATH syntax error: '~1~'. Атакующий увидит эту ошибку на странице и получит искомые данные.
Почему EXTRACTVALUE используется для error-based инъекций?
Функция EXTRACTVALUE появилась в MySQL 5.1 и предназначена для работы с XML. Однако при передаче некорректного XPath-выражения она возвращает ошибку, текст которой содержит переданный фрагмент. Это делает её удобным инструментом для извлечения данных через сообщения об ошибках. Аналогичными свойствами обладают UPDATEXML и GTID_SUBSET.
Важно: в MySQL 5.7+ и MariaDB 10.2+ использование EXTRACTVALUE в некоторых конфигурациях может быть ограничено, но на устаревших версиях она по-прежнему работает.
Пример эксплуатации
Предположим, есть уязвимый параметр id в URL: https://example.com/product?id=1. Злоумышленник подставляет:
1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))
В ответе сервера появится ошибка: XPATH syntax error: '~5.7.32~'. Так узнаётся версия СУБД. Далее можно извлекать имена таблиц, столбцов и содержимое базы.
Последствия успешной атаки
- Утечка конфиденциальных данных: логины, пароли, персональные данные пользователей.
- Компрометация всей базы данных, включая возможность изменения или удаления записей.
- В некоторых случаях — выполнение команд на сервере через
LOAD_FILEилиINTO OUTFILE. - Репутационные и финансовые потери для владельца сайта.
Как защититься от error-based SQL-инъекций
Основной метод — использование параметризованных запросов (prepared statements). Они отделяют код SQL от данных, поэтому внедрённые символы не интерпретируются как команды.
Дополнительные меры:
- Валидация и фильтрация входных данных: проверяйте типы, длины, допустимые символы.
- Экранирование специальных символов с помощью функций СУБД, например
mysqli_real_escape_string. - Отключение вывода ошибок базы данных на продакшене: сообщения об ошибках не должны попадать в браузер.
- Использование ORM и современных фреймворков, которые по умолчанию применяют параметризацию.
- Регулярное обновление СУБД и веб-приложений.
- Применение WAF (Web Application Firewall) для блокировки подозрительных запросов.
Заключение
Строка %\") OR EXTRACTVALUE(1579,CONCAT(0x7e,((SELECT (ELT(1579=1579,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для error-based SQL-инъекции. Понимание её работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: ни один пользовательский ввод нельзя доверять без проверки.
Комментарии
—Войдите, чтобы оставить комментарий