Введение в error-based SQL-инъекции

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

В этой статье мы детально разберём конкретный пейлоад:

') OR EXTRACTVALUE(6180,CONCAT(0x7e,((SELECT (ELT(6180=6180,1)))),0x7e))-- -

Вы увидите, как он устроен, какие функции задействованы и почему он может быть опасен для веб-приложения.

Что такое EXTRACTVALUE и XPATH-инъекция

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

EXTRACTVALUE(xml_frag, xpath_expr)

Она возвращает текст узла, соответствующего XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, которая включает в себя часть переданного выражения. Это позволяет атакующему внедрить в XPath произвольные данные и заставить СУБД вывести их в сообщении об ошибке.

Такой метод называется XPATH-инъекцией или error-based SQL-инъекцией через EXTRACTVALUE. Он был описан в различных исследовательских работах по пентесту.

Разбор пейлоада по частям

Рассмотрим пейлоад последовательно:

  1. ') — закрывает ранее открытую скобку и строковый литерал в уязвимом запросе. Это необходимо, чтобы внедрить собственный SQL-код.
  2. OR — логический оператор, который делает условие всегда истинным (если правая часть вернёт истину).
  3. EXTRACTVALUE(6180, CONCAT(0x7e, ((SELECT (ELT(6180=6180,1)))), 0x7e)) — вызов функции EXTRACTVALUE с двумя аргументами:
    • Первый аргумент — число 6180 (может быть любым, часто используется случайное число для уникальности ошибки).
    • Второй аргумент — результат CONCAT, который формирует строку, начинающуюся и заканчивающуюся символом тильды (0x7e).
  4. -- - — комментарий, который игнорирует оставшуюся часть оригинального запроса.

Функция CONCAT

CONCAT объединяет строки. В пейлоаде она собирает строку из трёх частей:

  • 0x7e — шестнадцатеричное представление символа ~ (тильда).
  • ((SELECT (ELT(6180=6180,1)))) — подзапрос, возвращающий результат функции ELT.
  • Ещё одна 0x7e — закрывающая тильда.

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

Функция ELT

ELT (Extract List Item) возвращает N-й элемент из списка строк. Синтаксис:

ELT(N, str1, str2, ...)

В нашем случае: ELT(6180=6180, 1). Выражение 6180=6180 всегда истинно, то есть равно 1. Значит, ELT вернёт первый элемент из списка, то есть 1. Это простейший пример, но на практике вместо 1 может быть подзапрос, извлекающий имя базы данных, версию СУБД или хеши паролей.

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

Когда MySQL выполняет EXTRACTVALUE, второй аргумент (XPath) должен быть корректным XPath-выражением. Строка, возвращённая CONCAT, содержит тильды и, возможно, другие символы, которые не являются допустимыми в XPath. Это вызывает ошибку вида:

XPATH syntax error: '~1~'

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

Данный метод часто используется на практике, например, при пентестах, когда другие способы (UNION, blind) недоступны.

Цели и последствия

Успешная эксплуатация такой инъекции позволяет:

  • Получить версию СУБД, имя текущей базы данных, пользователя.
  • Извлечь таблицы, столбцы и сами данные (логины, пароли, персональные данные).
  • В некоторых случаях — выполнить произвольные SQL-запросы, если у пользователя достаточно прав.

Последствия для бизнеса могут быть катастрофическими: утечка конфиденциальной информации, компрометация всей системы, финансовые и репутационные потери.

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

Чтобы предотвратить подобные атаки, необходимо:

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

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

Заключение

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

Помните: безопасность — это процесс, а не одноразовое действие. Постоянное обучение и следование лучшим практикам помогут минимизировать риски.

Источники