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

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

Внешне это выглядит как безобидный фрагмент SQL-кода, но на самом деле за ним стоит целая техника атаки на веб-приложения. Давайте разберём её по частям.

Разбор синтаксиса

Начало: обратная кавычка и AND

Строка начинается с символа обратной кавычки `. В MySQL обратные кавычки используются для экранирования имён таблиц и столбцов. Злоумышленник добавляет её, чтобы «закрыть» незакрытую кавычку в исходном запросе приложения. Далее идёт AND — логический оператор, который позволяет присоединить дополнительное условие к существующему запросу.

Функция EXTRACTVALUE

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

CONCAT и 0x7e

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

Подзапрос с ELT и условием 1993=1993

Внутри CONCAT находится подзапрос: SELECT (ELT(1993=1993,1)). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 1993=1993 — это всегда истинное условие, которое возвращает 1. Таким образом, ELT(1,1) вернёт строку '1'. В реальной атаке на месте 1 мог бы стоять, например, database() или user(), а вместо 1993=1993 — условие, проверяющее версию СУБД или наличие таблицы. В данном примере это просто демонстрация синтаксиса.

Завершение: -- -

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

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

Предположим, веб-приложение формирует запрос вида:

SELECT * FROM articles WHERE id = '$id';

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

SELECT * FROM articles WHERE id = '1` AND EXTRACTVALUE(1993,CONCAT(0x7e,((SELECT (ELT(1993=1993,1)))),0x7e))-- -';

MySQL выполнит EXTRACTVALUE с аргументом, содержащим тильду и результат подзапроса. Поскольку XPath-выражение ~1~ не является корректным, СУБД вернёт ошибку примерно такого вида:

XPATH syntax error: '~1~'

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

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

Основная цель — извлечение информации из базы данных без прямого доступа к ней. Error-based инъекции особенно удобны, когда приложение не выводит данные напрямую, но отображает ошибки СУБД. Злоумышленник может последовательно «вытаскивать» по одному значению: имя текущей базы, список таблиц, столбцов, содержимое конкретных ячеек. Для автоматизации этого процесса существуют инструменты вроде sqlmap.

Важно понимать: сам по себе фрагмент 1993=1993 — это тестовая заглушка. В реальной атаке вместо неё было бы, например, SUBSTRING(database(),1,1)='a' или аналогичное условие, позволяющее проверять догадки посимвольно.

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

  • Утечка данных: злоумышленник может получить доступ к логинам, паролям, персональным данным пользователей.
  • Компрометация всей системы: через SQL-инъекцию иногда удаётся выполнить произвольные команды на сервере.
  • Нарушение целостности: возможны модификация или удаление данных.
  • Репутационные потери: утечка данных приводит к штрафам и потере доверия клиентов.

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

Главный способ защиты — параметризованные запросы (prepared statements). Они разделяют код SQL и данные, поэтому пользовательский ввод никогда не интерпретируется как часть запроса. Дополнительные меры:

  1. Использовать ORM или библиотеки, которые автоматически экранируют ввод.
  2. Отключить вывод подробных ошибок СУБД в production-среде.
  3. Применять принцип наименьших привилегий для учётной записи базы данных.
  4. Регулярно обновлять СУБД и фреймворки.
  5. Проводить аудит кода и тестирование на проникновение.

Что делать, если вы нашли такую строку в логах?

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

  • Используются ли параметризованные запросы во всех местах работы с БД.
  • Нет ли ошибок в обработке пользовательского ввода.
  • Включён ли Web Application Firewall (WAF).
  • Не было ли успешных попыток эксплуатации (например, необычных запросов к БД).

Своевременное реагирование поможет предотвратить реальную атаку.

Итог

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

Источники