Введение

Встретив в логах или в поле ввода строку вида %' OR EXTRACTVALUE(7784,CONCAT(0x7e,((SELECT (ELT(7784=7784,1)))),0x7e))-- -, многие задаются вопросом: что это и чем опасно? Это классический пример error-based SQL-инъекции — атаки на базы данных, при которой злоумышленник заставляет сервер выдать сообщение об ошибке, содержащее полезные данные. В данной статье мы разберём каждый элемент этой конструкции и объясним, почему она считается признаком попытки взлома.

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

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

Существует несколько разновидностей инъекций: union-based, boolean-based, time-based и error-based. Последняя, к которой относится наш пример, основана на анализе текста ошибок, возвращаемых СУБД.

Разбор строки %' OR EXTRACTVALUE(7784,CONCAT(0x7e,((SELECT (ELT(7784=7784,1)))),0x7e))-- -

Рассмотрим каждый компонент подробно.

1. Начальный символ %'

Символ % часто используется в SQL-запросах как часть шаблона для оператора LIKE. Злоумышленник добавляет его, чтобы разорвать существующий запрос и вставить свою логику. Одинарная кавычка ' закрывает строковый литерал, после чего начинается внедряемый код.

2. Оператор OR

OR — логический оператор, который делает условие всегда истинным, если хотя бы одна часть выражения истинна. В контексте инъекции это позволяет обойти аутентификацию или изменить логику выборки данных.

3. Функция EXTRACTVALUE

EXTRACTVALUE(XML_document, XPath_expression) — встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Однако при передаче некорректного XPath она генерирует ошибку, текст которой включает переданное выражение. Именно это свойство и эксплуатируют злоумышленники: они подставляют в XPath результат подзапроса, и СУБД возвращает его в сообщении об ошибке.

4. CONCAT и шестнадцатеричные маркеры 0x7e

CONCAT объединяет строки. Шестнадцатеричное значение 0x7e соответствует символу тильды ~. Тильда используется как разделитель, чтобы облегчить автоматическое извлечение данных из текста ошибки. Конструкция CONCAT(0x7e, (подзапрос), 0x7e) обрамляет результат подзапроса тильдами.

5. Подзапрос (SELECT (ELT(7784=7784,1)))

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Выражение 7784=7784 всегда истинно, что даёт число 1, поэтому ELT(7784=7784,1) возвращает строку '1'. В реальной атаке на месте этой константы стоял бы подзапрос, извлекающий, например, имя пользователя или хеш пароля из системных таблиц. Здесь же приведён упрощённый пример для демонстрации.

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

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

Как это работает на практике

Предположим, на сайте есть форма поиска, и код формирует запрос:

SELECT * FROM products WHERE name LIKE '%пользовательский_ввод%'

Если злоумышленник введёт нашу строку, запрос превратится в:

SELECT * FROM products WHERE name LIKE '%%' OR EXTRACTVALUE(7784,CONCAT(0x7e,((SELECT (ELT(7784=7784,1)))),0x7e))-- -%'

Условие name LIKE '%%' истинно для всех записей, а OR делает всё выражение истинным. Далее выполняется EXTRACTVALUE, которая из-за некорректного XPath вызывает ошибку. MySQL вернёт сообщение вроде:

XPATH syntax error: '~1~'

Таким образом, атакующий видит результат выполнения подзапроса. Меняя подзапрос, он может последовательно извлекать данные из базы.

Чем опасна такая инъекция?

  • Утечка конфиденциальных данных: злоумышленник может получить доступ к логинам, паролям, персональным данным клиентов, коммерческой тайне.
  • Компрометация всей системы: при наличии прав администратора БД возможны чтение и запись файлов, выполнение команд ОС.
  • Репутационные потери: утечка данных ведёт к судебным искам, штрафам и потере доверия пользователей.

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

  1. Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода и не могут изменить его структуру.
  2. Экранируйте специальные символы. Если подготовленные выражения недоступны, применяйте функции экранирования, предоставляемые драйвером БД.
  3. Ограничьте права пользователя БД. Приложению не нужны права на удаление таблиц или доступ к системным схемам.
  4. Отключите вывод подробных ошибок. Настройте сервер так, чтобы ошибки СУБД не показывались пользователю, а логировались во внутренний файл.
  5. Регулярно обновляйте СУБД и фреймворки. Многие уязвимости закрываются в новых версиях.
  6. Используйте WAF (Web Application Firewall). Он может блокировать подозрительные запросы, содержащие характерные сигнатуры вроде EXTRACTVALUE.

Заключение

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

Источники