Что это за строка и откуда она берётся
В логах веб-сервера, в поле ввода формы или в параметрах URL можно встретить загадочную последовательность символов: %')))) AND EXTRACTVALUE(7326,CONCAT(0x7e,((SELECT (ELT(7326=7326,1)))),0x7e))-- -. Для неподготовленного пользователя это выглядит как случайный набор знаков, но на самом деле перед нами классический пример SQL-инъекции — попытки злоумышленника внедрить вредоносный код в SQL-запрос, который выполняется на сервере базы данных.
Подобные строки часто появляются в логах систем веб-аналитики, WAF (Web Application Firewall) или просто в журналах доступа. Они свидетельствуют о том, что сайт пытались просканировать на уязвимости. Важно понимать: сам по себе факт наличия такой строки в логах не означает, что взлом удался, но он показывает, что кто-то целенаправленно искал дыры в защите.
В данном запросе используется функция EXTRACTVALUE — одна из функций MySQL для работы с XML. Она извлекает значение из XML-строки по заданному XPath-выражению. Злоумышленники применяют её для того, чтобы вызвать ошибку, в тексте которой утечёт нужная информация. Это так называемая error-based SQL-инъекция.
Разбор по частям: что делает каждый элемент
Давайте разберём строку на составляющие, чтобы понять логику атаки.
- %')))) — это начало полезной нагрузки. Символ
%— URL-кодировка, а'))))— закрывающие скобки и кавычки, которые должны «закрыть» предыдущие части оригинального SQL-запроса, чтобы внедрить свой код. Количество скобок подбирается методом проб и ошибок в зависимости от структуры уязвимого запроса. - AND EXTRACTVALUE(7326,CONCAT(0x7e,((SELECT (ELT(7326=7326,1)))),0x7e)) — сердце инъекции. Функция EXTRACTVALUE принимает два аргумента: XML-документ и XPath-выражение. В качестве первого аргумента передаётся число 7326 (произвольное), а второй аргумент — результат CONCAT. CONCAT объединяет символ
0x7e(тильда ~) с результатом подзапросаSELECT (ELT(7326=7326,1))и ещё одной тильдой. - ELT(7326=7326,1) — функция ELT возвращает N-й элемент из списка. Здесь условие
7326=7326всегда истинно (1), поэтому ELT возвращает 1. Это тестовый запрос, проверяющий, выполняется ли инъекция. В реальной атаке вместо этого подзапроса стоял бы запрос к системным таблицам, например,SELECT GROUP_CONCAT(table_name) FROM information_schema.tables. - -- - — комментарий в SQL. Всё, что идёт после этих символов, игнорируется базой данных. Это нужно, чтобы «отрезать» остаток оригинального запроса и не вызвать синтаксическую ошибку.
Таким образом, злоумышленник заставляет сервер выполнить функцию EXTRACTVALUE с заведомо некорректным XPath-выражением (тильда не является допустимым синтаксисом XPath). MySQL генерирует ошибку, в тексте которой содержится результат подзапроса. Если сайт выводит ошибки базы данных на экран, атакующий увидит нужные данные.
Почему EXTRACTVALUE используется для атак
Функция EXTRACTVALUE появилась в MySQL 5.1 и предназначалась для работы с XML. Однако она стала популярным инструментом в арсенале пентестеров и злоумышленников по нескольким причинам:
- Вызов ошибки с данными. Если передать в XPath-выражение некорректную строку, MySQL выдаст ошибку вида
XPATH syntax error: '~результат~'. В эту ошибку можно «завернуть» вывод подзапроса. - Обход фильтров. Многие системы защиты ищут классические конструкции вроде
UNION SELECT, но пропускают вызовы EXTRACTVALUE. - Ограничение длины. Максимальная длина результата EXTRACTVALUE — 32 символа. Для извлечения длинных строк приходится использовать SUBSTR или LIMIT, что усложняет атаку, но не делает её невозможной.
Стоит отметить, что в более новых версиях MySQL (начиная с 5.7) функция EXTRACTVALUE была объявлена устаревшей, а в MySQL 8.0 удалена. Однако множество сайтов до сих пор работают на старых версиях, поэтому угроза сохраняется.
Как злоумышленник использует такую инъекцию
Рассмотрим типичный сценарий атаки. Предположим, на сайте есть страница product.php?id=1, где параметр id подставляется в SQL-запрос без должной очистки. Злоумышленник может отправить запрос:
product.php?id=1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -
Если сайт уязвим, в ответе появится ошибка с названием текущей базы данных. Далее атакующий может извлекать имена таблиц, столбцов, логины и пароли пользователей, хеши паролей и другую конфиденциальную информацию.
В нашем примере с ELT(7326=7326,1) — это, скорее всего, пробный запрос, чтобы проверить, работает ли инъекция. Если ошибка появляется, значит, уязвимость есть, и можно переходить к более серьёзным действиям.
Как защититься от SQL-инъекций через EXTRACTVALUE
Основной способ защиты — использовать параметризованные запросы (prepared statements). В этом случае данные пользователя передаются отдельно от SQL-кода и не могут изменить структуру запроса. Это золотой стандарт безопасности.
Дополнительные меры:
- Экранирование специальных символов. Если параметризация невозможна, используйте функции экранирования, предоставляемые драйвером базы данных (например,
mysqli_real_escape_stringв PHP). - Валидация входных данных. Проверяйте, что параметр
idявляется числом, а не строкой с произвольным содержимым. - Отключение вывода ошибок БД. Настройте сервер так, чтобы ошибки базы данных не показывались пользователю, а записывались в лог. Это не устранит уязвимость, но затруднит эксплуатацию.
- Использование WAF. Современные веб-приложения-фаерволы умеют распознавать попытки SQL-инъекций, включая конструкции с EXTRACTVALUE, и блокировать их.
- Обновление MySQL. В версиях 8.0 и выше EXTRACTVALUE отсутствует, что автоматически закрывает этот вектор атаки.
Если вы администратор сайта и видите в логах подобные строки, рекомендуется провести аудит кода на предмет уязвимостей, проверить, не произошла ли утечка данных, и убедиться, что все запросы к базе данных используют параметризацию.
Что делать, если вы нашли такую строку в логах
Прежде всего, не паникуйте. Наличие попытки инъекции не означает, что она успешна. Однако стоит предпринять следующие шаги:
- Проверьте, не отображаются ли на сайте ошибки базы данных. Если да — срочно отключите их вывод.
- Проведите сканирование сайта на известные уязвимости (например, с помощью OWASP ZAP или SQLMap в тестовом режиме).
- Просмотрите логи доступа на предмет других подозрительных запросов с этого IP-адреса.
- Убедитесь, что все формы и параметры URL обрабатываются безопасно.
- Если есть подозрения на утечку, смените пароли администраторов и пользователей, проверьте целостность файлов.
Помните, что безопасность — это процесс, а не разовое действие. Регулярные обновления, аудиты и обучение разработчиков помогают снизить риски.
Заключение
Строка %')))) AND EXTRACTVALUE(7326,CONCAT(0x7e,((SELECT (ELT(7326=7326,1)))),0x7e))-- - — это не случайный мусор, а осмысленный код SQL-инъекции, нацеленный на извлечение данных через ошибку. Подобные атаки остаются актуальными для сайтов на старых версиях MySQL и с недостаточной фильтрацией ввода. Защита от них строится на параметризованных запросах, валидации данных и своевременном обновлении программного обеспечения. Если вы встретили такую строку в логах — это повод проверить безопасность вашего веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий