Что это за строка?
Строка ') AND EXTRACTVALUE(6360,CONCAT(0x7e,((SELECT (ELT(6360=6360,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции широко используются злоумышленниками при тестировании на проникновение и в атаках на веб-приложения, где входные данные не фильтруются должным образом.
Внешне это выглядит как бессмысленный набор символов, но на самом деле каждый элемент здесь имеет строгое назначение. Давайте разберём его по частям.
Структура инъекции
Разложим строку на составляющие:
')— закрывает предыдущее выражение в SQL-запросе. Символы'и)позволяют «вырваться» из контекста, в который встроена инъекция. Часто это закрытие строкового литерала и скобки, чтобы далее можно было добавить свои команды.AND— логический оператор, который присоединяет наше условие к оригинальному запросу. Если исходный запрос был истинным, то добавлениеAND ...заставит СУБД вычислить и правую часть.EXTRACTVALUE(6360, CONCAT(0x7e, ((SELECT (ELT(6360=6360,1)))), 0x7e))— ключевая функция, вызывающая ошибку.EXTRACTVALUEпринимает два аргумента: фрагмент XML и выражение XPath. Если XPath синтаксически неверен, MySQL генерирует ошибку, в тексте которой отображается переданное значение.-- -— комментарий. В MySQL--(с пробелом после) означает начало комментария до конца строки. Дефис после пробела добавлен для надёжности, чтобы обойти возможные парсеры, требующие пробела.
Функция EXTRACTVALUE
EXTRACTVALUE() — это встроенная функция MySQL для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_fragment, XPath_expression). Если XPath-выражение некорректно (например, содержит недопустимые символы), MySQL возвращает ошибку вида:
XPATH syntax error: '~1~'
Именно это и нужно атакующему: в тексте ошибки отобразится результат подзапроса.
Конкатенация и маркеры
CONCAT(0x7e, ..., 0x7e) объединяет строки. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильды служат маркерами, чтобы в сообщении об ошибке было легко найти внедрённые данные. Они обрамляют результат подзапроса, делая его заметным.
Подзапрос с ELT
(SELECT (ELT(6360=6360,1))) — это сердце инъекции. Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Если N=1, возвращается первая строка. В нашем случае условие 6360=6360 всегда истинно, поэтому ELT(1,1) вернёт 1. Это простейший пример; в реальных атаках вместо 6360=6360 подставляются условия для извлечения данных побитово или посимвольно. Например, ELT(ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>100,1) и т.п.
Число 6360 — произвольный идентификатор, который может меняться. Он не несёт смысловой нагрузки, кроме как быть частью условия. В некоторых вариантах вместо ELT используются UPDATEXML или GTID_SUBSET.
Как это работает на практике
Предположим, на сервере выполняется запрос:
SELECT * FROM articles WHERE id = '') AND EXTRACTVALUE(6360,CONCAT(0x7e,((SELECT (ELT(6360=6360,1)))),0x7e))-- -';
СУБД видит: id = '' (пустая строка), затем AND с функцией EXTRACTVALUE. Поскольку EXTRACTVALUE получает некорректный XPath (из-за тильд), она выбрасывает ошибку. В сообщении об ошибке будет что-то вроде:
XPATH syntax error: '~1~'
Таким образом, атакующий узнаёт, что подзапрос вернул 1. Меняя условие внутри ELT, можно извлекать данные по битам: например, проверять, больше ли код символа какого-то значения. Это медленный, но надёжный метод, работающий даже при отсутствии вывода данных на экран.
Зачем это нужно злоумышленнику?
Error-based SQL-инъекции позволяют получать содержимое базы данных, даже если приложение не отображает результаты запроса. Ошибки СУБД часто выводятся в браузер или логи, что даёт атакующему канал утечки. С помощью таких конструкций можно извлечь имена таблиц, столбцов, логины, пароли и другую конфиденциальную информацию.
Особенно опасны подобные инъекции в сочетании с недостаточной валидацией входных данных. Если приложение использует динамическое построение SQL-запросов без параметризации, оно уязвимо.
Как защититься?
Основные меры защиты от error-based SQL-инъекций (и SQL-инъекций в целом):
- Параметризованные запросы (prepared statements) — самый надёжный способ. Всегда отделяйте код от данных.
- Экранирование специальных символов — используйте функции экранирования, предоставляемые драйвером СУБД.
- Валидация входных данных — проверяйте типы, длины, допустимые символы. Не доверяйте пользовательскому вводу.
- Отключение вывода ошибок СУБД в production — настройте логирование ошибок в файл, а не в ответ клиенту.
- Использование ORM — современные ORM обычно используют параметризацию.
- Регулярные обновления — устанавливайте патчи безопасности для СУБД и фреймворков.
Также рекомендуется проводить аудит кода и сканирование уязвимостей, чтобы вовремя выявлять подобные проблемы.
Заключение
Строка ') AND EXTRACTVALUE(6360,CONCAT(0x7e,((SELECT (ELT(6360=6360,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для эксплуатации ошибок MySQL. Понимание её работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Никогда не пренебрегайте параметризацией запросов и валидацией входных данных — это основа безопасной работы с базами данных.
Комментарии
—Войдите, чтобы оставить комментарий