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

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

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

Разбор компонентов инъекции

Давайте разберём строку по частям, чтобы понять, как она работает.

1. Начало: ` AND

Символ обратного апострофа (`) часто используется для экранирования имён таблиц или столбцов в MySQL. В контексте инъекции он может закрывать ранее открытую кавычку или просто быть частью синтаксиса, если внедрение происходит в определённое место запроса. Далее следует AND — логический оператор, который позволяет присоединить дополнительное условие к исходному SQL-запросу. Атакующий использует AND, чтобы внедрить свою функцию, которая выполнится, если исходное условие истинно (или просто для выполнения полезной нагрузки).

2. Функция EXTRACTVALUE

EXTRACTVALUE(7133, CONCAT(...)) — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа. Она принимает два аргумента: XML-документ (в данном случае число 7133, которое интерпретируется как строка) и XPath-выражение. Если XPath-выражение некорректно, MySQL генерирует ошибку, содержащую переданное выражение. Это и есть основа error-based инъекции: атакующий намеренно вызывает ошибку, чтобы в её тексте увидеть результат выполнения вложенного запроса.

3. CONCAT и шестнадцатеричные литералы

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

4. Функция ELT и условие 7133=7133

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(7133=7133, 1) — первый аргумент это логическое выражение 7133=7133, которое всегда истинно (равно 1 в MySQL). Таким образом, ELT(1, 1) возвращает строку '1'. Это простейшая проверка: если инъекция выполняется, функция вернёт 1, и в ошибке появится ~1~. В реальных атаках вместо 1 подставляются имена таблиц, колонок или другие данные, получаемые через подзапросы.

5. Комментарий -- -

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

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

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

Процесс выглядит так:

  1. Атакующий находит уязвимый параметр, который подставляется в SQL-запрос без должной обработки.
  2. Он внедряет конструкцию, которая вызывает ошибку, содержащую результат подзапроса.
  3. Сервер возвращает страницу с сообщением об ошибке MySQL, в котором виден результат.
  4. Атакующий извлекает данные по частям, так как длина сообщения об ошибке ограничена (обычно 32 символа для EXTRACTVALUE).
Важно: максимальная длина результата EXTRACTVALUE — 32 символа. Для извлечения более длинных строк используются функции SUBSTR() или LIMIT.

Пример извлечения данных

Чтобы получить имя текущей базы данных, атакующий может использовать такой запрос:

` AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -

Если уязвимость есть, MySQL вернёт ошибку вида: XPATH syntax error: '~имя_базы~'. Аналогично можно извлекать имена таблиц, колонок и сами данные, используя GROUP_CONCAT и ограничивая длину через SUBSTR.

Последствия и защита

Успешная error-based SQL-инъекция может привести к полному раскрытию базы данных, включая учётные записи пользователей, персональные данные, финансовую информацию. В некоторых случаях возможна запись файлов на сервер или выполнение команд ОС.

Для защиты необходимо:

  • Использовать подготовленные выражения (prepared statements) с параметризацией запросов.
  • Применять хранимые процедуры с параметрами.
  • Экранировать все пользовательские данные, попадающие в SQL-запросы.
  • Ограничить права пользователя базы данных, от имени которого работает приложение.
  • Отключить вывод подробных ошибок MySQL на продакшене.
  • Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Заключение

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

Источники