Что такое 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 и другими функциями, необходимо применять комплекс мер:

  1. Использование подготовленных выражений (prepared statements). Это самый надёжный способ, при котором SQL-код и данные передаются раздельно, и внедрение команд становится невозможным.
  2. Экранирование специальных символов. Если prepared statements недоступны, следует тщательно экранировать все пользовательские вводы с помощью функций вроде mysqli_real_escape_string.
  3. Валидация входных данных. Проверяйте, что вводимые данные соответствуют ожидаемому формату (числа, email, даты).
  4. Ограничение прав пользователя БД. Приложение должно подключаться к базе с минимально необходимыми привилегиями. Не используйте root.
  5. Отключение вывода ошибок на продакшене. Ошибки СУБД не должны показываться пользователю, чтобы злоумышленник не мог получить через них информацию.
  6. Регулярное обновление СУБД и фреймворков. Исправления безопасности закрывают известные векторы атак.
  7. Использование WAF (Web Application Firewall). Современные WAF могут обнаруживать и блокировать попытки SQL-инъекций.

Заключение

Функция EXTRACTVALUE, изначально предназначенная для работы с XML, стала популярным инструментом для проведения error-based SQL-инъекций. Конструкции вида AND EXTRACTVALUE(..., CONCAT(0x7e, (подзапрос), 0x7e)) позволяют злоумышленникам извлекать произвольные данные из базы через сообщения об ошибках. Единственный надёжный способ защиты — использовать параметризованные запросы и следовать лучшим практикам безопасности при разработке веб-приложений.

Источники