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

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

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

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

Давайте разберём каждый элемент:

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

Как это работает: механизм error-based SQL-инъекции

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

Пример работы:

  1. Приложение формирует запрос: SELECT * FROM articles WHERE id = '$_GET[id]'.
  2. Злоумышленник передаёт в параметре id строку: ` AND EXTRACTVALUE(6089,CONCAT(0x7e,((SELECT (ELT(6089=6089,1)))),0x7e))-- -.
  3. Итоговый запрос становится: SELECT * FROM articles WHERE id = '` AND EXTRACTVALUE(6089,CONCAT(0x7e,((SELECT (ELT(6089=6089,1)))),0x7e))-- -'.
  4. MySQL выполняет запрос. Функция EXTRACTVALUE получает XPath-выражение ~1~ (тильда, единица, тильда). Это выражение некорректно с точки зрения XPath, поэтому MySQL выбрасывает ошибку: XPATH syntax error: '~1~'.
  5. В тексте ошибки злоумышленник видит ~1~ — это результат выполнения подзапроса. В данном примере это просто 1, но если вместо ELT(6089=6089,1) подставить, например, SELECT version(), то в ошибке отобразится версия MySQL.

Таким образом, атакующий может пошагово извлекать любые данные из базы: имена таблиц, столбцов, логины, пароли. Для этого он использует подзапросы и функции вроде CONCAT, GROUP_CONCAT, SUBSTRING и т.д.

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

Цель — получить доступ к конфиденциальной информации или выполнить произвольные действия с базой. Error-based инъекция особенно удобна, когда приложение не выводит данные напрямую (например, нет вывода на страницу), но отображает ошибки базы данных. Даже если ошибки не показываются пользователю, они могут попадать в логи, которые потом анализируются.

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

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

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

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

  • Экранирование специальных символов — используйте функции экранирования, предоставляемые драйвером БД (например, mysqli_real_escape_string в PHP). Но это менее надёжно, чем параметризация.
  • Отключение вывода ошибок БД на страницу — ошибки должны логироваться, но не показываться пользователю. Это затрудняет эксплуатацию error-based инъекций.
  • Использование ORM — современные ORM (например, Doctrine, Hibernate) обычно используют параметризацию по умолчанию.
  • Регулярное обновление СУБД — иногда уязвимости есть в самих функциях, но чаще проблема в коде приложения.
  • WAF (Web Application Firewall) — может блокировать известные шаблоны атак, но не является панацеей.

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

Часто задаваемые вопросы

Что означает число 6089 в строке?

Это произвольное число, которое используется как первый аргумент функции EXTRACTVALUE. Оно не несёт смысловой нагрузки, кроме как служить XML-документом (число преобразуется в строку). В других вариантах инъекции число может меняться.

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

0x7e — это шестнадцатеричный код символа ~. Тильда выбрана потому, что она редко встречается в обычных данных и легко заметна в сообщении об ошибке. Атакующий оборачивает выводимое значение в тильды, чтобы точно определить его границы.

Можно ли использовать эту строку для взлома любого сайта?

Нет. Она сработает только если сайт уязвим к SQL-инъекциям, то есть если пользовательский ввод попадает в SQL-запрос без должной обработки. Большинство современных фреймворков и CMS защищены от таких атак.

Заключение

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

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

Источники