Что это за строка?

Строка ')) AND EXTRACTVALUE(8704,CONCAT(0x7e,((SELECT (ELT(8704=8704,1)))),0x7e))-- - — это классический пример SQL-инъекции (SQL injection), нацеленной на базу данных MySQL. Подобные конструкции часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL. Их основная цель — проверить, уязвимо ли приложение перед внедрением вредоносного SQL-кода, и при возможности извлечь данные из базы.

В данной статье мы разберём, из чего состоит этот запрос, как работает каждый его элемент и какие меры защиты помогут предотвратить подобные атаки.

Расшифровка компонентов инъекции

Рассмотрим каждый элемент по порядку.

1. ')) — закрытие исходного выражения

Два символа ) и одинарная кавычка ' используются для того, чтобы «закрыть» ранее открытые скобки и строковый литерал в оригинальном SQL-запросе. Злоумышленник предполагает, что приложение подставляет пользовательский ввод внутрь запроса, например: SELECT * FROM users WHERE name = ('$input'). Вставив ')), атакующий пытается завершить оригинальное выражение и добавить своё условие.

2. AND EXTRACTVALUE(...) — вызов функции

EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа. Однако в контексте SQL-инъекций она используется иначе: при передаче некорректного XPath-выражения функция генерирует ошибку, в текст которой попадает результат вычисления переданного аргумента. Это позволяет злоумышленнику «прочитать» данные из базы через сообщения об ошибках (техника error-based SQL injection).

Первый аргумент — 8704 — это просто число, которое будет использовано как XML-документ (фактически не является корректным XML, что и вызовет ошибку). Второй аргумент — CONCAT(...) — формирует строку, которая попадёт в сообщение об ошибке.

3. CONCAT(0x7e, ..., 0x7e) — обёртка с тильдами

0x7e — это шестнадцатеричное представление символа ~ (тильда). Функция CONCAT объединяет строки. Тильды добавляются по краям, чтобы в сообщении об ошибке было легко найти внедрённые данные: они будут окружены символами ~. Это упрощает автоматический парсинг ответа сервера.

4. (SELECT (ELT(8704=8704,1))) — подзапрос с ELT

ELT(N, str1, str2, ...) — функция MySQL, которая возвращает N-ю строку из списка. В данном случае ELT(8704=8704, 1) возвращает 1, если условие 8704=8704 истинно (а оно всегда истинно). Фактически это тестовый запрос: он проверяет, что инъекция выполняется и функция ELT доступна. Если ошибка возникает, значит, приложение уязвимо. В реальной атаке вместо 8704=8704 могло бы быть условие, проверяющее, например, первый символ имени пользователя, и тогда возвращаемое значение зависело бы от данных.

5. -- - — комментарий

Два дефиса и пробел (или дефис) обозначают начало комментария в SQL. Всё, что идёт после, игнорируется базой данных. Это нужно, чтобы «отрезать» оставшуюся часть оригинального запроса, которая могла бы вызвать синтаксическую ошибку.

Как работает атака целиком

Когда уязвимое приложение подставляет эту строку в SQL-запрос, итоговый запрос может выглядеть примерно так:

SELECT * FROM products WHERE id = ('1')) AND EXTRACTVALUE(8704,CONCAT(0x7e,((SELECT (ELT(8704=8704,1)))),0x7e))-- -')

База данных выполняет следующее:

  1. Закрывает исходное выражение и добавляет условие AND EXTRACTVALUE(...).
  2. Вычисляет ELT(8704=8704,1) → получает 1.
  3. Формирует строку ~1~ (тильда, единица, тильда).
  4. Вызывает EXTRACTVALUE(8704, '~1~'), что приводит к ошибке вида: XPATH syntax error: '~1~'.
  5. Приложение, если оно выводит ошибки базы данных пользователю, показывает этот текст. Злоумышленник видит, что инъекция сработала, и может заменить ELT(8704=8704,1) на подзапрос, извлекающий реальные данные (например, SELECT password FROM users LIMIT 1).

Таким образом, данная строка — это разведочный тест, а не финальная атака. Её задача — убедиться в наличии уязвимости и в возможности использовать error-based технику.

Почему это опасно?

SQL-инъекции остаются одной из самых распространённых угроз веб-приложений (входят в топ OWASP). Успешная эксплуатация позволяет злоумышленнику:

  • читать произвольные данные из базы (учётные записи, персональные данные, платёжную информацию);
  • модифицировать или удалять данные;
  • обходить аутентификацию и получать доступ к административным функциям;
  • в некоторых случаях — выполнять команды на сервере.

Конструкции с EXTRACTVALUE особенно удобны для атакующих, потому что не требуют вывода данных в ответе приложения — достаточно лишь сообщения об ошибке. Даже если приложение не показывает ошибки, злоумышленник может использовать слепые (blind) методы, но это уже сложнее.

Как защититься

Основные меры противодействия SQL-инъекциям хорошо известны:

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

Также рекомендуется проводить регулярные аудиты кода и сканирования уязвимостей.

Заключение

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

Источники