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

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

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

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

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

Функция EXTRACTVALUE(XML, XPath) извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в тексте которой может отображаться переданный фрагмент. Это и используется для внедрения.

Например, выражение EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) вызовет ошибку вида XPATH syntax error: '~5.7.42~', где 5.7.42 — версия СУБД.

В нашем случае используется аналогичный приём, но с дополнительной конструкцией ELT().

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

Рассмотрим строку ) AND EXTRACTVALUE(3709,CONCAT(0x7e,((SELECT (ELT(3709=3709,1)))),0x7e))-- - поэлементно:

  • ) — закрывающая скобка, которая завершает предыдущее выражение в исходном запросе, делая возможным добавление нового условия.
  • AND — логический оператор, присоединяющий наше внедрение к оригинальному запросу.
  • EXTRACTVALUE(3709, ...) — функция, которая должна вызвать ошибку. Первый аргумент (3709) — произвольное число, имитирующее XML-документ (фактически не является корректным XML, но это не важно, так как ошибка будет вызвана вторым аргументом).
  • CONCAT(0x7e, ..., 0x7e) — объединяет символ ~ (шестнадцатеричный код 0x7e) с результатом подзапроса и ещё одним ~. Символы тильды используются как маркеры, чтобы облегчить поиск данных в сообщении об ошибке.
  • (SELECT (ELT(3709=3709,1))) — подзапрос, возвращающий результат функции ELT(). ELT(N, str1, str2, ...) возвращает строку с номером N. В данном случае 3709=3709 — это логическое выражение, всегда истинное (1). Таким образом, ELT(1, 1) вернёт строку '1'. Это простейшая проверка работоспособности инъекции: если ошибка содержит ~1~, значит, внедрение выполнено.
  • -- - — комментарий, который «отрезает» оставшуюся часть исходного SQL-запроса, чтобы синтаксис оставался корректным.

Итог: при выполнении этого фрагмента MySQL попытается вычислить XPath-выражение ~1~, что вызовет ошибку с текстом, содержащим этот маркер. Злоумышленник, анализируя ответ сервера, может понять, что инъекция возможна, и затем заменить ELT(3709=3709,1) на подзапрос, извлекающий реальные данные (например, версию БД, имена таблиц, пароли).

Зачем злоумышленнику это нужно?

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

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

Строка с ELT(3709=3709,1) — это, как правило, «разведка боем»: она безопасна для данных, но показывает, что приложение уязвимо. Если сервер возвращает ошибку с тильдами, атакующий переходит к следующему этапу.

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

Лучшая защита — использовать параметризованные запросы (prepared statements) и хранимые процедуры. Никогда не подставляйте пользовательский ввод напрямую в SQL-запрос. Дополнительные меры:

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

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

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

Число 3709 в данном случае не несёт специальной смысловой нагрузки — это произвольное число, выбранное для уникальности или маскировки. В разных вариантах инъекций можно встретить другие числа (7289, 3029 и т.п.). Главное — чтобы оно было допустимым аргументом функции EXTRACTVALUE() (фактически любой целочисленный литерал).

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

Вывод

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

Источники