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

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

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

Разбор конструкции по частям

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

  • %"))) — начальная часть, которая закрывает ранее открытые кавычки и скобки в оригинальном запросе. Обычно используется для «выхода» из строкового литерала и добавления собственного кода. Количество скобок и кавычек подбирается под конкретный запрос.
  • AND — логический оператор, позволяющий присоединить условие к WHERE-части исходного запроса.
  • EXTRACTVALUE(5501, CONCAT(...)) — вызов встроенной функции MySQL, которая извлекает значение из XML-документа. Если первый аргумент не является корректным XML, функция генерирует ошибку. Злоумышленник использует это для вывода данных в тексте ошибки.
  • CONCAT(0x7e, ((SELECT (ELT(5501=5501,1)))), 0x7e) — конкатенация трёх частей: шестнадцатеричный код 0x7e (символ ~), результат подзапроса и снова ~. Символы ~ служат маркерами, по которым потом легко найти внедрённые данные в сообщении об ошибке.
  • (SELECT (ELT(5501=5501,1))) — подзапрос, возвращающий значение. ELT() — функция, возвращающая N-й элемент из списка. В данном случае условие 5501=5501 всегда истинно, поэтому ELT возвращает первый элемент — число 1. Это простейшая проверка работоспособности инъекции. В реальной атаке вместо этого подзапроса мог бы быть, например, (SELECT password FROM users LIMIT 1).
  • -- - — комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы синтаксис оставался корректным.

Таким образом, вся конструкция заставляет MySQL выполнить EXTRACTVALUE с заведомо некорректным XML (из-за добавленных символов ~), что приводит к ошибке вида: XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса.

Цель инъекции

Основная цель — получить возможность читать данные из базы, не имея прямого доступа. Error-based инъекции особенно удобны, когда приложение не выводит результаты запроса на экран, но отображает сообщения об ошибках базы данных. Злоумышленник может последовательно извлекать имена таблиц, колонок и содержимое записей, подставляя вместо ELT(5501=5501,1) другие подзапросы.

Например, чтобы узнать версию MySQL, можно использовать EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)). В ответе придёт ошибка с версией. Аналогично извлекаются имена пользователей, хеши паролей и другие конфиденциальные сведения.

Почему используется EXTRACTVALUE?

Функция EXTRACTVALUE появилась в MySQL давно и часто применяется в error-based атаках, потому что она генерирует ошибку с контролируемым текстом. Другие функции, такие как UPDATEXML или GEOMETRYCOLLECTION, также могут использоваться для этих целей. Важно, что EXTRACTVALUE не требует прав на запись или специальных привилегий — достаточно возможности выполнять SELECT.

Символ 0x7e (~) выбран не случайно: он редко встречается в обычных данных, поэтому его легко найти в сообщении об ошибке и извлечь полезную нагрузку. Иногда вместо ~ используют другие разделители, например, 0x3a (двоеточие).

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

Лучший способ защиты — использовать параметризованные запросы (prepared statements). Они разделяют код SQL и данные, поэтому даже если в параметр попадёт строка с кавычками и функциями, она будет воспринята как обычное значение, а не как часть запроса. Также рекомендуется:

  • Отключить вывод подробных ошибок базы данных на продакшн-серверах. Пользователь должен видеть общее сообщение, а детали писать в лог.
  • Использовать ORM или библиотеки, которые автоматически экранируют опасные символы.
  • Проводить регулярные аудиты кода и сканирование уязвимостей.
  • Ограничить права пользователя базы данных, от имени которого работает приложение: только необходимые операции.

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

Пример уязвимого запроса

Предположим, в приложении есть такой код на PHP:

$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = '$id'";
$result = mysqli_query($conn, $query);

Если передать в параметр id строку %"))) AND EXTRACTVALUE(5501,CONCAT(0x7e,((SELECT (ELT(5501=5501,1)))),0x7e))-- -, то итоговый запрос примет вид:

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

После подстановки MySQL выполнит инъекцию и вернёт ошибку с внедрённым значением. Если приложение выводит эту ошибку, злоумышленник увидит результат.

Заключение

Рассмотренная строка — типичный пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание таких конструкций необходимо специалистам по безопасности для тестирования приложений и разработчикам для предотвращения уязвимостей. Помните: лучшая защита — параметризованные запросы и скрытие деталей ошибок от конечных пользователей.

Источники