Что такое ExtractValue в MySQL?
Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из фрагмента XML-документа с помощью выражения XPath. Она принимает два строковых аргумента: первый — это XML-разметка, второй — XPath-локатор. Функция возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению.
Например, запрос SELECT EXTRACTVALUE('<a><b>текст</b></a>', '/a/b') вернёт строку «текст». Однако при некорректном XPath-выражении MySQL генерирует ошибку, которая может содержать часть переданных данных. Именно эта особенность делает функцию опасным инструментом в руках злоумышленников.
SQL-инъекция на основе ошибок (error-based)
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Error-based SQL-инъекция — это техника, при которой атакующий заставляет сервер вернуть сообщение об ошибке, содержащее конфиденциальные данные. Функция EXTRACTVALUE часто используется для реализации таких атак, поскольку она позволяет вывести результат подзапроса прямо в текст ошибки.
Пример вредоносного запроса
Рассмотрим запрос из вашего вопроса:
)) AND EXTRACTVALUE(6289,CONCAT(0x7e,((SELECT (ELT(6289=6289,1)))),0x7e))-- -
Разберём его по частям:
- )) — закрывающие скобки, которые завершают предыдущее выражение в уязвимом запросе.
- AND — логический оператор, добавляющий условие.
- EXTRACTVALUE(6289, CONCAT(0x7e, ((SELECT (ELT(6289=6289,1)))), 0x7e)) — вызов функции с двумя аргументами. Первый аргумент — число 6289 (может быть любым), второй — конкатенация тильды (0x7e), результата подзапроса и ещё одной тильды.
- -- - — комментарий, который обрезает оставшуюся часть оригинального запроса.
Внутри EXTRACTVALUE выполняется подзапрос SELECT (ELT(6289=6289,1)). Функция ELT возвращает N-й элемент из списка. Здесь условие 6289=6289 всегда истинно, поэтому ELT(1,1) вернёт 1. Однако в реальной атаке вместо 1 может быть подставлено выражение, извлекающее имя пользователя, хэш пароля или другую информацию, например: SELECT user() или SELECT password FROM users LIMIT 1.
Когда MySQL пытается вычислить XPath-выражение, содержащее недопустимые символы (например, тильду ~), он выбрасывает ошибку вида: XPATH syntax error: '~результат~'. В этом сообщении и утекают данные.
Зачем нужны 0x7e и CONCAT?
Символ 0x7e — это шестнадцатеричное представление тильды (~). Она используется как маркер, чтобы отделить извлекаемые данные от остального текста ошибки. CONCAT объединяет тильду, полезную нагрузку (результат подзапроса) и ещё одну тильду. Это позволяет атакующему легко найти нужную строку в сообщении об ошибке.
Как злоумышленники используют эту уязвимость?
Основная цель — получить доступ к данным, которые не должны быть видны. С помощью error-based инъекций через EXTRACTVALUE можно:
- Извлечь версию базы данных (
SELECT version()). - Получить имя текущего пользователя БД (
SELECT user()). - Вытащить имена таблиц и колонок из information_schema.
- Похитить учётные данные пользователей (логины, хэши паролей).
Атака обычно проводится автоматизированными инструментами, например sqlmap, которые подставляют различные полезные нагрузки и анализируют ответы сервера.
Методы защиты от SQL-инъекций
Чтобы предотвратить эксплуатацию уязвимостей, связанных с EXTRACTVALUE и другими функциями, необходимо применять комплекс мер:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ, при котором SQL-код и данные передаются раздельно, и внедрение команд становится невозможным.
- Экранирование специальных символов. Если prepared statements недоступны, следует тщательно экранировать все пользовательские вводы с помощью функций вроде
mysqli_real_escape_string. - Валидация входных данных. Проверяйте, что вводимые данные соответствуют ожидаемому формату (числа, email, даты).
- Ограничение прав пользователя БД. Приложение должно подключаться к базе с минимально необходимыми привилегиями. Не используйте root.
- Отключение вывода ошибок на продакшене. Ошибки СУБД не должны показываться пользователю, чтобы злоумышленник не мог получить через них информацию.
- Регулярное обновление СУБД и фреймворков. Исправления безопасности закрывают известные векторы атак.
- Использование WAF (Web Application Firewall). Современные WAF могут обнаруживать и блокировать попытки SQL-инъекций.
Заключение
Функция EXTRACTVALUE, изначально предназначенная для работы с XML, стала популярным инструментом для проведения error-based SQL-инъекций. Конструкции вида AND EXTRACTVALUE(..., CONCAT(0x7e, (подзапрос), 0x7e)) позволяют злоумышленникам извлекать произвольные данные из базы через сообщения об ошибках. Единственный надёжный способ защиты — использовать параметризованные запросы и следовать лучшим практикам безопасности при разработке веб-приложений.
Комментарии
—Войдите, чтобы оставить комментарий