Введение
Строка %") AND EXTRACTVALUE(7091,CONCAT(0x7e,((SELECT (ELT(7091=7091,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер базы данных.
В данной статье мы подробно разберём, как работает этот запрос, какие функции задействованы и почему он представляет опасность. Материал будет полезен как специалистам по информационной безопасности, так и разработчикам, желающим понять механизмы защиты.
Что такое error-based SQL-инъекция?
SQL-инъекция — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Error-based инъекция — это разновидность, при которой атакующий заставляет базу данных выдать ошибку, содержащую полезные данные (например, версию СУБД, имена таблиц, содержимое полей).
В MySQL существует несколько функций, специально предназначенных для генерации ошибок с внедрёнными данными. Одна из них — EXTRACTVALUE(), которая извлекает значение из XML-строки по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим переданный аргумент. Это и позволяет извлекать произвольные данные.
Разбор строки инъекции
Рассмотрим каждый элемент запроса:
- %") — это часть исходного запроса, которая, вероятно, была вставлена в параметр, заключённый в кавычки и скобки. Символ
%может быть частью шаблона LIKE, а")закрывает кавычку и скобку, завершая оригинальное выражение. - AND — логический оператор, добавляющий условие к запросу.
- EXTRACTVALUE(7091,CONCAT(0x7e,((SELECT (ELT(7091=7091,1)))),0x7e)) — вызов функции EXTRACTVALUE с двумя аргументами. Первый аргумент — число 7091 (произвольное). Второй аргумент — результат конкатенации символа
~(0x7e в шестнадцатеричном виде), подзапроса и снова~. - -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не возникло синтаксической ошибки.
Функция EXTRACTVALUE
Синтаксис: EXTRACTVALUE(XML_fragment, XPath_expression). Функция возвращает текст из XML-фрагмента, соответствующий XPath-выражению. Если XPath-выражение содержит недопустимые символы (например, ~), MySQL генерирует ошибку вида: XPATH syntax error: '~...~'. Именно эта ошибка и содержит внедрённые данные.
Функция CONCAT
CONCAT() объединяет строки. Здесь она склеивает тильду, результат подзапроса и ещё одну тильду. Тильда (0x7e) используется как маркер, чтобы в сообщении об ошибке было легко найти внедрённые данные между двумя тильдами.
Подзапрос с ELT
SELECT (ELT(7091=7091,1)) — это подзапрос, который возвращает число 1. Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Если N=1, возвращается первая строка. В данном случае условие 7091=7091 всегда истинно, поэтому ELT возвращает 1. Это простейший пример; в реальных атаках вместо 1 может быть подзапрос, извлекающий данные (например, версию БД, имя пользователя, хеши паролей).
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE name LIKE '%");
Злоумышленник подставляет вместо % строку %") AND EXTRACTVALUE(7091,CONCAT(0x7e,((SELECT (ELT(7091=7091,1)))),0x7e))-- -. В результате запрос становится:
SELECT * FROM users WHERE name LIKE '%") AND EXTRACTVALUE(7091,CONCAT(0x7e,((SELECT (ELT(7091=7091,1)))),0x7e))-- -';
MySQL выполняет функцию EXTRACTVALUE, которая вызывает ошибку. В ответе сервера появится сообщение:
XPATH syntax error: '~1~'
Таким образом, атакующий видит результат выполнения подзапроса — в данном случае 1. Заменив ELT(7091=7091,1) на что-то вроде (SELECT version()), он получит версию СУБД. Аналогично можно извлекать имена таблиц, столбцов и любые другие данные.
Опасность и последствия
Error-based SQL-инъекции через EXTRACTVALUE позволяют злоумышленнику:
- Получить информацию о структуре базы данных.
- Извлечь конфиденциальные данные (логины, пароли, персональные данные).
- В некоторых случаях — выполнить произвольные SQL-запросы, вплоть до удаления или изменения данных.
Эта техника особенно опасна, потому что не требует слепого подбора и даёт быстрый результат. Ошибки СУБД часто отображаются прямо на странице, что упрощает атаку.
Как защититься
Основные меры защиты от SQL-инъекций:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ.
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(). - Отключение вывода ошибок СУБД на продакшн-серверах. Ошибки должны логироваться, но не показываться пользователю.
- Применение WAF (Web Application Firewall) для фильтрации подозрительных запросов.
- Регулярное обновление СУБД и фреймворков, чтобы закрыть известные уязвимости.
Важно понимать, что никакая отдельная мера не даёт 100% гарантии, поэтому рекомендуется использовать комплексный подход.
Заключение
Строка %") AND EXTRACTVALUE(7091,CONCAT(0x7e,((SELECT (ELT(7091=7091,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для MySQL. Она демонстрирует, как злоумышленники могут использовать функции EXTRACTVALUE, CONCAT и ELT для извлечения данных через сообщения об ошибках. Понимание этой техники помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.
Если вы обнаружили подобные конструкции в логах или запросах, это признак попытки взлома. Немедленно проверьте свой код на уязвимости и примите меры по устранению.
Комментарии
—Войдите, чтобы оставить комментарий