Что такое SQL-инъекция через EXTRACTVALUE?

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запрос к базе данных. В данном случае рассматривается конкретный пример: ")) AND EXTRACTVALUE(9360,CONCAT(0x7e,((SELECT (ELT(9360=9360,1)))),0x7e))-- -. Эта строка не является обычным запросом — это эксплойт, нацеленный на извлечение информации из базы данных MySQL через ошибки, вызываемые функцией EXTRACTVALUE.

Подобные строки часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL. Понимание их структуры помогает администраторам и разработчикам своевременно обнаруживать попытки взлома и укреплять защиту.

Разбор структуры инъекции

Рассматриваемый запрос состоит из нескольких частей, каждая из которых выполняет свою роль:

  • ")) — закрывает предыдущие скобки и кавычки в оригинальном SQL-запросе, чтобы внедрить свой код.
  • AND EXTRACTVALUE(9360,CONCAT(0x7e,((SELECT (ELT(9360=9360,1)))),0x7e)) — основная полезная нагрузка.
  • -- - — комментарий, который игнорирует оставшуюся часть исходного запроса.

Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако при некорректном XPath она генерирует ошибку, текст которой может содержать результат выполнения вложенного запроса. Это и используется для так называемой error-based SQL-инъекции.

Как работает EXTRACTVALUE

Синтаксис функции: EXTRACTVALUE(XML_fragment, XPath_expression). Она возвращает текст узла, соответствующего XPath. Если XPath синтаксически неверен, MySQL выдаёт ошибку вида XPATH syntax error: '...'. Злоумышленник конструирует XPath таким образом, чтобы в сообщение об ошибке попали данные из базы.

В нашем примере вторым аргументом идёт CONCAT(0x7e,((SELECT (ELT(9360=9360,1)))),0x7e). 0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить чтение результата в сообщении об ошибке.

Функция ELT и условие 9360=9360

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(9360=9360, 1) — условие 9360=9360 всегда истинно, что в MySQL соответствует 1. Значит, ELT вернёт первый элемент — число 1. Это простейший пример, демонстрирующий работу инъекции. В реальной атаке вместо 1 могла бы быть подзапрос, извлекающий имя пользователя, версию базы или хеши паролей.

Цель такой инъекции — заставить базу данных выдать конфиденциальную информацию через текст ошибки, который отображается на странице или попадает в лог.

Какие ошибки вызывает EXTRACTVALUE?

При выполнении запроса MySQL попытается интерпретировать строку, переданную в EXTRACTVALUE, как XPath. Поскольку строка начинается с тильды (~), это не является допустимым XPath-выражением. Возникает ошибка:

XPATH syntax error: '~1~'

Таким образом, в сообщении об ошибке отображается результат выполнения вложенного SELECT — в примере это 1. Если бы вместо 1 стоял подзапрос, например (SELECT password FROM users LIMIT 1), то в ошибке появился бы пароль. Именно поэтому error-based инъекции считаются одними из самых опасных.

Зачем злоумышленники используют EXTRACTVALUE?

Основная причина — обход фильтров и получение данных там, где другие методы (UNION, blind) не работают. Функция EXTRACTVALUE доступна в MySQL и MariaDB, но отсутствует в некоторых других СУБД. Она позволяет извлекать информацию посимвольно или целыми строками, если приложение выводит ошибки базы данных на экран.

Другой популярный вариант — функция UPDATEXML, которая работает аналогично. Обе они относятся к категории функций для работы с XML и часто используются в error-based атаках.

Как защититься от SQL-инъекций через EXTRACTVALUE?

Меры защиты универсальны для всех типов SQL-инъекций:

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

Также рекомендуется регулярно обновлять СУБД и фреймворки, проводить аудит кода и сканирование уязвимостей.

Что делать, если вы обнаружили такую строку в логах?

Появление подобных запросов в логах сервера — признак попытки взлома. Необходимо:

  • Проверить, не была ли атака успешной (искать необычные ошибки, изменения в базе).
  • Заблокировать IP-адрес источника, если атака повторяется.
  • Убедиться, что все формы и параметры URL защищены от инъекций.
  • Провести тестирование на проникновение или обратиться к специалистам по безопасности.

Игнорирование таких сигналов может привести к утечке данных и финансовым потерям.

Заключение

Запрос ")) AND EXTRACTVALUE(9360,CONCAT(0x7e,((SELECT (ELT(9360=9360,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для вызова ошибки с внедрёнными данными. Понимание механизма работы таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости. Главный совет: никогда не доверяйте пользовательскому вводу, используйте параметризованные запросы и скрывайте детали ошибок от посторонних.

Источники

  • SQL Injection — Wikipedia