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

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

В отличие от UNION-based или blind-инъекций, error-based метод заставляет базу данных вернуть результат запроса прямо в тексте ошибки. Это делает атаку быстрой и удобной для злоумышленника, если приложение отображает сообщения об ошибках СУБД.

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

Давайте разберём каждый элемент запроса.

  • AND — логический оператор, который присоединяется к исходному SQL-запросу приложения. Если исходный запрос был, например, SELECT * FROM users WHERE id = 1, то после подстановки получается SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(...).
  • EXTRACTVALUE(3265, CONCAT(...)) — функция MySQL для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Первый аргумент — это XML-строка (в нашем случае просто число 3265, которое интерпретируется как текст). Второй аргумент — XPath-выражение. Если XPath синтаксически некорректен, MySQL генерирует ошибку XPATH syntax error, в тексте которой выводится переданное выражение.
  • CONCAT(0x7e, ..., 0x7e) — функция конкатенации. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер начала и конца выводимых данных, чтобы их было легко найти в сообщении об ошибке.
  • SELECT (ELT(3265=3265,1)) — подзапрос, который возвращает результат функции ELT(). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 3265=3265 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) возвращает строку '1'. В реальной атаке вместо 1 могло бы быть имя базы данных, версия, имя пользователя или другой полезный результат подзапроса.
  • -- - — комментарий в MySQL. Всё, что идёт после --, игнорируется парсером. Пробел после двух дефисов обязателен в некоторых реализациях, а третий дефис добавлен для надёжности.

В результате выполнения такого запроса MySQL выдаст ошибку вида:

ERROR 1105 (HY000): XPATH syntax error: '~1~'

Злоумышленник видит в сообщении об ошибке результат подзапроса, обёрнутый в тильды. Это и есть извлечение данных.

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

Error-based SQL-инъекция позволяет атакующему получать произвольные данные из базы, даже если приложение не выводит результаты запроса напрямую. Например, можно узнать:

  • версию MySQL (SELECT VERSION());
  • имя текущей базы данных (SELECT DATABASE());
  • имя пользователя СУБД (SELECT USER());
  • список таблиц и колонок из information_schema;
  • пароли пользователей, номера кредитных карт и другие конфиденциальные данные.

Конструкция с ELT(3265=3265,1) — это упрощённый пример, который часто используется в сканерах уязвимостей для проверки наличия инъекции. Если сервер возвращает ошибку с тильдами, значит, параметр уязвим.

Почему EXTRACTVALUE работает?

Функция EXTRACTVALUE была добавлена в MySQL 5.1. Она предназначена для извлечения данных из XML-документов. Однако при передаче некорректного XPath-выражения СУБД генерирует ошибку, в которой отображается переданная строка. Это и эксплуатируют злоумышленники.

Аналогичными функциями, которые также могут вызывать ошибки с выводом данных, являются UPDATEXML и GTID_SUBSET (в некоторых версиях). В MariaDB и других СУБД есть свои особенности.

Пример реальной атаки

Предположим, на сайте есть страница product.php?id=1. Запрос к базе выглядит так:

SELECT * FROM products WHERE id = 1

Злоумышленник подставляет вместо 1 следующий код:

1 AND EXTRACTVALUE(3265,CONCAT(0x7e,(SELECT VERSION()),0x7e))

Итоговый запрос:

SELECT * FROM products WHERE id = 1 AND EXTRACTVALUE(3265,CONCAT(0x7e,(SELECT VERSION()),0x7e))

СУБД вернёт ошибку с версией MySQL, например: XPATH syntax error: '~5.7.23~'. Так атакующий узнаёт версию сервера.

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

Основной метод защиты — использование параметризованных запросов (prepared statements). Это позволяет отделить код SQL от данных, и никакие пользовательские данные не попадут в тело запроса как исполняемый код.

  • Параметризация запросов — самый надёжный способ. В PHP используйте PDO или mysqli с подготовленными выражениями.
  • Экранирование специальных символов — вспомогательная мера, но не панацея. Лучше не полагаться только на неё.
  • Отключение вывода ошибок СУБД — не показывайте пользователям сообщения об ошибках базы данных. Это усложняет эксплуатацию, но не устраняет уязвимость.
  • Регулярное обновление СУБД — в новых версиях MySQL некоторые функции могут быть удалены или изменены, что снижает риск.
  • Использование WAF — веб-приложения-экраны могут блокировать подозрительные конструкции, но их можно обойти.
  • Принцип наименьших привилегий — учётная запись, от имени которой работает приложение, не должна иметь прав на чтение information_schema или системных таблиц.

Важно понимать, что error-based инъекция — лишь один из многих методов. Полноценная защита требует комплексного подхода: аудит кода, тестирование на проникновение, обучение разработчиков.

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

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

  1. Проверить, не была ли атака успешной (искать другие подозрительные запросы с этого IP).
  2. Заблокировать IP-адрес атакующего на файрволе.
  3. Провести аудит кода на наличие уязвимостей.
  4. Обновить ПО и СУБД.
  5. Усилить мониторинг и логирование.

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

Заключение

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

Никогда не доверяйте пользовательскому вводу. Используйте параметризованные запросы, ограничивайте права СУБД и следите за обновлениями. Безопасность — это процесс, а не одноразовое действие.

Источники