Что такое SQL-инъекция и при чём тут EXTRACTVALUE

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

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

Разбор конкретного payload

Рассмотрим запрос из примера:

')) AND EXTRACTVALUE(3139,CONCAT(0x7e,((SELECT (ELT(3139=3139,1)))),0x7e))-- -

Этот payload состоит из нескольких частей, каждая из которых выполняет свою роль.

1. Закрывающие символы '))

Два символа ) и одинарная кавычка ' используются для «выхода» из оригинального SQL-запроса. Разработчик мог написать что-то вроде SELECT * FROM articles WHERE id = ('$input'). Злоумышленник подставляет ')), чтобы закрыть строку и скобки, а затем добавить свою логику через AND.

2. Оператор AND

Оператор AND позволяет присоединить дополнительное условие к исходному запросу. Если исходный запрос возвращает true, то добавленное условие с EXTRACTVALUE выполнится. Это классический приём для внедрения вызова функции.

3. Функция EXTRACTVALUE(3139, ...)

Первый аргумент — произвольное число (3139). Второй аргумент — XPath-выражение, которое формируется с помощью CONCAT. EXTRACTVALUE возвращает текст из XML, но если XPath некорректен, возникает ошибка с сообщением, содержащим переданное выражение. Именно это и эксплуатируется.

4. CONCAT(0x7e, ... ,0x7e)

0x7e — шестнадцатеричный код символа ~ (тильда). Он используется как маркер, чтобы облегчить поиск извлечённых данных в тексте ошибки. CONCAT объединяет тильду, результат вложенного запроса и ещё одну тильду. В итоге в сообщении об ошибке появится что-то вроде ~1~, если вложенный запрос вернул 1.

5. Вложенный запрос (SELECT (ELT(3139=3139,1)))

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

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

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

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

Когда MySQL выполняет EXTRACTVALUE с некорректным XPath (а CONCAT создаёт строку, которая не является валидным XPath), генерируется ошибка вида:

XPATH syntax error: '~1~'

Если приложение выводит сообщения об ошибках базы данных на страницу, атакующий видит этот текст и может подставлять другие подзапросы, чтобы извлекать произвольные данные. Например, заменив ELT(3139=3139,1) на (SELECT password FROM users LIMIT 1), он получит пароль в сообщении об ошибке.

Последствия успешной атаки

  • Утечка конфиденциальных данных (пароли, персональные данные, номера кредитных карт).
  • Обход аутентификации и авторизации.
  • Модификация или удаление информации в базе.
  • Полный контроль над сервером в некоторых случаях.

Как защититься от подобных инъекций

Основной метод — использование параметризованных запросов (prepared statements). В этом случае пользовательский ввод передаётся отдельно от SQL-кода и не может изменить структуру запроса. Дополнительные меры:

  • Экранирование специальных символов (хотя это не всегда надёжно).
  • Валидация и фильтрация входных данных (например, ожидание только цифр для числовых полей).
  • Ограничение прав пользователя базы данных (принцип наименьших привилегий).
  • Отключение вывода подробных сообщений об ошибках в production-окружении.
  • Регулярное обновление СУБД и фреймворков.

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

Заключение

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

Источники