Что это за строка с EXTRACTVALUE?

Строка вида %")) AND EXTRACTVALUE(7899,CONCAT(0x7e,((SELECT (ELT(7899=7899,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через вывод сообщений об ошибках. Встречая подобное в логах сервера или в поле ввода, многие задаются вопросом: что это и какова её цель? Ответ прост: это попытка взлома, направленная на получение информации из базы данных.

В данной статье мы разберём, как работает эта инъекция, какие функции задействованы и как защитить свой сайт от подобных атак.

Расшифровка компонентов инъекции

Рассмотрим каждый элемент запроса подробно.

EXTRACTVALUE

Функция EXTRACTVALUE(XML_fragment, XPath_expression) в MySQL предназначена для извлечения значения из XML-строки по заданному XPath-выражению. Однако при передаче некорректного XPath-выражения она генерирует ошибку, которая может содержать переданные данные. Именно это свойство и эксплуатируют злоумышленники: они заставляют базу вывести результат подзапроса в тексте ошибки.

CONCAT и 0x7e

CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильды используются как маркеры, чтобы облегчить поиск выведенных данных в сообщении об ошибке. В нашем случае конкатенация выглядит так: CONCAT(0x7e, ((SELECT ...)), 0x7e) — то есть результат подзапроса обрамляется тильдами.

ELT и условие 7899=7899

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

Комментарий -- -

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

Как работает error-based инъекция

Предположим, на сервере выполняется запрос:

SELECT * FROM users WHERE id = '$input';

Злоумышленник передаёт в $input нашу строку. После подстановки запрос принимает вид:

SELECT * FROM users WHERE id = '%")) AND EXTRACTVALUE(7899,CONCAT(0x7e,((SELECT (ELT(7899=7899,1)))),0x7e))-- -';

База данных пытается выполнить EXTRACTVALUE с аргументом CONCAT(0x7e, '1', 0x7e), что даёт строку ~1~. Но EXTRACTVALUE ожидает XML-фрагмент, а получает просто текст. Возникает ошибка вида:

XPATH syntax error: '~1~'

Эта ошибка возвращается пользователю (если включён вывод ошибок), и злоумышленник видит результат выполнения подзапроса. Меняя подзапрос, можно извлекать произвольные данные: версию MySQL, имена таблиц, логины и пароли пользователей.

Цели и опасность атаки

Error-based SQL-инъекции позволяют:

  • Получить информацию о структуре базы данных (имена таблиц и колонок).
  • Извлечь конфиденциальные данные: учётные записи, хеши паролей, персональные сведения.
  • В некоторых случаях — выполнить произвольные SQL-команды, вплоть до удаления данных.

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

Примеры других инъекций

Помимо EXTRACTVALUE, существуют и другие техники error-based инъекций, например, с использованием функций UPDATEXML или GTID_SUBSET. Также распространены UNION-инъекции, когда злоумышленник добавляет UNION SELECT для объединения результатов. Например:

' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users #

Здесь атакующий пытается вывести логины и пароли в одном столбце. Однако такие запросы требуют совпадения количества колонок в оригинальном и внедряемом запросе, что не всегда просто.

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

Основные меры защиты:

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

Важно понимать, что даже простая строка с EXTRACTVALUE может быть частью масштабной атаки. Поэтому необходимо регулярно проверять логи на наличие подобных конструкций и своевременно реагировать.

Заключение

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

Источники