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

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

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

Существует несколько разновидностей SQL-инъекций: UNION-based, blind, error-based, time-based и другие. Строка, которую мы рассматриваем, относится к классу error-based SQL injection — инъекции, основанной на ошибках.

Разбор строки инъекции

Давайте разберём её по частям.

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

В начале строки идут четыре закрывающие круглые скобки. Это не случайность: часто в уязвимый SQL-запрос уже встроены открывающие скобки (например, в конструкциях WHERE id IN (…) или AND (…)). Злоумышленник добавляет закрывающие скобки, чтобы «закрыть» исходные конструкции и затем вставить свой код. Количество скобок подбирается экспериментально или автоматически инструментами вроде sqlmap.

2. AND EXTRACTVALUE(6263,CONCAT(0x7e,((SELECT (ELT(6263=6263,1)))),0x7e))

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

Первый аргумент — 6263 — это произвольное число, которое не несёт смысловой нагрузки, но часто используется как идентификатор в автоматизированных атаках (например, sqlmap подставляет случайные числа).

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

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

Функция ELT(N, str1, str2, …) возвращает N-ю строку из списка. В данном случае 6263=6263 — это логическое выражение, которое всегда истинно (1). Поэтому ELT(1, 1) вернёт 1. Это простейший пример, демонстрирующий работу инъекции. В реальной атаке вместо 1 могло бы быть, например, version(), database() или подзапрос, извлекающий имена таблиц и пароли.

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

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

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

Механизм прост: злоумышленник заставляет базу данных выполнить выражение, результат которого попадает в текст ошибки. Если приложение выводит ошибки СУБД пользователю (или если они попадают в логи), атакующий может прочитать этот результат. В нашем случае EXTRACTVALUE с некорректным XPath (например, ~1~ не является валидным XPath) вызовет ошибку вида:

XPATH syntax error: '~1~'

Таким образом, в сообщении об ошибке появится значение, возвращённое вложенным запросом. Это позволяет посимвольно извлекать данные из базы.

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

  • Получение версии СУБД, имени базы данных, текущего пользователя.
  • Извлечение имён таблиц и столбцов из information_schema.
  • Чтение конфиденциальных данных: логинов, паролей, персональной информации.
  • В некоторых случаях — модификация или удаление данных.

Автоматизированные инструменты, такие как sqlmap, генерируют подобные строки автоматически, подставляя случайные числа и адаптируя синтаксис под конкретную СУБД.

Как защититься от SQL-инъекций?

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

Дополнительные меры:

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

Что делать, если вы нашли такую строку в логах?

Если вы обнаружили подобную инъекцию в логах, это может означать, что ваш сайт пытались взломать. Не паникуйте, но проверьте:

  1. Уязвим ли ваш код? Проведите аудит всех мест, где пользовательский ввод попадает в SQL-запросы.
  2. Используются ли параметризованные запросы? Если нет — срочно перепишите уязвимые участки.
  3. Настроен ли вывод ошибок? Убедитесь, что детали ошибок не показываются пользователям.
  4. Обновите WAF-правила, если используете файрвол.

Помните: даже если атака не удалась, она указывает на потенциальную уязвимость, которую нужно закрыть.

Заключение

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

Источники