В мире веб-безопасности SQL-инъекции остаются одной из самых распространённых и опасных уязвимостей. Строка, которую вы видите в запросе, — это фрагмент эксплойта, использующего функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. В этой статье мы детально разберём, что означает каждый элемент этого запроса, как работает атака и как от неё защититься.

Что такое EXTRACTVALUE?

EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), предназначенная для работы с XML-документами. Она извлекает значение из XML-строки по заданному XPath-выражению. Синтаксис:

EXTRACTVALUE(XML_фрагмент, XPath_выражение)

Функция возвращает текст узла, соответствующего XPath. Если XPath некорректен или XML невалиден, MySQL генерирует ошибку XPATH syntax error. Именно это свойство и используется злоумышленниками для проведения error-based SQL-инъекций.

Разбор вредоносного запроса

Рассмотрим строку по частям:

%') AND EXTRACTVALUE(8402,CONCAT(0x7e,((SELECT (ELT(8402=8402,1)))),0x7e))-- -
  • %') — закрывает предыдущее строковое значение и скобку в уязвимом SQL-запросе. Символ % часто используется в шаблонах LIKE, а ') завершает строку и условие.
  • AND — логический оператор, добавляющий условие к оригинальному запросу.
  • EXTRACTVALUE(8402, ...) — вызов уязвимой функции. Первый аргумент (8402) — произвольное число, которое не влияет на результат, но должно быть допустимым XML.
  • CONCAT(0x7e, ((SELECT (ELT(8402=8402,1)))), 0x7e) — конкатенация тильды (0x7e — шестнадцатеричный код символа ~), результата подзапроса и ещё одной тильды. Тильды служат маркерами, чтобы облегчить извлечение данных из сообщения об ошибке.
  • SELECT (ELT(8402=8402,1)) — подзапрос, возвращающий 1, если условие 8402=8402 истинно (а оно всегда истинно). ELT — функция, возвращающая N-й элемент из списка. Здесь она всегда возвращает 1. В реальной атаке вместо этого подзапроса внедряется запрос к базе данных, например, SELECT version() или SELECT password FROM users LIMIT 1.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.

Таким образом, при выполнении этого кода MySQL попытается интерпретировать строку, начинающуюся с тильды, как XPath. Поскольку ~ не является допустимым началом XPath, возникнет ошибка вида:

ERROR 1105 (HY000): XPATH syntax error: '~1~'

В сообщении об ошибке отобразится результат подзапроса, окружённый тильдами. Злоумышленник может заменить подзапрос на извлечение любых данных и читать их через ошибки.

Почему это работает?

MySQL при ошибке в функции EXTRACTVALUE возвращает клиенту подробное сообщение, включающее фрагмент переданного XPath. Если в этот фрагмент внедрить результат подзапроса, он окажется в тексте ошибки. Это классический пример error-based SQL-инъекции. Уязвимость возникает, когда пользовательский ввод попадает в SQL-запрос без должной обработки, и при этом включён вывод ошибок СУБД.

Стоит отметить, что в версиях MySQL 5.7 и выше функция EXTRACTVALUE всё ещё доступна, но её использование в production-среде не рекомендуется из-за подобных рисков. В MariaDB также есть аналогичные функции.

Примеры других error-based функций

Помимо EXTRACTVALUE, злоумышленники часто используют:

  • UPDATEXML — аналогичная функция для обновления XML, также генерирует ошибки с внедрёнными данными.
  • GTID_SUBSET и GTID_SUBTRACT — в MySQL генерируют ошибки, содержащие результат подзапроса.
  • EXP — математическая функция, вызывающая ошибку переполнения с внедрёнными данными (в некоторых версиях).

Как защититься от таких атак?

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

Заключение

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

Источники