Введение

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

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

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

Существует несколько типов SQL-инъекций: union-based, error-based, blind (boolean и time-based). Рассматриваемый запрос относится к error-based, так как использует функцию, вызывающую ошибку с внедрёнными данными.

Разбор строки EXTRACTVALUE

Строка " ) AND EXTRACTVALUE(8376,CONCAT(0x7e,((SELECT (ELT(8376=8376,1)))),0x7e))-- - состоит из нескольких частей:

  • " ) — попытка закрыть ранее открытую скобку и кавычку в уязвимом запросе.
  • AND EXTRACTVALUE(...) — вызов функции EXTRACTVALUE(XML_document, XPath_expression), которая извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение содержит недопустимые символы, MySQL генерирует ошибку с текстом, включающим это выражение.
  • CONCAT(0x7e, ..., 0x7e) — конкатенация символа ~ (0x7e) с подзапросом и ещё одним ~. Это делается для того, чтобы отделить выводимые данные в сообщении об ошибке.
  • (SELECT (ELT(8376=8376,1))) — подзапрос, который возвращает результат функции ELT(N, str1, str2, ...). ELT возвращает N-ю строку из списка. Здесь 8376=8376 — всегда истинное условие (1), поэтому ELT(1, 1) вернёт 1. В реальной атаке вместо этого подзапроса мог бы быть запрос к системным таблицам, например, SELECT version() или SELECT table_name FROM information_schema.tables.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы не возникло синтаксической ошибки.

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

Как работает error-based SQL-инъекция через EXTRACTVALUE

Функция EXTRACTVALUE появилась в MySQL 5.1.5 и предназначена для работы с XML. Она принимает два аргумента: фрагмент XML и выражение XPath. Если XPath-выражение синтаксически неверно, MySQL возвращает ошибку вида:

XPATH syntax error: '~результат~'

Злоумышленник пользуется этим, чтобы поместить в XPath результат подзапроса. Поскольку символ ~ недопустим в XPath, база данных выдаёт ошибку, в тексте которой содержится внедрённая строка. Так происходит утечка данных.

Аналогично работают функции UPDATEXML и GTID_SUBSET. Все они относятся к классу error-based инъекций.

Цель запроса

Цель данного конкретного запроса — проверить, уязвимо ли приложение к SQL-инъекции. Если сервер возвращает ошибку с символом ~1~, значит, инъекция возможна. Далее атакующий может заменить подзапрос на извлечение имён таблиц, столбцов, логинов и паролей пользователей.

Важно понимать, что даже если база данных не выводит ошибки на экран, они могут попадать в логи. Поэтому анализ логов — важная часть обнаружения атак.

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

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

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

  • Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (но это менее надёжно, чем prepared statements).
  • Ограничение прав пользователя базы данных: приложению не нужны права на удаление таблиц или доступ к системным схемам.
  • Валидация и фильтрация входных данных на стороне сервера.
  • Использование ORM или query builder, которые автоматически параметризуют запросы.
  • Регулярный аудит кода и сканирование уязвимостей.
  • Настройка WAF (Web Application Firewall) для блокировки подозрительных запросов.

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

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

  1. Проверьте, не увенчалась ли атака успехом: поищите необычные запросы к базе, изменения в данных.
  2. Убедитесь, что все запросы к БД используют параметризацию.
  3. Обновите CMS и библиотеки до последних версий.
  4. Просмотрите логи на предмет других попыток инъекций (UNION, SELECT, EXTRACTVALUE, UPDATEXML).
  5. При необходимости обратитесь к специалистам по информационной безопасности.

Заключение

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

Источники