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

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Одной из разновидностей является error-based SQL-инъекция, когда атакующий извлекает данные через сообщения об ошибках. Функция ExtractValue в MySQL часто используется для таких атак, так как она генерирует ошибку XPATH, содержащую результат подзапроса.

В запросе пользователя: "))) AND EXTRACTVALUE(6853,CONCAT(0x7e,((SELECT (ELT(6853=6853,1)))),0x7e))-- - — представлен классический пример эксплуатации этой уязвимости. Давайте разберём его по частям.

Анатомия эксплойта

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

  • "))) — последовательность символов, которая часто используется для закрытия ранее открытых скобок и кавычек в уязвимом параметре. Это позволяет «вырваться» из контекста оригинального SQL-запроса.
  • AND EXTRACTVALUE(6853, ...) — вызов функции ExtractValue с двумя аргументами. Первый аргумент (6853) — произвольное число, второй — XML-фрагмент, который должен быть корректным. Если XML некорректен, MySQL выдаёт ошибку, содержащую часть переданного XML.
  • CONCAT(0x7e, ((SELECT (ELT(6853=6853,1)))), 0x7e) — конкатенация символа тильды (0x7e), результата подзапроса и ещё одной тильды. Символы тильды используются как маркеры, чтобы облегчить извлечение данных из сообщения об ошибке.
  • SELECT (ELT(6853=6853,1)) — подзапрос, который возвращает 1, если условие 6853=6853 истинно. ELT — функция, возвращающая N-й элемент из списка; здесь она возвращает 1. В реальных атаках вместо этого подзапроса внедряют запросы к системным таблицам для получения имён баз, таблиц, колонок и данных.
  • -- - — комментарий, который обрезает оставшуюся часть оригинального запроса, чтобы избежать синтаксических ошибок.

Таким образом, при выполнении этого запроса MySQL попытается обработать ExtractValue с некорректным XML (содержащим тильды и результат подзапроса) и выдаст ошибку вида: XPATH syntax error: '~1~'. Именно эта ошибка и является каналом утечки данных.

Пример работы в уязвимом приложении

Предположим, что веб-приложение формирует SQL-запрос следующим образом:

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

Если параметр $id не фильтруется, атакующий может передать значение:

1"))) AND EXTRACTVALUE(6853,CONCAT(0x7e,((SELECT (ELT(6853=6853,1)))),0x7e))-- -

Тогда итоговый запрос примет вид:

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

СУБД выполнит его, и в ответе сервера появится сообщение об ошибке XPATH, содержащее результат выполнения подзапроса. В нашем случае это будет ~1~, что подтверждает работоспособность инъекции.

Почему это опасно?

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

Особенно опасна комбинация с функцией ExtractValue, так как она доступна в большинстве версий MySQL и MariaDB. Даже если приложение скрывает ошибки от пользователя, они могут попадать в логи, которые затем анализируются атакующим.

Методы защиты

Чтобы предотвратить эксплуатацию подобных уязвимостей, необходимо:

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

Также рекомендуется регулярно проводить аудит кода и пентесты.

Заключение

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

Источники