Введение

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

Что такое SQL-инъекция?

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

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

Разбор payload: EXTRACTVALUE и CONCAT

Рассматриваемая строка %")) AND EXTRACTVALUE(8457,CONCAT(0x7e,((SELECT (ELT(8457=8457,1)))),0x7e))-- - представляет собой попытку эксплуатации уязвимости с использованием функций MySQL: EXTRACTVALUE, CONCAT и ELT.

Функция EXTRACTVALUE

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

Функция CONCAT

CONCAT(str1, str2, ...) объединяет строки. В payload она собирает строку из трёх частей: символа ~ (0x7e), результата подзапроса и снова ~. Это нужно, чтобы отделить выводимые данные от служебного текста ошибки и облегчить их извлечение.

Функция ELT

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

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

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

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

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

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

Если злоумышленник передаст в $input строку %")) AND EXTRACTVALUE(8457,CONCAT(0x7e,((SELECT (ELT(8457=8457,1)))),0x7e))-- -, то итоговый запрос станет таким:

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

Часть %")) закрывает предыдущие конструкции и добавляет условие AND. Затем вызывается EXTRACTVALUE с заведомо некорректным XPath (второй аргумент — строка, начинающаяся с ~, что не является валидным XPath). MySQL сгенерирует ошибку, в тексте которой будет присутствовать результат CONCAT, то есть ~1~. Атакующий, видя эту ошибку в ответе сервера, понимает, что инъекция сработала, и может заменить ELT(8457=8457,1) на любой другой подзапрос, например, для извлечения имён таблиц или паролей пользователей.

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

Основная цель такой инъекции — получить информацию из базы данных. С помощью EXTRACTVALUE можно извлекать:

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

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

Защита от SQL-инъекций

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

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

Заключение

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

Источники