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

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

Подобные строки часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL. Они не являются частью легитимного запроса — это попытка атакующего заставить базу данных выдать скрытую информацию.

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

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

В нашем случае:

  • EXTRACTVALUE(8274, CONCAT(0x7e, ..., 0x7e)) — первый аргумент (8274) — произвольное число, второй аргумент — конкатенация тильды (0x7e), результата подзапроса и снова тильды.
  • CONCAT(0x7e, ((SELECT (ELT(8274=8274,1)))), 0x7e) — формирует строку вида ~1~, если условие 8274=8274 истинно (а оно всегда истинно).
  • ELT(N, str1, str2, ...) — возвращает N-ю строку из списка. Здесь N=1 (так как 8274=8274 даёт 1), а список состоит из одной строки '1'.

В итоге XPath-выражение получается ~1~, что не является корректным XPath. MySQL генерирует ошибку: XPATH syntax error: '~1~'. Эта ошибка возвращается в ответе сервера и видна атакующему.

Зачем нужны ELT и CONCAT?

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

CONCAT с тильдами (0x7e) нужен для того, чтобы отделить выводимые данные от служебного текста ошибки. Тильда — удобный маркер, который легко найти в сообщении об ошибке.

Конструкция -- - в конце — это комментарий в MySQL. Он обрезает остаток оригинального SQL-запроса, чтобы синтаксис оставался корректным.

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

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = '$_GET[id]'

Если передать 1')) AND EXTRACTVALUE(8274,CONCAT(0x7e,(SELECT database()),0x7e))-- -, то база вернёт ошибку с именем текущей базы данных. Аналогично можно извлечь версию MySQL, имена таблиц, столбцов и даже содержимое записей.

В нашем случае вместо database() стоит ELT(8274=8274,1) — это тестовая проверка, чтобы убедиться, что инъекция работает. Злоумышленник сначала проверяет уязвимость, а затем подставляет реальные подзапросы.

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

Error-based SQL-инъекции позволяют злоумышленнику:

  • получить доступ к конфиденциальным данным (пароли, персональные данные, номера карт);
  • изменить или удалить информацию в базе;
  • выполнить административные операции, если уязвимый пользователь БД имеет высокие привилегии;
  • в некоторых случаях — выполнить произвольные команды на сервере.

Особенность error-based в том, что она не требует слепого перебора и даёт быстрый результат, если сервер возвращает сообщения об ошибках клиенту.

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

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

  1. Экранирование специальных символов (но это менее надёжно, чем параметризация).
  2. Отключение вывода ошибок БД в продакшене — чтобы атакующий не видел текст ошибок.
  3. Ограничение прав пользователя БД: приложению не нужны права на удаление таблиц или доступ к системным таблицам.
  4. Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов.
  5. Регулярное обновление СУБД и фреймворков.

Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based атаках. Аналогично применяются UPDATEXML, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.

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

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

  • проверить код на наличие уязвимостей (особенно в местах работы с БД);
  • убедиться, что все запросы используют параметризацию;
  • просмотреть логи на предмет других подозрительных активностей;
  • при необходимости обратиться к специалистам по информационной безопасности.

Если же вы просто пользователь и увидели такую строку в поле ввода или в URL — не пытайтесь её исполнять, это может быть частью вредоносного сценария.

Заключение

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

Источники