В логах веб-сервера или в поле ввода часто можно встретить загадочную последовательность символов: )))) 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) для блокировки подозрительных запросов.
- Регулярное обновление СУБД и фреймворков.
Что делать, если вы нашли такую строку в логах?
Если вы обнаружили подобную инъекцию в логах, это может означать, что ваш сайт пытались взломать. Не паникуйте, но проверьте:
- Уязвим ли ваш код? Проведите аудит всех мест, где пользовательский ввод попадает в SQL-запросы.
- Используются ли параметризованные запросы? Если нет — срочно перепишите уязвимые участки.
- Настроен ли вывод ошибок? Убедитесь, что детали ошибок не показываются пользователям.
- Обновите WAF-правила, если используете файрвол.
Помните: даже если атака не удалась, она указывает на потенциальную уязвимость, которую нужно закрыть.
Заключение
Строка )))) AND EXTRACTVALUE(6263,CONCAT(0x7e,((SELECT (ELT(6263=6263,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, использующей функции MySQL EXTRACTVALUE, CONCAT и ELT. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои приложения. Главный вывод: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий