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

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

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

Разбор компонентов инъекции

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

1. %" — начало полезной нагрузки

Символ % часто используется в SQL-инъекциях как часть шаблона поиска (например, в LIKE '%...%'). Закрывающая кавычка " (или ') необходима, чтобы «разорвать» исходный SQL-запрос и добавить собственный код. В данном случае предполагается, что приложение подставляет пользовательский ввод в строковый литерал, не экранируя кавычки.

2. AND — логический оператор

Оператор AND используется для присоединения дополнительного условия. Если исходный запрос уже содержит WHERE, то добавление AND позволяет внедрить новое выражение, которое будет вычислено. В error-based инъекциях это выражение специально сконструировано так, чтобы вызвать ошибку с полезными данными.

3. EXTRACTVALUE(6340, CONCAT(...)) — функция, генерирующая ошибку

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

В нашем случае вторым аргументом является CONCAT(0x7e, ((SELECT ...)), 0x7e). 0x7e — это шестнадцатеричное представление символа ~ (тильда). Функция CONCAT склеивает тильду, результат подзапроса и ещё одну тильду. Полученная строка передаётся как XPath-выражение. Поскольку она содержит символы, недопустимые в XPath (например, тильду), MySQL выдаёт ошибку, в текст которой попадает вычисленное значение.

Число 6340 — произвольный идентификатор, который не влияет на логику, но может использоваться для уникализации ошибки или обхода простых фильтров.

4. CONCAT(0x7e, ..., 0x7e) — обёртка для вывода данных

Тильда (~) используется как маркер, чтобы в сообщении об ошибке было легко найти границы извлечённых данных. Например, ошибка может выглядеть так: XPATH syntax error: '~1~'. Всё, что находится между тильдами, — это результат подзапроса.

5. (SELECT (ELT(6340=6340,1))) — извлекаемый запрос

В данном примере подзапрос возвращает 1. Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Выражение 6340=6340 всегда истинно (1), поэтому ELT(1, 1) вернёт 1. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы быть, например, (SELECT password FROM users LIMIT 1). Таким образом, злоумышленник может извлекать произвольные данные из базы.

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

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

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

Error-based SQL-инъекция — это метод, при котором злоумышленник заставляет базу данных вернуть сообщение об ошибке, содержащее результат выполнения внедрённого запроса. Это возможно, когда приложение выводит ошибки СУБД пользователю (или когда ошибки попадают в логи, доступные атакующему).

В MySQL для этих целей часто используют функции EXTRACTVALUE и UPDATEXML. Обе они при некорректных аргументах генерируют ошибку с текстом, включающим переданное значение. Именно поэтому в инъекции применяется CONCAT с тильдами: чтобы отделить полезную нагрузку от служебного текста ошибки.

Пример сообщения об ошибке, которое может увидеть атакующий:

XPATH syntax error: '~1~'

Если вместо 1 подставить подзапрос, возвращающий имя пользователя, то в ошибке отобразится это имя.

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

Успешная error-based инъекция позволяет злоумышленнику:

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

Даже если приложение не выводит ошибки напрямую, они могут попадать в логи, которые затем утекают. Поэтому error-based инъекции считаются серьёзной угрозой.

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

Основной способ защиты — параметризованные запросы (prepared statements). При их использовании пользовательский ввод передаётся отдельно от SQL-кода, и внедрить операторы или функции невозможно. Например, в PHP с PDO:

$stmt = $pdo->prepare('SELECT * FROM users WHERE name = ?');
$stmt->execute([$userInput]);

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

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

Заключение

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

Источники