Что это за строка с EXTRACTVALUE?
Если вы увидели в логах веб-сервера или в параметрах URL строку вида %")))) AND EXTRACTVALUE(8067,CONCAT(0x7e,((SELECT (ELT(8067=8067,1)))),0x7e))-- -, знайте: перед вами классический пример error-based SQL-инъекции. Это попытка злоумышленника заставить базу данных вернуть сообщение об ошибке, содержащее полезную для атакующего информацию. Подобные конструкции часто встречаются в автоматизированных сканерах уязвимостей, которые проверяют сайты на наличие дыр в защите.
В данной статье мы подробно разберём, из чего состоит этот запрос, как он работает, какие цели преследует и, главное, как защитить свой сайт от подобных атак.
Разбор конструкции по частям
Начнём с начала строки. Символы %")))) — это попытка закрыть ранее открытые кавычки и скобки в уязвимом SQL-запросе. Проценты и кавычки часто используются для обхода простых фильтров. Далее идёт ключевое слово AND, которое добавляет условие к исходному запросу.
Основная часть — функция EXTRACTVALUE(8067,CONCAT(0x7e,((SELECT (ELT(8067=8067,1)))),0x7e)). EXTRACTVALUE — это функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа по XPath-выражению. Она принимает два аргумента: XMLType-экземпляр и XPath-выражение. Если XPath-выражение некорректно или возвращает недопустимый результат, функция генерирует ошибку, в тексте которой может отображаться переданное значение.
Второй аргумент — CONCAT(0x7e,((SELECT (ELT(8067=8067,1)))),0x7e). CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа тильды (~). Он используется как маркер, чтобы в сообщении об ошибке легко было найти внедрённые данные. SELECT (ELT(8067=8067,1)) — это подзапрос, который возвращает результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 8067=8067 — всегда истинное выражение, которое в числовом контексте даёт 1, поэтому ELT(1, 1) вернёт строку '1'.
Завершают конструкцию символы -- - — это комментарий в SQL, который отсекает оставшуюся часть исходного запроса, чтобы не возникло синтаксической ошибки.
Как работает error-based инъекция
Цель атакующего — заставить базу данных выдать сообщение об ошибке, содержащее результат выполнения подзапроса. В данном примере подзапрос возвращает всего лишь '1', но это демонстрация уязвимости. В реальной атаке вместо ELT(8067=8067,1) может стоять, например, SELECT version() или SELECT password FROM users LIMIT 1. Тогда в тексте ошибки EXTRACTVALUE появится версия СУБД или хеш пароля.
Механизм таков: MySQL пытается выполнить XPath-запрос, который содержит символ тильды и внедрённые данные. Поскольку такой XPath синтаксически неверен, СУБД возвращает ошибку вида XPATH syntax error: '~5.7.33~'. Атакующий читает эту ошибку и получает нужную информацию.
Error-based SQL-инъекции — один из самых быстрых способов извлечения данных, так как не требуют слепого перебора. Достаточно одной уязвимости, чтобы выкачать всю базу.
Почему это опасно?
Успешная эксплуатация error-based инъекции открывает злоумышленнику доступ к содержимому базы данных. В зависимости от привилегий пользователя, от имени которого работает веб-приложение, он может:
- получить список таблиц и колонок;
- извлечь логины, пароли, персональные данные пользователей;
- изменить или удалить информацию;
- в некоторых случаях выполнить произвольные команды на сервере.
Особенно опасны такие атаки для сайтов, где ввод пользователя попадает в SQL-запрос без должной обработки. Часто это формы авторизации, поиска, фильтры товаров.
Как защититься от SQL-инъекций
Главное правило — никогда не доверять пользовательскому вводу. Все данные, приходящие от клиента, должны проходить валидацию и экранирование. Вот основные меры защиты:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ. Параметры передаются отдельно от SQL-кода, и СУБД не интерпретирует их как часть запроса.
- Применение ORM. Современные фреймворки (Django, Laravel, Hibernate) автоматически используют параметризацию, если разработчик не пишет сырые запросы вручную.
- Экранирование специальных символов. Если по каким-то причинам нельзя использовать подготовленные выражения, нужно применять функции экранирования, например
mysqli_real_escape_stringв PHP. - Ограничение привилегий пользователя БД. Веб-приложение должно работать от имени пользователя с минимально необходимыми правами. Не давайте ему доступ к системным таблицам и возможность выполнять
DROPилиFILE. - Регулярное обновление СУБД и фреймворков. Иногда уязвимости возникают из-за ошибок в самом ПО.
- Использование WAF (Web Application Firewall). Специализированные решения могут блокировать подозрительные запросы, содержащие характерные сигнатуры SQL-инъекций.
Также рекомендуется вести логирование всех запросов к базе данных и анализировать их на предмет аномалий. Если вы обнаружили в логах строку, подобную описанной, это повод немедленно проверить код приложения на наличие уязвимостей.
Что делать, если вы нашли такой запрос в логах?
Прежде всего, не паникуйте. Возможно, это просто сканер, который не смог ничего навредить. Но игнорировать нельзя. Проверьте:
- не было ли успешных попыток инъекции с других IP;
- есть ли в приложении места, где пользовательский ввод попадает в SQL без параметризации;
- не скомпрометированы ли учётные записи пользователей.
Если вы не уверены в безопасности своего кода, лучше обратиться к специалистам по информационной безопасности и провести аудит.
Заключение
Строка %")))) AND EXTRACTVALUE(8067,CONCAT(0x7e,((SELECT (ELT(8067=8067,1)))),0x7e))-- - — это не случайный набор символов, а целенаправленная попытка проэксплуатировать уязвимость SQL-инъекции. Понимание того, как работают такие атаки, помогает разработчикам писать более безопасный код, а администраторам — своевременно реагировать на инциденты. Помните: лучшая защита — это параметризованные запросы и внимательное отношение к безопасности на всех этапах разработки.
Комментарии
—Войдите, чтобы оставить комментарий