Что это за строка и откуда она берётся

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

Подобные конструкции часто встречаются в автоматизированных сканерах уязвимостей (например, sqlmap) и в ручных атаках на сайты, где входные данные не фильтруются. Внешне это выглядит как случайный набор символов, но за ним стоит строгая логика, основанная на особенностях функций MySQL.

Разбор по частям

Чтобы понять, как работает эта инъекция, разберём её на составляющие.

1. Начало: %" AND ...

Символ % и кавычка " часто используются для «разрыва» исходного SQL-запроса. Предположим, приложение формирует запрос вида:

SELECT * FROM users WHERE name = '...'

Если злоумышленник подставляет %" AND ..., то закрывает строковый литерал и добавляет своё условие. Символ % может быть частью LIKE-шаблона или просто «мусором» для обхода простых фильтров. Ключевое слово AND присоединяет дополнительное выражение к исходному WHERE.

2. Функция EXTRACTVALUE(3212, ...)

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

В нашем случае первым аргументом идёт число 3212 — это не XML, но MySQL пытается интерпретировать его как XML-фрагмент и терпит неудачу. Это и нужно атакующему: ошибка станет каналом передачи данных.

3. CONCAT(0x7e, ..., 0x7e)

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

4. SELECT (ELT(3212=3212,1))

Внутренний подзапрос SELECT (ELT(3212=3212,1)) возвращает значение. ELT — функция MySQL, которая возвращает N-й элемент из списка. Синтаксис: ELT(N, str1, str2, ...). Если N=1, возвращается первая строка.

Выражение 3212=3212 всегда истинно, поэтому в MySQL оно преобразуется в 1. Таким образом, ELT(1, 1) вернёт 1. Это простейшая проверка: если инъекция сработала, в ошибке появится ~1~. В реальной атаке вместо 1 подставляются имена таблиц, версии СУБД, хеши паролей и другие данные.

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

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

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

Собрав все части, получаем логику:

  1. Приложение подставляет пользовательский ввод в SQL-запрос без экранирования.
  2. Введённая строка закрывает кавычку и добавляет AND EXTRACTVALUE(...).
  3. MySQL пытается выполнить EXTRACTVALUE с некорректным XML-фрагментом (3212).
  4. Второй аргумент — CONCAT('~', (SELECT ...), '~') — вычисляется, и его результат попадает в текст ошибки.
  5. Сообщение об ошибке возвращается приложением (если включён вывод ошибок), и атакующий видит данные.

Например, MySQL может выдать: XPATH syntax error: '~1~'. Это подтверждает, что инъекция работает.

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

Error-based инъекции — один из самых быстрых способов извлечения информации из базы данных. В отличие от blind-инъекций, где данные угадываются по времени или логическим условиям, здесь результат приходит сразу в виде сообщения об ошибке. Злоумышленник может получить:

  • версию MySQL;
  • имя текущей базы данных;
  • список таблиц и колонок;
  • логины и хеши паролей пользователей;
  • любые другие данные, доступные учётной записи, от имени которой работает приложение.

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

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

Главная рекомендация — никогда не подставлять пользовательский ввод в SQL-запрос напрямую. Используйте подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ.

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

  • Валидация и фильтрация входных данных (белые списки).
  • Отключение вывода подробных ошибок на продакшене.
  • Использование ORM с автоматическим экранированием.
  • Регулярное обновление СУБД и фреймворков.
  • Установка WAF (Web Application Firewall) для блокировки типовых атак.
  • Принцип минимальных привилегий для учётной записи БД: не давайте ей прав на чтение системных таблиц, если это не нужно.

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

Частые вопросы

Может ли эта строка появиться случайно?

Практически нет. Комбинация EXTRACTVALUE, CONCAT, 0x7e и ELT — это чёткая сигнатура атаки. Случайный пользователь не введёт такое в форму.

Работает ли это на других СУБД?

Функция EXTRACTVALUE есть в MySQL и MariaDB. В PostgreSQL, Oracle или MS SQL используются другие функции для error-based инъекций (например, CAST, UTL_INADDR и т.п.).

Что означает число 3212?

Это произвольное число, выбранное сканером. Оно не несёт смысла, кроме как быть первым аргументом EXTRACTVALUE. В других вариантах вы увидите другие числа (2015, 7289 и т.д.).

Заключение

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

Источники