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

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

Разбор компонентов инъекции

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

1. Закрывающая кавычка и скобка: ')

Строка начинается с '). Это попытка закрыть ранее открытую кавычку и скобку в оригинальном SQL-запросе. Например, если уязвимый запрос выглядит как SELECT * FROM users WHERE id = ('$input'), то подстановка ') завершает условие и позволяет добавить произвольный SQL-код.

2. Оператор AND

Логический оператор AND используется для соединения с оригинальным условием. Если оригинальное условие истинно, то и всё выражение останется истинным, что позволяет внедрённой части выполниться.

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

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

4. Аргументы EXTRACTVALUE(8535, CONCAT(...))

Первый аргумент — число 8535. Это произвольное число, которое не несёт смысловой нагрузки, но служит для уникальности или обхода фильтров. Второй аргумент — результат функции CONCAT.

5. Функция CONCAT(0x7e, ..., 0x7e)

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

6. Подзапрос (SELECT (ELT(8535=8535,1)))

Внутри CONCAT находится подзапрос, который выполняет функцию ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь ELT(8535=8535, 1): выражение 8535=8535 истинно и возвращает 1 (в MySQL TRUE равно 1). Таким образом, ELT(1, 1) вернёт первую строку из списка, то есть 1. Фактически подзапрос возвращает число 1. Это простейший случай, демонстрирующий технику. В реальных атаках вместо 1 мог бы быть, например, SELECT password FROM users LIMIT 1.

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

Два дефиса и пробел (или дефис) обозначают начало комментария в SQL. Всё, что идёт после, игнорируется. Это позволяет отбросить остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку. Вариант -- - часто используется, чтобы гарантировать, что комментарий не будет случайно съеден при передаче (пробел после дефисов обязателен в некоторых СУБД).

Как это работает в целом?

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

SELECT * FROM products WHERE category = ('') AND EXTRACTVALUE(8535,CONCAT(0x7e,((SELECT (ELT(8535=8535,1)))),0x7e))-- -')

MySQL выполнит:

  1. Закроет кавычку и скобку, сделав условие category = '' (ложным, но это неважно, так как далее идёт AND).
  2. Вычислит EXTRACTVALUE. Второй аргумент будет строкой ~1~, потому что CONCAT соединит тильду, результат подзапроса (1) и ещё одну тильду.
  3. Функция EXTRACTVALUE попытается интерпретировать ~1~ как XML. Это невалидный XML, поэтому возникнет ошибка: XPATH syntax error: '~1~'.
  4. Сообщение об ошибке будет возвращено приложению (если вывод ошибок включён), и злоумышленник увидит ~1~, то есть извлечёт данные.

В более сложных случаях вместо 1 можно поместить подзапрос, возвращающий конфиденциальные данные, например, версию СУБД, имя базы данных, логины и пароли пользователей.

Зачем это нужно злоумышленнику?

Error-based SQL-инъекция — один из методов извлечения информации из базы данных, когда прямой вывод данных (например, через UNION) невозможен. Он использует ошибки СУБД как канал утечки. Основные цели:

  • Получение версии MySQL и другой служебной информации.
  • Извлечение имён таблиц и колонок из information_schema.
  • Чтение содержимого таблиц (логины, пароли, персональные данные).
  • Иногда — выполнение произвольных команд, если привилегии позволяют.

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

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

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

Важно понимать, что даже если приложение не выводит ошибки, злоумышленник может использовать слепые методы (boolean-based, time-based), но error-based проще в эксплуатации при наличии вывода ошибок.

Заключение

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

Источники